/aclocal.m4
/autom4te.cache
/autom4te.cache
+/build-aux/
/compile
/config.guess
/config.sub
/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
*.la
*.lo
*.o
+.dirstamp
.libs/
.deps/
-src/collectd-nagios
-src/collectd-tg
-src/collectdctl
-src/collectdmon
+/collectd-nagios
+/collectd-tg
+/collectdctl
+/collectdmon
src/*.1
src/*.5
src/.pod2man.tmp.*
src/liboconfig/scanner.c
# protobuf stuff:
-src/*.pb-c.[ch]
-src/*.grpc.pb.cc
-src/*.pb.cc
-src/*.pb.h
+*.pb-c.[ch]
+*.grpc.pb.cc
+*.pb.cc
+*.pb.h
# make dist stuff:
/collectd-*.tar.gz
/collectd-*.tar.bz2
# perl stuff:
-bindings/.perl-directory-stamp
+/.perl-directory-stamp
bindings/perl/Collectd/pm_to_blib
bindings/perl/blib/
bindings/perl/pm_to_blib
-bindings/buildperl
+/buildperl
# java stuff
-bindings/java/java-build-stamp
-bindings/java/org/collectd/api/*.class
-bindings/java/org/collectd/java/*.class
+*.jar
+/org/collectd/api/*.class
+/org/collectd/java/*.class
+/bindings/java/java-build-stamp
+/classnoinst.stamp
# python stuff
*.pyc
test_*
# src/daemon/...
-src/daemon/collectd
+/collectd
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
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
David Bacher <drbacher at gmail.com>
- serial plugin.
+Denis Pompilio <denis.pompilio at gmail.com>
+ - Improvements to the write_http plugin.
+
Doug MacEachern <dougm at hyperic.com>
- The `-T' option (config testing mode).
- OpenVPN plugin.
Sebastien Pahl <sebastien.pahl at dotcloud.com>
- AMQP plugin.
+Serhiy Pshyk <serhiyx.pshyk at intel.com>
+ - intel_pmu plugin
+ - intel_rdt plugin
+ - snmp_agent plugin
+
Simon Kuhnle <simon at blarzwurst.de>
- OpenBSD code for the cpu and memory plugins.
Stefan Hacker <stefan.hacker at web.de>
- teamspeak2 plugin.
+Steven Bell <stv.bell07 at gmail.com>
+ - nut plugin.
+
Sven Trenkel <collectd at semidefinite.de>
- netapp plugin.
- python plugin.
* *Focus:* Fix *one thing* in your PR. The smaller your change, the faster it
will be reviewed and merged.
-* *Coding style:* Please run `clang-format -style=file -i $FILE` on new files.
- For existing files, please blend into surrounding code, i.e. mimic the
- coding style of the code around your changes.
+* *Coding style:* Please run `clang-format -style=file -i $FILE` after editing
+ `.c`, `.h` and `.proto` files. If you don't want to install *clang-format*
+ locally or your version produces a different result than the formatting
+ check on Github, use `contrib/format.sh` to format files using the same web
+ service used by our check.
* *Documentation:* New config options need to be documented in two places: the
manpage (`src/collectd.conf.pod`) and the example config
(`src/collectd.conf.in`). New plugins need to be added to the `README` file.
+2017-11-17, Version 5.8.0
+ * collectd: The core daemon is now completely licensed under the MIT
+ license.
+ * collectd: Added daemon option to avoid making BaseDir. Thanks to
+ Nathaniel Wesley Filardo and Florian Forster. #2422
+ * collectd: Global variables have been moved to their own module to make
+ porting collectd easier. Thanks to Sean Campbell. #2467
+ * collectd as well as Apache, memcached, OpenLDAP, Perl, RouterOS, SNMP,
+ Tail-CSV plugins: Free userdata for "plugin_register_complex_read()".
+ Thanks to Pavel Rochnyack. #2349
+ * Collectd client library: Added parsing and server code. Thanks to
+ Florian Forster. #2258
+ * Build system: Dependency on libltdl has been removed, support for
+ libtool 1 has been dropped. Thanks to Ruben Kerkhof. #1898
+ * Build system: The build system has been switched to non-recursive
+ make. Thanks to Ruben Kerkhof. #2085
+ * APC UPS plugin: The plugin's configuration is now optional. Without a
+ "<Plugin />" block reasonable defaults will be used. Thanks to Pavel
+ Rochnyack. #2351
+ * Chrony plugin: Several issues found when working with a stratum-1
+ server have been fixed. Thanks to Miroslav Lichvar. #2190
+ * Ceph plugin: Support for the Ceph version "Luminous" has been added.
+ Thanks to Aleksei Zakharov. #2464
+ * CPU plugin : Linux-specific "guest" states have been added. Thanks to
+ Xavier G. #2439
+ * cURL plugin, cURL-JSON, cURL-XML, DBI, FileCount, memcachec, Oracle,
+ PostgreSQL, Table, Tail, Tail CSV plugins: The ability to configure
+ the "plugin" field of generated metrics has been added. Thanks to
+ Pavel Rochnyack. #1944, #1681, #1558
+ * cURL-JSON plugin: Parsing of arrays has been fixed. Thanks to Florian
+ Forster. #2281
+ * DPDKEvents plugin: This new plugin reports link status and keep alive
+ events. Thanks to Maryam Tahhan, Harry van Haaren, Serhiy Pshyk,
+ Kim-Marie Jones, Krzysztof Matczak, Przemyslaw Szczerbik, Christian
+ Ehrhardt and Luca Boccassi. #2157, #2348, #2400, #2405, #2417
+ * DPDKStat plugin: The plugin has been refactored to make DPDK related
+ utility functions reusable. Thanks to Krzysztof Matczak, Przemyslaw
+ Szczerbik, Christian Ehrhardt and Luca Boccassi. #2130, #2348, #2400,
+ #2405, #2417
+ * DPDKStat plugin: The "LogLevel" and "RteDriverLibPath" config options
+ have been added. Thanks to Jiri Prokes. #2505
+ * Email plugin as well as Exec and Unixsock plugins: Use
+ "_SC_GETPW_R_SIZE_MAX". Thanks to Florian Forster. #2451
+ * FileCount plugin: Custom values for reported plugin, type and type
+ instance. Thanks to Pavel Rochnyack. #1979
+ * GenericJMX plugin: Support for "AtomicInteger" and "AtomicLong" has
+ been added. Thanks to Pierre Mauduit. #2158
+ * gRPC plugin: Support for meta data has been added. Thanks to Taylor
+ Cramer. #2378
+ * IPC plugin: Fixed failed compilation on AIX. Thanks to Pavel
+ Rochnyack. #2357
+ * Intel PMU plugin: This new plugin collects CPU performance metrics
+ using Intel's Performance Monitoring Unit (PMU). Scaling information
+ added to metadata. Thanks to Serhiy Pshyk and Roman Korynkevych.
+ #2276, #2398, #2374
+ * Intel RDT plugin: Support for collectd's logging infrastructure has
+ been added. PQoS monitoring groups are being reset on start-up to fix
+ potential previous unclean shutdowns. Thanks to Roman Korynkevych.
+ #2089.
+ * IPMI plugin: Support for System Event Log (SEL) has been added. Thanks
+ to Roman Korynkevych. #2091
+ * IPMI plugin: Support for remote IPMI controllers has been added.
+ Thanks to Pavel Rochnyack. #2024
+ * LVM plugin: A check for the "CAP_SYS_ADMIN" capability has been added.
+ This will give users an informative warning when the process is not
+ running with the required privileges for this plugin. Thanks to
+ Florian Forster. #2426, #2499
+ * mcelog plugin: This new plugin subscribes to Machine Check Exceptions
+ (MCE) and dispatches notifications. Metadata reset. Thanks to Maryam
+ Tahhan, Volodymyr Mytnyk, Taras Chornyi, Krzysztof Matczak and Roman
+ Korynkevych. #2003, #2246, #2380
+ * MQTT plugin: Add support for TLS in "Subscriber" blocks. Thanks to
+ Florian Forster. #2434
+ * memcached plugin: Persistent connections have been implemented. Fix
+ hit ratio reporting, add connections rate report. Thanks to Pavel
+ Rochnyack. #2388, #2385
+ * memcached plugin: The type of the "listen_disabled" metric has been
+ changed to "total_events". Thanks to Florian Forster. #2386, #2468
+ * Netlink plugin: The dropped packets metric has been added. Thanks to
+ Denys Fedoryshchenko. #2053
+ * NFS plugin: Support for NFS 4.2 metrics has been added. Thanks to
+ Marek Becka. #2369
+ * NFS plugin: Config options to ignore specified NFS versions have been
+ added. Thanks to Christian Bartolomäus. #2430
+ * NUT plugin: The "ConnectTimeout", "ForceSSL", "VerifyPeer" and
+ "CAPath" options have been added. Thanks to Pavel Rochnyack and Steven
+ Bell. #2145, #2354
+ * OpenLDAP plugin: A segfault after a connection failure has been fixed.
+ Thanks to Pavel Rochnyack. #2377
+ * Openvpn plugin: Added support for status files from latest OpenVPN-2.4
+ and possible from future versions. Thanks to Pavel Rochnyack. #2352
+ * OVS Events plugin: This new plugin reports link state changes from
+ Open vSwitch (OVS). Thanks to Volodymyr Mytnyk. #1971
+ * OVS Stats plugin: This new plugin reports bridge / interface
+ statistics from Open vSwitch (OVS). Thanks to Volodymyr Mytnyk and
+ Taras Chornyi. #2137
+ * Perl plugin: Bugfix, added check of proper interpreter initialization.
+ Thanks to Pavel Rochnyack. #2391
+ * PostgreSQL plugin: The plugin now sets the "application_name"
+ parameter when connecting to the database. Thanks to daniacs. #2497
+ * Processes plugin: The I/O operations reported for selected processes
+ has been fixed. The metric "ps_disk_octets" has been renamed to
+ "io_octets" because it actually contains the number of I/O operation
+ by the process, not just disk related I/O. Same for "io_ops"
+ (previously "ps_disk_ops"). The new metric "disk_octets" has been
+ added and is reporting disk I/O only. Add option to collect the count
+ of active memory maps for Linux processes. The "CollectFileDescriptor"
+ and "CollectContextSwitch" options have been added. Thanks to Pavel
+ Rochnyack and to Wilfried Goesgens. #2232, #2454, #1989
+ * Processes and TCPConns plugins: The OpenBSD implementation has been
+ changed to use "kvm_openfiles" with "KVM_NO_FILES". Thanks to Jeremie
+ Courreges-Anglas. #2061
+ * Python plugin: Extend Notification class to include metadata. Thanks
+ to Volodymyr Mytnyk. #2135
+ * Python plugin: The "CollectdException" class has been added. This
+ allows to throw an exception without a stack trace being logged.
+ Thanks to Sven Trenkel. #2330, #2346
+ * Sensors plugin: Support for (electrical) current has been added.
+ Thanks to Clemens Gruber. #2255
+ * SNMP plugin: Error handling has been improved: a potential double-free
+ is now avoided (potentially leaking memory) and handling of
+ non-failing subtrees has been fixed. Thanks to Pavel Rochnyack. #2449
+ * SNMP plugin: The "Timeout" and "Retries" config options have been
+ added. Thanks to Carlos Vicente. #1472, #2488
+ * SNMP Agent plugin: This new plugin implements an SNMP AgentX subagent
+ that receives and handles queries from SNMP master agent and returns
+ configured metrics. Thanks to Roman Korynkevych, Serhiy Pshyk and
+ Pavel Rochnyack. #2105, #2362
+ * Synproxy plugin: This new plugin provides statistics for Linux
+ SYNPROXY. Thanks to Marek Bečka. #2381
+ * Tail plugin: Allow the calculation of several distributions in one
+ "tail" instance through a "bucket" type. Thanks to Pavel Rochnyack.
+ #2442
+ * Turbostat plugin: Import "msr-index.h" header from Linux and better
+ support for mutliple packages. Thanks to Vincent Brillault. #2445,
+ #2446
+ * Uptime plugin: Changed implementation to read from "/proc/uptime"
+ instead of "/proc/stat". Update for Linux and AIX, uptime is read
+ directly using a system call. Update for BSD and Solaris, uptime is
+ calculated by subtracting boot time from current time. Thanks to Ivan
+ Kurnosov and Marcin Jurkowski. #2431, #2034
+ * UUID plugin: Support for libhal has been removed. Thanks to Ruben
+ Kerkhof. #2080
+ * Varnish plugin: Extended the varnish plugin with varnish-plus
+ counters. Fixed invalid data source type. Thanks to Denes Matetelki.
+ #2453, #2463
+ * virt plugin: The plugin has been updated to use
+ "virConnectListAllDomains()". Thanks to Denis Silakov. #2051
+ * virt plugin: Support for domain tags has been added. Thanks to
+ Francesco Romani. #2048
+ * virt plugin: Connection handling has been improved. Thanks to
+ Francesco Romani. #2100, #2101
+ * virt plugin: Many metrics have been added, including disk, hypervisor
+ CPU usage, performance monitoring events, domain state, CPU pinning
+ (affinity), file system, and job statistics. Thanks to Francesco
+ Romani and Przemyslaw Szczerbik. #2103, #2175, #2168
+ * Write Graphite plugin: Additional tests have been added. Thanks to
+ Florian Forster.
+ * Write HTTP plugin: The "Attribute" and "TTL" options for the KairosDB
+ format have been added. Implementation of "Prefix" option. Thanks to
+ jaroug, Denis Pompilio and Pavel Rochnyack. #2199, #2252, #2482
+ * Write MongoDB plugin: Memory leaks have been fixed. Thanks to
+ Saikrishna Arcot. #2307
+ * Write Prometheus plugin: Label values are now properly escaped. Thanks
+ to Florian Forster. #2035
+ * Write Redis plugin: Add "max_set_duration" to set duration for value.
+ Thanks to Tomofumi Hayashi. #2440
+ * Write Riemann plugin: Export times with microsecond resolution. Thanks
+ to mcorbin. #2315
+ * Write TSDB plugin: The options "ResolveInterval" and "ResolveJitter"
+ have been added to control DNS lookup behavior. This prevents DNS
+ flooding in case TSDB is not available. Thanks to Yves Mettier and
+ Florian Forster. #2059
+ * ZFS ARC plugin: Header lines are now ignored in the Linux
+ implementation. Thanks to YmrDtnJu. #2097
+
2017-06-06, Version 5.7.2
* Build system: The Notify Email plugin is no longer linked with
indirect dependencies. Thanks to Marc Fournier.
-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/lcc_features.h \
+ src/libcollectdclient/collectd/network_buffer.h \
+ src/libcollectdclient/collectd/network.h \
+ src/libcollectdclient/collectd/network_parse.h \
+ src/libcollectdclient/collectd/server.h \
+ src/libcollectdclient/collectd/types.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
+
+
+check_LTLIBRARIES = \
+ 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 \
+ test_libcollectd_network_parse
+
+
+TESTS = $(check_PROGRAMS)
+
+LOG_COMPILER = env VALGRIND="@VALGRIND@" $(abs_srcdir)/testwrapper.sh
+
+
+jardir = $(pkgdatadir)/java
+
+pkglib_LTLIBRARIES =
+
+
+PLUGIN_LDFLAGS = \
+ -module \
+ -avoid-version \
+ -export-symbols-regex '\<module_register\>'
+
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src -I$(top_srcdir)/src/daemon \
+ -DPREFIX='"${prefix}"' \
+ -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"' \
+ -DLOCALSTATEDIR='"${localstatedir}"' \
+ -DPKGLOCALSTATEDIR='"${localstatedir}/lib/${PACKAGE_NAME}"' \
+ -DPLUGINDIR='"${pkglibdir}"' \
+ -DPKGDATADIR='"${pkgdatadir}"'
+
+
+# Link to these libraries..
+COMMON_LIBS = $(PTHREAD_LIBS)
+if BUILD_WITH_CAPABILITY
+COMMON_LIBS += -lcap
+endif
+if BUILD_WITH_LIBRT
+COMMON_LIBS += -lrt
+endif
+if BUILD_WITH_LIBPOSIX4
+COMMON_LIBS += -lposix4
+endif
+if BUILD_WITH_LIBSOCKET
+COMMON_LIBS += -lsocket
+endif
+if BUILD_WITH_LIBKSTAT
+COMMON_LIBS += -lkstat
+endif
+if BUILD_WITH_LIBDEVINFO
+COMMON_LIBS += -ldevinfo
+endif
+
+
+collectd_SOURCES = \
+ src/daemon/collectd.c \
+ src/daemon/collectd.h \
+ src/daemon/configfile.c \
+ src/daemon/configfile.h \
+ src/daemon/filter_chain.c \
+ src/daemon/filter_chain.h \
+ src/daemon/globals.c \
+ src/daemon/globals.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 \
+ -I$(top_builddir)/src/libcollectdclient
+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 \
+ -I$(top_builddir)/src/libcollectdclient
+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 \
+ -I$(top_builddir)/src/libcollectdclient
+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 \
+ src/libcollectdclient/network_parse.c \
+ src/libcollectdclient/server.c
+libcollectdclient_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(srcdir)/src/libcollectdclient \
+ -I$(top_builddir)/src/libcollectdclient \
+ -I$(srcdir)/src/daemon
+libcollectdclient_la_LDFLAGS = -version-info 2:0:1
+libcollectdclient_la_LIBADD = -lm
+if BUILD_WITH_LIBGCRYPT
+libcollectdclient_la_CPPFLAGS += $(GCRYPT_CPPFLAGS)
+libcollectdclient_la_LDFLAGS += $(GCRYPT_LDFLAGS)
+libcollectdclient_la_LIBADD += $(GCRYPT_LIBS)
+endif
+
+# network_parse_test.c includes network_parse.c, so no need to link with
+# libcollectdclient.so.
+test_libcollectd_network_parse_SOURCES = src/libcollectdclient/network_parse_test.c
+test_libcollectd_network_parse_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(srcdir)/src/libcollectdclient \
+ -I$(top_builddir)/src/libcollectdclient
+if BUILD_WITH_LIBGCRYPT
+test_libcollectd_network_parse_CPPFLAGS += $(GCRYPT_CPPFLAGS)
+test_libcollectd_network_parse_LDFLAGS = $(GCRYPT_LDFLAGS)
+test_libcollectd_network_parse_LDADD = $(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)
+
+test_plugin_curl_json_SOURCES = src/curl_json_test.c \
+ src/utils_curl_stats.c \
+ src/daemon/configfile.c \
+ src/daemon/types_list.c
+test_plugin_curl_json_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
+test_plugin_curl_json_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
+test_plugin_curl_json_LDADD = libavltree.la liboconfig.la libplugin_mock.la $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBYAJL_LIBS)
+check_PROGRAMS += test_plugin_curl_json
+endif
+
+if BUILD_PLUGIN_CURL_XML
+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_CFLAGS = $(AM_CFLAGS) $(LIBDPDK_CFLAGS)
+dpdkevents_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS)
+dpdkevents_la_LIBADD = $(LIBDPDK_LIBS)
+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_CFLAGS = $(AM_CFLAGS) $(LIBDPDK_CFLAGS)
+dpdkstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS)
+dpdkstat_la_LIBADD = $(LIBDPDK_LIBS)
+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_PMU
+pkglib_LTLIBRARIES += intel_pmu.la
+intel_pmu_la_SOURCES = src/intel_pmu.c
+intel_pmu_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBJEVENTS_CPPFLAGS)
+intel_pmu_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBJEVENTS_LDFLAGS)
+intel_pmu_la_LIBADD = $(BUILD_WITH_LIBJEVENTS_LIBS)
+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_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
+
+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)
+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_SNMP_AGENT
+pkglib_LTLIBRARIES += snmp_agent.la
+snmp_agent_la_SOURCES = src/snmp_agent.c
+snmp_agent_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBNETSNMPAGENT_CPPFLAGS)
+snmp_agent_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBNETSNMPAGENT_LDFLAGS)
+snmp_agent_la_LIBADD = $(BUILD_WITH_LIBNETSNMPAGENT_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_SYNPROXY
+pkglib_LTLIBRARIES += synproxy.la
+synproxy_la_SOURCES = src/synproxy.c
+synproxy_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_SYSLOG
+pkglib_LTLIBRARIES += syslog.la
+syslog_la_SOURCES = src/syslog.c
+syslog_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TABLE
+pkglib_LTLIBRARIES += table.la
+table_la_SOURCES = src/table.c
+table_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TAIL
+pkglib_LTLIBRARIES += tail.la
+tail_la_SOURCES = \
+ src/tail.c \
+ src/utils_match.c \
+ src/utils_match.h \
+ src/utils_tail.c \
+ src/utils_tail.h \
+ src/utils_tail_match.c \
+ src/utils_tail_match.h
+tail_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+tail_la_LIBADD = liblatency.la
+endif
+
+if BUILD_PLUGIN_TAIL_CSV
+pkglib_LTLIBRARIES += tail_csv.la
+tail_csv_la_SOURCES = \
+ src/tail_csv.c \
+ src/utils_tail.c \
+ src/utils_tail.h
+tail_csv_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TAPE
+pkglib_LTLIBRARIES += tape.la
+tape_la_SOURCES = src/tape.c
+tape_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+tape_la_LIBADD = -lkstat -ldevinfo
+endif
+
+if BUILD_PLUGIN_TARGET_NOTIFICATION
+pkglib_LTLIBRARIES += target_notification.la
+target_notification_la_SOURCES = src/target_notification.c
+target_notification_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TARGET_REPLACE
+pkglib_LTLIBRARIES += target_replace.la
+target_replace_la_SOURCES = src/target_replace.c
+target_replace_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TARGET_SCALE
+pkglib_LTLIBRARIES += target_scale.la
+target_scale_la_SOURCES = src/target_scale.c
+target_scale_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TARGET_SET
+pkglib_LTLIBRARIES += target_set.la
+target_set_la_SOURCES = src/target_set.c
+target_set_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TARGET_V5UPGRADE
+pkglib_LTLIBRARIES += target_v5upgrade.la
+target_v5upgrade_la_SOURCES = src/target_v5upgrade.c
+target_v5upgrade_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TCPCONNS
+pkglib_LTLIBRARIES += tcpconns.la
+tcpconns_la_SOURCES = src/tcpconns.c
+tcpconns_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+tcpconns_la_LIBADD =
+if BUILD_WITH_LIBKVM_NLIST
+tcpconns_la_LIBADD += -lkvm
+endif
+endif
+
+if BUILD_PLUGIN_TEAMSPEAK2
+pkglib_LTLIBRARIES += teamspeak2.la
+teamspeak2_la_SOURCES = src/teamspeak2.c
+teamspeak2_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_TED
+pkglib_LTLIBRARIES += ted.la
+ted_la_SOURCES = src/ted.c
+ted_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_THERMAL
+pkglib_LTLIBRARIES += thermal.la
+thermal_la_SOURCES = src/thermal.c
+thermal_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+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 \
+ src/msr-index.h
+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
+
+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
-SUBDIRS += proto src bindings .
+AM_V_POD2MAN_C = $(am__v_POD2MAN_C_@AM_V@)
+am__v_POD2MAN_C_ = $(am__v_POD2MAN_C_@AM_DEFAULT_V@)
+am__v_POD2MAN_C_0 = @echo " POD2MAN " $@;
+am__v_POD2MAN_C_1 =
+
+.pod.1:
+ $(AM_V_POD2MAN_C)pod2man --release=$(VERSION) --center=$(PACKAGE) $< \
+ >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true
+ @if grep '\<POD ERRORS\>' $@ >/dev/null 2>&1; \
+ then \
+ echo "$@ has some POD errors!"; false; \
+ fi
+
+.pod.5:
+ $(AM_V_POD2MAN_C)pod2man --section=5 --release=$(VERSION) --center=$(PACKAGE) $< \
+ >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true
+ @if grep '\<POD ERRORS\>' $@ >/dev/null 2>&1; \
+ then \
+ echo "$@ has some POD errors!"; false; \
+ fi
+
+V_PROTOC = $(v_protoc_@AM_V@)
+v_protoc_ = $(v_protoc_@AM_DEFAULT_V@)
+v_protoc_0 = @echo " PROTOC " $@;
+
+AM_V_PROTOC_C = $(am__v_PROTOC_C_@AM_V@)
+am__v_PROTOC_C_ = $(am__v_PROTOC_C_@AM_DEFAULT_V@)
+am__v_PROTOC_C_0 = @echo " PROTOC-C" $@;
+am__v_PROTOC_C_1 =
+
+# Protocol buffer for the "pinba" plugin.
+if BUILD_PLUGIN_PINBA
+BUILT_SOURCES += src/pinba.pb-c.c src/pinba.pb-c.h
+
+src/pinba.pb-c.c src/pinba.pb-c.h: $(srcdir)/src/pinba.proto
+ $(AM_V_PROTOC_C)$(PROTOC_C) -I$(srcdir) --c_out . $(srcdir)/src/pinba.proto
+endif
-AM_CPPFLAGS = $(LTDLINCL)
+# Protocol buffer for the "write_prometheus" plugin.
+if BUILD_PLUGIN_WRITE_PROMETHEUS
+BUILT_SOURCES += prometheus.pb-c.c prometheus.pb-c.h
-EXTRA_DIST = contrib version-gen.sh testwrapper.sh
+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;
-maintainer-clean-local:
- -rm -f -r libltdl
- -rm -f INSTALL
- -rm -f aclocal.m4
+uninstall-hook:
+ rm -f $(DESTDIR)$(pkgdatadir)/types.db;
+ rm -f $(DESTDIR)$(sysconfdir)/collectd.conf
+ rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
+
+all-local: @PERL_BINDINGS@
+
+install-exec-local:
+ [ ! -f buildperl/Makefile ] || ( cd buildperl && $(MAKE) install )
+
+# Perl 'make uninstall' does not work as well as wanted.
+# So we do the work here.
+uninstall-local:
+ @PERL@ -I$(DESTDIR)$(prefix) $(srcdir)/bindings/perl/uninstall_mod.pl Collectd
+ find $(DESTDIR)$(prefix) -name "perllocal.pod" -exec rm {} \;
+
+clean-local:
+ rm -rf buildperl
+
+perl: buildperl/Makefile
+ cd buildperl && $(MAKE)
+
+buildperl/Makefile: .perl-directory-stamp buildperl/Makefile.PL \
+ $(top_builddir)/config.status
+ @# beautify the output a bit
+ @echo 'cd buildperl && @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@'
+ @cd buildperl && ( if ! @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@; then \
+ echo ""; \
+ echo 'Check whether you have set $$PERL_MM_OPT in your environment and try using ./configure --with-perl-bindings=""'; \
+ echo ""; \
+ fi )
+
+buildperl/Makefile.PL: .perl-directory-stamp $(top_builddir)/config.status
+
+.perl-directory-stamp:
+ if test ! -d buildperl; then \
+ mkdir -p buildperl/Collectd/Plugins; \
+ cp $(srcdir)/bindings/perl/lib/Collectd.pm buildperl/; \
+ cp $(srcdir)/bindings/perl/Makefile.PL buildperl/; \
+ cp $(srcdir)/bindings/perl/lib/Collectd/Unixsock.pm buildperl/Collectd/; \
+ cp $(srcdir)/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm buildperl/Collectd/Plugins/; \
+ fi
+ touch $@
+
+.PHONY: perl
+
+
+if BUILD_WITH_JAVA
+dist_noinst_JAVA = \
+ bindings/java/org/collectd/api/Collectd.java \
+ bindings/java/org/collectd/api/CollectdConfigInterface.java \
+ bindings/java/org/collectd/api/CollectdFlushInterface.java \
+ bindings/java/org/collectd/api/CollectdInitInterface.java \
+ bindings/java/org/collectd/api/CollectdLogInterface.java \
+ bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java \
+ bindings/java/org/collectd/api/CollectdMatchInterface.java \
+ bindings/java/org/collectd/api/CollectdNotificationInterface.java \
+ bindings/java/org/collectd/api/CollectdReadInterface.java \
+ bindings/java/org/collectd/api/CollectdShutdownInterface.java \
+ bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java \
+ bindings/java/org/collectd/api/CollectdTargetInterface.java \
+ bindings/java/org/collectd/api/CollectdWriteInterface.java \
+ bindings/java/org/collectd/api/DataSet.java \
+ bindings/java/org/collectd/api/DataSource.java \
+ bindings/java/org/collectd/api/Notification.java \
+ bindings/java/org/collectd/api/OConfigItem.java \
+ bindings/java/org/collectd/api/OConfigValue.java \
+ bindings/java/org/collectd/api/PluginData.java \
+ bindings/java/org/collectd/api/ValueList.java \
+ bindings/java/org/collectd/java/GenericJMX.java \
+ bindings/java/org/collectd/java/GenericJMXConfConnection.java \
+ bindings/java/org/collectd/java/GenericJMXConfMBean.java \
+ bindings/java/org/collectd/java/GenericJMXConfValue.java \
+ bindings/java/org/collectd/java/JMXMemory.java
+
+collectd-api.jar: $(JAVA_TIMESTAMP_FILE)
+ $(JAR) cf $(JARFLAGS) $@ org/collectd/api/*.class
+
+generic-jmx.jar: $(JAVA_TIMESTAMP_FILE)
+ $(JAR) cf $(JARFLAGS) $@ org/collectd/java/*.class
+
+jar_DATA = collectd-api.jar generic-jmx.jar
+endif
hugepages can be found here:
https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt.
+ - intel_pmu
+ The intel_pmu plugin reads performance counters provided by the Linux
+ kernel perf interface. The plugin uses jevents library to resolve named
+ events to perf events and access perf interface.
+
- intel_rdt
The intel_rdt plugin collects information provided by monitoring features
of Intel Resource Director Technology (Intel(R) RDT) like Cache Monitoring
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).
- netapp
Plugin to query performance values from a NetApp storage system using the
- “Manage ONTAP” SDK provided by NetApp.
+ “Manage ONTAP” SDK provided by NetApp.
- netlink
Very detailed Linux network interface and routing statistics. You can get
plugin of choice for that.
- nfs
- NFS Procedures: Which NFS command were called how often. Only NFSv2 and
- NFSv3 right now.
+ NFS Procedures: Which NFS command were called how often.
- nginx
Collects statistics from `nginx' (speak: engine X), a HTTP and mail
- oracle
Query data from an Oracle database.
+ - ovs_events
+ The plugin monitors the link status of Open vSwitch (OVS) connected
+ interfaces, dispatches the values to collectd and sends the notification
+ whenever the link state change occurs in the OVS database. It requires
+ YAJL library to be installed.
+ Detailed instructions for installing and setting up Open vSwitch, see
+ OVS documentation.
+ <http://openvswitch.org/support/dist-docs/INSTALL.rst.html>
+
+ - ovs_stats
+ The plugin collects the statistics of OVS connected bridges and
+ interfaces. It requires YAJL library to be installed.
+ Detailed instructions for installing and setting up Open vSwitch, see
+ OVS documentation.
+ <http://openvswitch.org/support/dist-docs/INSTALL.rst.html>
+
- perl
The perl plugin implements a Perl-interpreter into collectd. You can
write your own plugins in Perl and return arbitrary values using this
updates to the files and write a bunch of updates at once, which lessens
system load a lot.
+ - snmp_agent
+ Receives and handles queries from SNMP master agent and returns the data
+ collected by read plugins. Handles requests only for OIDs specified in
+ configuration file. To handle SNMP queries the plugin gets data from
+ collectd and translates requested values from collectd's internal format
+ to SNMP format.
+
- unixsock
One can query the values from the unixsock plugin whenever they're
needed. Please read collectd-unixsock(5) for a description on how that's
Used by the `gps' plugin.
<http://developer.berlios.de/projects/gpsd/>
- * libhal (optional)
- If present, the `uuid' plugin will check for UUID from HAL.
- <http://hal.freedesktop.org/>
-
* libi2c-dev (optional)
Used for the plugin `barometer', provides just the i2c-dev.h header file
for user space i2c development.
For querying iptables counters.
<http://netfilter.org/>
+ * libjevents (optional)
+ The jevents library is used by the `intel_pmu' plugin to access the Linux
+ kernel perf interface.
+ Note: the library should be build with -fPIC flag to be linked with
+ intel_pmu shared object correctly.
+ <https://github.com/andikleen/pmu-tools>
+
* libjvm (optional)
Library that encapsulates the `Java Virtual Machine' (JVM). This library is
used by the `java' plugin to execute Java bytecode.
This library is part of the “Manage ONTAP SDK” published by NetApp.
* libnetsnmp (optional)
- For the `snmp' plugin.
+ For the `snmp' and 'snmp_agent' plugins.
+ <http://www.net-snmp.org/>
+
+ * libnetsnmpagent (optional)
+ Required for the 'snmp_agent' plugin.
<http://www.net-snmp.org/>
* libnotify (optional)
<http://www.xmms.org/>
* libyajl (optional)
- Parse JSON data. This is needed for the `ceph', `curl_json' and
- `log_logstash' plugins.
+ Parse JSON data. This is needed for the `ceph', `curl_json', 'ovs_events',
+ 'ovs_stats' and `log_logstash' plugins.
<http://github.com/lloyd/yajl>
* libvarnish (optional)
- flex
- bison
- libtool
-- libtool-ltdl
- pkg-config
The `build.sh' script takes no arguments.
+++ /dev/null
-SUBDIRS =
-
-if BUILD_WITH_JAVA
-SUBDIRS += java
-endif
-
-EXTRA_DIST = perl/Makefile.PL \
- perl/uninstall_mod.pl \
- perl/lib/Collectd.pm \
- perl/lib/Collectd/Unixsock.pm \
- perl/lib/Collectd/Plugins/Monitorus.pm \
- perl/lib/Collectd/Plugins/OpenVZ.pm
-
-CLEANFILES = \
- buildperl/Collectd.pm \
- buildperl/Collectd/Plugins/OpenVZ.pm \
- buildperl/Collectd/Unixsock.pm \
- buildperl/Makefile.PL \
- .perl-directory-stamp
-
-DISTCLEANFILES = \
- buildperl/Collectd.pm \
- buildperl/Collectd/Plugins/OpenVZ.pm \
- buildperl/Collectd/Unixsock.pm \
- buildperl/Makefile.PL \
- .perl-directory-stamp
-
-all-local: @PERL_BINDINGS@
-
-
-install-exec-local:
- [ ! -f buildperl/Makefile ] || ( cd buildperl && $(MAKE) install )
-
-# Perl 'make uninstall' does not work as well as wanted.
-# So we do the work here.
-uninstall-local:
- @PERL@ -I$(DESTDIR)$(prefix) $(srcdir)/perl/uninstall_mod.pl Collectd
- find $(DESTDIR)$(prefix) -name "perllocal.pod" -exec rm {} \;
-
-clean-local:
- rm -rf buildperl
-
-perl: buildperl/Makefile
- cd buildperl && $(MAKE)
-
-buildperl/Makefile: .perl-directory-stamp buildperl/Makefile.PL \
- $(top_builddir)/config.status
- @# beautify the output a bit
- @echo 'cd buildperl && @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@'
- @cd buildperl && ( if ! @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@; then \
- echo ""; \
- echo 'Check whether you have set $$PERL_MM_OPT in your environment and try using ./configure --with-perl-bindings=""'; \
- echo ""; \
- fi )
-
-buildperl/Makefile.PL: .perl-directory-stamp $(top_builddir)/config.status
-
-.perl-directory-stamp:
- if test ! -d buildperl; then \
- mkdir -p buildperl/Collectd/Plugins; \
- cp $(srcdir)/perl/lib/Collectd.pm buildperl/; \
- cp $(srcdir)/perl/Makefile.PL buildperl/; \
- cp $(srcdir)/perl/lib/Collectd/Unixsock.pm buildperl/Collectd/; \
- cp $(srcdir)/perl/lib/Collectd/Plugins/OpenVZ.pm buildperl/Collectd/Plugins/; \
- fi
- touch $@
-
-.PHONY: perl
-
+++ /dev/null
-EXTRA_DIST = org/collectd/api/CollectdConfigInterface.java \
- org/collectd/api/CollectdFlushInterface.java \
- org/collectd/api/CollectdInitInterface.java \
- org/collectd/api/Collectd.java \
- org/collectd/api/CollectdLogInterface.java \
- org/collectd/api/CollectdMatchFactoryInterface.java \
- org/collectd/api/CollectdMatchInterface.java \
- org/collectd/api/CollectdNotificationInterface.java \
- org/collectd/api/CollectdReadInterface.java \
- org/collectd/api/CollectdShutdownInterface.java \
- org/collectd/api/CollectdTargetFactoryInterface.java \
- org/collectd/api/CollectdTargetInterface.java \
- org/collectd/api/CollectdWriteInterface.java \
- org/collectd/api/DataSet.java \
- org/collectd/api/DataSource.java \
- org/collectd/api/Notification.java \
- org/collectd/api/OConfigItem.java \
- org/collectd/api/OConfigValue.java \
- org/collectd/api/PluginData.java \
- org/collectd/api/ValueList.java \
- org/collectd/java/GenericJMXConfConnection.java \
- org/collectd/java/GenericJMXConfMBean.java \
- org/collectd/java/GenericJMXConfValue.java \
- org/collectd/java/GenericJMX.java \
- org/collectd/java/JMXMemory.java
-
-java-build-stamp: $(srcdir)/org/collectd/api/*.java $(srcdir)/org/collectd/java/*.java
- $(JAVAC) -d "." "$(srcdir)/org/collectd/api"/*.java
- $(JAVAC) -d "." "$(srcdir)/org/collectd/java"/*.java
- mkdir -p .libs
- $(JAR) cf .libs/collectd-api.jar "org/collectd/api"/*.class
- $(JAR) cf .libs/generic-jmx.jar "org/collectd/java"/*.class
- touch "$@"
-
-all-local: java-build-stamp
-
-install-exec-local: java-build-stamp
- mkdir -p "$(DESTDIR)$(pkgdatadir)/java"
- $(INSTALL) -m 644 .libs/collectd-api.jar \
- "$(DESTDIR)$(pkgdatadir)/java"
- $(INSTALL) -m 644 .libs/generic-jmx.jar \
- "$(DESTDIR)$(pkgdatadir)/java"
-
-uninstall-local:
- rm -f "$(DESTDIR)$(pkgdatadir)/java/collectd-api.jar"
- rm -f "$(DESTDIR)$(pkgdatadir)/java/generic-jmx.jar"
- rmdir "$(DESTDIR)$(pkgdatadir)/java" || true
-
-clean-local:
- rm -f "org/collectd/api"/*.class
- rm -f "org/collectd/java"/*.class
- rm -f .libs
- rm -f "java-build-stamp"
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;
{
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 */
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
autoheader \
&& aclocal \
-&& $libtoolize --ltdl --copy --force \
+&& $libtoolize --copy --force \
&& automake --add-missing --copy \
&& autoconf
&& rm -f configure \
&& rm -f depcomp \
&& rm -f install-sh \
-&& rm -f -r libltdl \
&& rm -f libtool \
&& rm -f ltmain.sh \
&& rm -f Makefile \
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])])
AC_PROG_CC_C99([],
[AC_MSG_ERROR([No compiler found that supports C99])]
)
+
+AX_COMPILER_VENDOR
+
AC_PROG_CXX
AC_PROG_CPP
AC_PROG_EGREP
AC_PROG_LN_S
AC_PROG_MAKE_SET
AM_PROG_CC_C_O
-AM_CONDITIONAL(COMPILER_IS_GCC, test "x$GCC" = "xyes")
-AC_DISABLE_STATIC
-AC_PROG_LIBTOOL
AC_PROG_LEX
AC_PROG_YACC
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])
+if test "x$lt_cv_dlopen" = "xno"; then
+ AC_MSG_ERROR([Your system does not support dlopen])
fi
-AM_CONDITIONAL(HAVE_PROTOC3, test "x$have_protoc3" = "xyes")
-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])
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" = "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 \
kstat.h \
kvm.h \
libgen.h \
- limits.h \
- locale.h \
- math.h \
mntent.h \
mnttab.h \
netdb.h \
pthread_np.h \
pwd.h \
regex.h \
- signal.h \
- stdarg.h \
- stdio.h \
+ sys/endian.h \
sys/fs_types.h \
sys/fstyp.h \
sys/ioctl.h \
sys/vfstab.h \
sys/vmmeter.h \
syslog.h \
- wordexp.h \
+ wordexp.h
])
-# For entropy plugin on newer NetBSD
-AC_CHECK_HEADERS(sys/rndio.h, [], [],
-[#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-])
+if test "x$ac_system" = "xNetBSD"; then
+ # For entropy plugin on newer NetBSD
+ AC_CHECK_HEADERS([sys/rndio.h], [], [],
+ [[
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_SYS_IOCTL_H
+ # include <sys/ioctl.h>
+ #endif
+ #if HAVE_SYS_PARAM_H
+ # include <sys/param.h>
+ #endif
+ ]]
+ )
+fi
# For ping library
-AC_CHECK_HEADERS(netinet/in_systm.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/in.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/ip.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/ip_icmp.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-# include <netinet/ip.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/ip_var.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-# include <netinet/ip.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/ip6.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/icmp6.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP6_H
-# include <netinet/ip6.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/tcp.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-# include <netinet/ip.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/udp.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-# include <netinet/ip.h>
-#endif
-])
+AC_CHECK_HEADERS([netinet/in_systm.h], [], [],
+ [[
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ ]]
+)
-have_ip6_ext="no"
-AC_CHECK_TYPES([struct ip6_ext], [have_ip6_ext="yes"], [have_ip6_ext="no"],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP6_H
-# include <netinet/ip6.h>
-#endif
-])
+AC_CHECK_HEADERS([netinet/in.h], [], [],
+ [[
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_NETINET_IN_SYSTM_H
+ # include <netinet/in_systm.h>
+ #endif
+ ]]
+)
-if test "x$have_ip6_ext" = "xno"; then
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -DSOLARIS2=8"
-
- AC_CHECK_TYPES([struct ip6_ext],
- [have_ip6_ext="yes, with -DSOLARIS2=8"],
- [have_ip6_ext="no"],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP6_H
-# include <netinet/ip6.h>
-#endif
-])
+AC_CHECK_HEADERS([netinet/ip.h], [], [],
+ [[
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_NETINET_IN_SYSTM_H
+ # include <netinet/in_systm.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ ]]
+)
- if test "x$have_ip6_ext" = "xno"; then
- CFLAGS="$SAVE_CFLAGS"
- fi
-fi
+AC_CHECK_HEADERS([netinet/ip_icmp.h], [], [],
+ [[
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_NETINET_IN_SYSTM_H
+ # include <netinet/in_systm.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ #if HAVE_NETINET_IP_H
+ # include <netinet/ip.h>
+ #endif
+ ]]
+)
-# For cpu modules
-AC_CHECK_HEADERS(sys/dkstat.h)
-if test "x$ac_system" = "xDarwin"
-then
- AC_CHECK_HEADERS(mach/mach_init.h mach/host_priv.h mach/mach_error.h mach/mach_host.h mach/mach_port.h mach/mach_types.h mach/message.h mach/processor_set.h mach/processor.h mach/processor_info.h mach/task.h mach/thread_act.h mach/vm_region.h mach/vm_map.h mach/vm_prot.h mach/vm_statistics.h mach/kern_return.h)
- AC_CHECK_HEADERS(CoreFoundation/CoreFoundation.h IOKit/IOKitLib.h IOKit/IOTypes.h IOKit/ps/IOPSKeys.h IOKit/IOBSD.h IOKit/storage/IOBlockStorageDriver.h)
- # For the battery plugin
- AC_CHECK_HEADERS(IOKit/ps/IOPowerSources.h, [], [],
-[
-#if HAVE_IOKIT_IOKITLIB_H
-# include <IOKit/IOKitLib.h>
-#endif
-#if HAVE_IOKIT_IOTYPES_H
-# include <IOKit/IOTypes.h>
-#endif
-])
+AC_CHECK_HEADERS([netinet/ip_var.h], [], [],
+ [[
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_NETINET_IN_SYSTM_H
+ # include <netinet/in_systm.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ #if HAVE_NETINET_IP_H
+ # include <netinet/ip.h>
+ #endif
+ ]]
+)
-fi
+AC_CHECK_HEADERS([netinet/ip6.h], [], [],
+ [[
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_NETINET_IN_SYSTM_H
+ # include <netinet/in_systm.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ ]]
+)
-AC_CHECK_HEADERS(sys/sysctl.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-])
+AC_CHECK_HEADERS([netinet/icmp6.h], [], [],
+ [[
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_NETINET_IN_SYSTM_H
+ # include <netinet/in_systm.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ #if HAVE_NETINET_IP6_H
+ # include <netinet/ip6.h>
+ #endif
+ ]]
+)
-AC_MSG_CHECKING([for sysctl kern.cp_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/tcp.h], [], [],
+ [[
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_NETINET_IN_SYSTM_H
+ # include <netinet/in_systm.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ #if HAVE_NETINET_IP_H
+ # include <netinet/ip.h>
+ #endif
+ ]]
+)
-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/udp.h], [], [],
+ [[
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_NETINET_IN_SYSTM_H
+ # include <netinet/in_systm.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ #if HAVE_NETINET_IP_H
+ # include <netinet/ip.h>
+ #endif
+ ]]
+)
-# For hddtemp module
-AC_CHECK_HEADERS(linux/major.h)
+# 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 md module (Linux only)
-if test "x$ac_system" = "xLinux"
-then
- AC_CHECK_HEADERS(linux/raid/md_u.h,
- [have_linux_raid_md_u_h="yes"],
- [have_linux_raid_md_u_h="no"],
-[
-#include <sys/ioctl.h>
-#include <linux/major.h>
-#include <linux/types.h>
-])
- AC_CHECK_HEADERS([sys/sysmacros.h])
-else
- have_linux_raid_md_u_h="no"
+ # For the battery plugin
+ AC_CHECK_HEADERS([IOKit/ps/IOPowerSources.h], [], [],
+ [[
+ #if HAVE_IOKIT_IOKITLIB_H
+ # include <IOKit/IOKitLib.h>
+ #endif
+ #if HAVE_IOKIT_IOTYPES_H
+ # include <IOKit/IOTypes.h>
+ #endif
+ ]]
+ )
fi
-# For the wireless module
-have_linux_wireless_h="no"
-if test "x$ac_system" = "xLinux"
-then
- AC_CHECK_HEADERS(linux/wireless.h,
- [have_linux_wireless_h="yes"],
- [have_linux_wireless_h="no"],
-[
-#include <dirent.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-])
-fi
+AC_CHECK_HEADERS([sys/sysctl.h], [], [],
+ [[
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_SYS_PARAM_H
+ # include <sys/param.h>
+ #endif
+ ]]
+)
-# For the swap module
-have_sys_swap_h="yes"
-AC_CHECK_HEADERS(sys/swap.h vm/anon.h, [], [have_sys_swap_h="no"],
-[
-#undef _FILE_OFFSET_BITS
-#undef _LARGEFILE64_SOURCE
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-])
+# For interface plugin
+AC_CHECK_HEADERS([ifaddrs.h])
+AC_CHECK_HEADERS([net/if.h], [], [],
+ [[
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+ ]]
+)
-# For load module
-# For the processes plugin
-# For users module
-AC_CHECK_HEADERS(sys/loadavg.h linux/config.h utmp.h utmpx.h)
+if test "x$ac_system" = "xLinux"; then
+ # For hddtemp module
+ AC_CHECK_HEADERS([linux/major.h])
+
+ # For md module (Linux only)
+ AC_CHECK_HEADERS([linux/raid/md_u.h],
+ [have_linux_raid_md_u_h="yes"],
+ [have_linux_raid_md_u_h="no"],
+ [[
+ #include <sys/ioctl.h>
+ #include <linux/major.h>
+ #include <linux/types.h>
+ ]]
+ )
+ AC_CHECK_HEADERS([sys/sysmacros.h])
+
+ AC_CHECK_HEADERS([linux/wireless.h],
+ [have_linux_wireless_h="yes"],
+ [have_linux_wireless_h="no"],
+ [[
+ #include <dirent.h>
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
+ ]]
+ )
-# For interface plugin
-AC_CHECK_HEADERS(ifaddrs.h)
-AC_CHECK_HEADERS(net/if.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-])
-AC_CHECK_HEADERS(linux/if.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-])
-AC_CHECK_HEADERS(linux/inet_diag.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#if HAVE_LINUX_INET_DIAG_H
-# include <linux/inet_diag.h>
-#endif
-])
-AC_CHECK_HEADERS(linux/netdevice.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#if HAVE_LINUX_IF_H
-# include <linux/if.h>
-#endif
-])
+ AC_CHECK_HEADERS([linux/if.h], [], [],
+ [[
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+ ]]
+ )
-# For ethstat module
-AC_CHECK_HEADERS(linux/sockios.h,
+ AC_CHECK_HEADERS([linux/inet_diag.h], [], [],
+ [[
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+ ]]
+ )
+
+ AC_CHECK_HEADERS([linux/netdevice.h], [], [],
+ [[
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+ #if HAVE_LINUX_IF_H
+ # include <linux/if.h>
+ #endif
+ ]]
+ )
+
+ # For ethstat module
+ AC_CHECK_HEADERS([linux/sockios.h],
[have_linux_sockios_h="yes"],
[have_linux_sockios_h="no"],
- [
-#if HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#if HAVE_NET_IF_H
-# include <net/if.h>
-#endif
- ])
-AC_CHECK_HEADERS(linux/ethtool.h,
+ [[
+ #if HAVE_SYS_IOCTL_H
+ # include <sys/ioctl.h>
+ #endif
+ #if HAVE_NET_IF_H
+ # include <net/if.h>
+ #endif
+ ]]
+ )
+
+ AC_CHECK_HEADERS([linux/ethtool.h],
[have_linux_ethtool_h="yes"],
[have_linux_ethtool_h="no"],
- [
-#if HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#if HAVE_NET_IF_H
-# include <net/if.h>
-#endif
-#if HAVE_LINUX_SOCKIOS_H
-# include <linux/sockios.h>
-#endif
- ])
-
-# For ipvs module
-have_linux_ip_vs_h="no"
-have_net_ip_vs_h="no"
-have_ip_vs_h="no"
-ip_vs_h_needs_kernel_cflags="no"
-if test "x$ac_system" = "xLinux"
-then
- AC_CHECK_HEADERS(linux/ip_vs.h, [have_linux_ip_vs_h="yes"])
- AC_CHECK_HEADERS(net/ip_vs.h, [have_net_ip_vs_h="yes"])
- AC_CHECK_HEADERS(ip_vs.h, [have_ip_vs_h="yes"])
+ [[
+ #if HAVE_SYS_IOCTL_H
+ # include <sys/ioctl.h>
+ #endif
+ #if HAVE_NET_IF_H
+ # include <net/if.h>
+ #endif
+ #if HAVE_LINUX_SOCKIOS_H
+ # include <linux/sockios.h>
+ #endif
+ ]]
+ )
+
+ # For ipvs module
+ AC_CHECK_HEADERS_ONCE([linux/ip_vs.h])
- 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 the email plugin
+ AC_CHECK_HEADERS([linux/un.h], [], [],
+ [[
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+ ]]
+ )
+ # For the turbostat plugin
+ AC_CHECK_HEADERS([cpuid.h],
+ [have_cpuid_h="yes"],
+ [have_cpuid_h="no (cpuid.h not found)"]
+ )
+
+ AC_CHECK_HEADERS([sys/capability.h],
+ [have_capability="yes"],
+ [have_capability="no (<sys/capability.h> not found)"]
+ )
- AC_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 <sys/capability.h>]]
+ )
+ 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([BUILD_WITH_CAPABILITY], [test "x$have_capability" = "xyes"])
+
+# For the swap module
+have_sys_swap_h="yes"
+AC_CHECK_HEADERS([sys/swap.h vm/anon.h],
+ [],
+ [have_sys_swap_h="no"],
+ [[
+ #undef _FILE_OFFSET_BITS
+ #undef _LARGEFILE64_SOURCE
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_SYS_PARAM_H
+ # include <sys/param.h>
+ #endif
+ ]]
+)
+
+# For load module
+# For the processes plugin
+# For users module
+AC_CHECK_HEADERS([sys/loadavg.h linux/config.h utmp.h utmpx.h])
# For quota module
-AC_CHECK_HEADERS(sys/ucred.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-])
+AC_CHECK_HEADERS([sys/ucred.h], [], [],
+ [[
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_SYS_PARAM_H
+ # include <sys/param.h>
+ #endif
+ ]]
+)
# For mount interface
-AC_CHECK_HEADERS(sys/mount.h, [], [],
-[
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-])
-
-# For the email plugin
-AC_CHECK_HEADERS(linux/un.h, [], [],
-[
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-])
+AC_CHECK_HEADERS([sys/mount.h], [], [],
+ [[
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_SYS_PARAM_H
+ # include <sys/param.h>
+ #endif
+ ]]
+)
# --enable-xfs {{{
AC_ARG_ENABLE([xfs],
# }}}
# For the dns plugin
-AC_CHECK_HEADERS(arpa/nameser.h)
-AC_CHECK_HEADERS(arpa/nameser_compat.h, [], [],
-[
-#if HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#endif
-])
+AC_CHECK_HEADERS([arpa/nameser.h])
+AC_CHECK_HEADERS([arpa/nameser_compat.h], [], [],
+ [[
+ #if HAVE_ARPA_NAMESER_H
+ # include <arpa/nameser.h>
+ #endif
+ ]]
+)
-AC_CHECK_HEADERS(net/if_arp.h, [], [],
-[#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-])
-AC_CHECK_HEADERS(net/ppp_defs.h)
-AC_CHECK_HEADERS(net/if_ppp.h, [], [],
-[#if HAVE_NET_PPP_DEFS_H
-# include <net/ppp_defs.h>
-#endif
-])
-AC_CHECK_HEADERS(netinet/if_ether.h, [], [],
-[#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#if HAVE_NET_IF_H
-# include <net/if.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-])
+AC_CHECK_HEADERS([net/if_arp.h], [], [],
+ [[
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+ ]]
+)
-have_net_pfvar_h="no"
-AC_CHECK_HEADERS(net/pfvar.h,
- [have_net_pfvar_h="yes"],
- [have_net_pfvar_h="no"],
-[
-#if HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#if HAVE_NET_IF_H
-# include <net/if.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-])
+AC_CHECK_HEADERS([net/ppp_defs.h])
+AC_CHECK_HEADERS([net/if_ppp.h], [], [],
+ [[
+ #if HAVE_NET_PPP_DEFS_H
+ # include <net/ppp_defs.h>
+ #endif
+ ]]
+)
+
+AC_CHECK_HEADERS([netinet/if_ether.h], [], [],
+ [[
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+ #if HAVE_NET_IF_H
+ # include <net/if.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ ]]
+)
+
+AC_CHECK_HEADERS([net/pfvar.h],
+ [have_net_pfvar_h="yes"],
+ [have_net_pfvar_h="no"],
+ [[
+ #if HAVE_SYS_IOCTL_H
+ # include <sys/ioctl.h>
+ #endif
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #endif
+ #if HAVE_NET_IF_H
+ # include <net/if.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ ]]
+)
# For the multimeter plugin
-have_termios_h="no"
-AC_CHECK_HEADERS(termios.h, [have_termios_h="yes"])
+AC_CHECK_HEADERS([termios.h],
+ [have_termios_h="yes"],
+ [have_termios_h="no"]
+)
# For cpusleep plugin
AC_CACHE_CHECK([whether clock_boottime and clock_monotonic are supported],
- [c_cv_have_clock_boottime_monotonic],
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[
-#include <time.h>
-]],
-[[
- struct timespec b, m;
- clock_gettime(CLOCK_BOOTTIME, &b );
- clock_gettime(CLOCK_MONOTONIC, &m );
-]]
- )],
- [c_cv_have_clock_boottime_monotonic="yes"],
- [c_cv_have_clock_boottime_monotonic="no"]))
-
-
-# For the turbostat plugin
-AC_CHECK_HEADERS([cpuid.h],
- [have_cpuid_h="yes"],
- [have_cpuid_h="no (cpuid.h not found)"]
-)
-
-have_capability="yes"
-AC_CHECK_HEADERS(sys/capability.h,
- [have_capability="yes"],
- [have_capability="no (<sys/capability.h> not found)"])
-if test "x$have_capability" = "xyes"; then
-AC_CHECK_LIB(cap, cap_get_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 <sys/capability.h>]])
-fi
-if test "x$have_capability" = "xyes"; then
- AC_DEFINE(HAVE_CAPABILITY, 1, [Define to 1 if you have cap_get_proc() (-lcap).])
-fi
-AM_CONDITIONAL(BUILD_WITH_CAPABILITY, test "x$have_capability" = "xyes")
+ [c_cv_have_clock_boottime_monotonic],
+ [
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <time.h>]],
+ [[
+ struct timespec b, m;
+ clock_gettime(CLOCK_BOOTTIME, &b );
+ clock_gettime(CLOCK_MONOTONIC, &m );
+ ]]
+ )
+ ],
+ [c_cv_have_clock_boottime_monotonic="yes"],
+ [c_cv_have_clock_boottime_monotonic="no"]
+ )
+ ]
+)
+
#
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_UID_T
AC_HEADER_TIME
+test_cxx_flags() {
+ AC_LANG_PUSH([C++])
+ AC_LANG_CONFTEST(
+ [AC_LANG_SOURCE([[int main(void){}]]) ]
+ )
+ $CXX -c conftest.cpp $CXXFLAGS $@ > /dev/null 2> /dev/null
+ ret=$?
+ rm -f conftest.o
+ AC_LANG_POP([C++])
+ return $ret
+}
+
#
# Checks for library functions.
#
-AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv if_indextoname setlocale asprintf)
+AC_CHECK_FUNCS_ONCE([ \
+ asprintf \
+ closelog \
+ getaddrinfo \
+ getgrnam_r \
+ getnameinfo \
+ getpwnam_r \
+ gettimeofday \
+ if_indextoname \
+ openlog \
+ regcomp \
+ regerror \
+ regexec \
+ regfree \
+ select \
+ setenv \
+ setgroups \
+ strcasecmp \
+ strdup \
+ strncasecmp \
+ sysconf
+ ]
+)
AC_FUNC_STRERROR_R
-test_cxx_flags() {
- AC_LANG_PUSH([C++])
- AC_LANG_CONFTEST([
- AC_LANG_SOURCE([[int main(void){}]])
- ])
- $CXX -c conftest.cpp $CXXFLAGS $@ > /dev/null 2> /dev/null
- ret=$?
- rm -f conftest.o
- AC_LANG_POP([C++])
- return $ret
-}
-
SAVE_CFLAGS="$CFLAGS"
# Emulate behavior of src/Makefile.am
-if test "x$GCC" = "xyes"
-then
- CFLAGS="$CFLAGS -Wall -Werror"
+if test "x$GCC" = "xyes"; then
+ CFLAGS="$CFLAGS -Wall -Werror"
fi
AC_CACHE_CHECK([for strtok_r],
[c_cv_have_strtok_r_default],
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-]]],
-[[[
- char buffer[] = "foo,bar,baz";
- char *token;
- char *dummy;
- char *saveptr;
-
- dummy = buffer;
- saveptr = NULL;
- while ((token = strtok_r (dummy, ",", &saveptr)) != NULL)
- {
- dummy = NULL;
- printf ("token = %s;\n", token);
- }
-]]]
- )],
- [c_cv_have_strtok_r_default="yes"],
- [c_cv_have_strtok_r_default="no"]
- )
+ [
+ AC_LINK_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+ ]],
+ [[
+ char buffer[] = "foo,bar,baz";
+ char *token;
+ char *dummy;
+ char *saveptr;
+
+ dummy = buffer;
+ saveptr = NULL;
+ while ((token = strtok_r (dummy, ",", &saveptr)) != NULL)
+ {
+ dummy = NULL;
+ printf ("token = %s;\n", token);
+ }
+ ]]
+ )
+ ],
+ [c_cv_have_strtok_r_default="yes"],
+ [c_cv_have_strtok_r_default="no"]
+ )
+ ]
)
-if test "x$c_cv_have_strtok_r_default" = "xno"
-then
+if test "x$c_cv_have_strtok_r_default" = "xno"; then
CFLAGS="$CFLAGS -D_REENTRANT=1"
AC_CACHE_CHECK([if strtok_r needs _REENTRANT],
[c_cv_have_strtok_r_reentrant],
- AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-]]],
-[[[
- char buffer[] = "foo,bar,baz";
- char *token;
- char *dummy;
- char *saveptr;
-
- dummy = buffer;
- saveptr = NULL;
- while ((token = strtok_r (dummy, ",", &saveptr)) != NULL)
- {
- dummy = NULL;
- printf ("token = %s;\n", token);
- }
-]]]
- )],
- [c_cv_have_strtok_r_reentrant="yes"],
- [AC_MSG_FAILURE([strtok_r isn't available. Please file a bugreport!])]
- )
+ [
+ AC_LINK_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+ ]],
+ [[
+ char buffer[] = "foo,bar,baz";
+ char *token;
+ char *dummy;
+ char *saveptr;
+
+ dummy = buffer;
+ saveptr = NULL;
+ while ((token = strtok_r (dummy, ",", &saveptr)) != NULL)
+ {
+ dummy = NULL;
+ printf ("token = %s;\n", token);
+ }
+ ]]
+ )
+ ],
+ [c_cv_have_strtok_r_reentrant="yes"],
+ [AC_MSG_FAILURE([strtok_r is not available. Please file a bugreport!])]
+ )
+ ]
)
fi
CFLAGS="$SAVE_CFLAGS"
-if test "x$c_cv_have_strtok_r_reentrant" = "xyes"
-then
- CFLAGS="$CFLAGS -D_REENTRANT=1"
+if test "x$c_cv_have_strtok_r_reentrant" = "xyes"; then
+ CFLAGS="$CFLAGS -D_REENTRANT=1"
fi
-AC_CHECK_FUNCS(getpwnam_r getgrnam_r setgroups regcomp regerror regexec regfree)
-
-socket_needs_socket="no"
-AC_CHECK_FUNCS(socket, [], AC_CHECK_LIB(socket, socket, [socket_needs_socket="yes"], AC_MSG_ERROR(cannot find socket)))
-AM_CONDITIONAL(BUILD_WITH_LIBSOCKET, test "x$socket_needs_socket" = "xyes")
+AC_CHECK_FUNCS([socket],
+ [],
+ [
+ AC_CHECK_LIB([socket], [socket],
+ [socket_needs_socket="yes"],
+ [AC_MSG_ERROR([cannot find socket() in libsocket])]
+ )
+ ]
+)
+AM_CONDITIONAL([BUILD_WITH_LIBSOCKET], [test "x$socket_needs_socket" = "xyes"])
-clock_gettime_needs_rt="no"
clock_gettime_needs_posix4="no"
-have_clock_gettime="no"
-AC_CHECK_FUNCS(clock_gettime, [have_clock_gettime="yes"])
-if test "x$have_clock_gettime" = "xno"
-then
- AC_CHECK_LIB(rt, clock_gettime, [clock_gettime_needs_rt="yes"
- have_clock_gettime="yes"])
+AC_CHECK_FUNCS([clock_gettime],
+ [have_clock_gettime="yes"],
+ [have_clock_gettime="no"]
+)
+
+if test "x$have_clock_gettime" = "xno"; then
+ AC_CHECK_LIB([rt], [clock_gettime],
+ [
+ clock_gettime_needs_rt="yes"
+ have_clock_gettime="yes"
+ ]
+ )
fi
-if test "x$have_clock_gettime" = "xno"
-then
- AC_CHECK_LIB(posix4, clock_gettime, [clock_gettime_needs_posix4="yes"
- have_clock_gettime="yes"])
+
+if test "x$have_clock_gettime" = "xno"; then
+ AC_CHECK_LIB([posix4], [clock_gettime],
+ [
+ clock_gettime_needs_posix4="yes"
+ have_clock_gettime="yes"
+ ]
+ )
fi
-if test "x$have_clock_gettime" = "xyes"
-then
- AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if the clock_gettime(2) function is available.])
+
+if test "x$have_clock_gettime" = "xyes"; then
+ AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Define if the clock_gettime(2) function is available.])
fi
-nanosleep_needs_rt="no"
-nanosleep_needs_posix4="no"
-AC_CHECK_FUNCS(nanosleep,
- [],
- AC_CHECK_LIB(rt, nanosleep,
- [nanosleep_needs_rt="yes"],
- AC_CHECK_LIB(posix4, nanosleep,
- [nanosleep_needs_posix4="yes"],
- AC_MSG_ERROR(cannot find nanosleep))))
-
-AM_CONDITIONAL(BUILD_WITH_LIBRT, test "x$clock_gettime_needs_rt" = "xyes" || test "x$nanosleep_needs_rt" = "xyes")
-AM_CONDITIONAL(BUILD_WITH_LIBPOSIX4, test "x$clock_gettime_needs_posix4" = "xyes" || test "x$nanosleep_needs_posix4" = "xyes")
-
-AC_CHECK_FUNCS(sysctl, [have_sysctl="yes"], [have_sysctl="no"])
-AC_CHECK_FUNCS(sysctlbyname, [have_sysctlbyname="yes"], [have_sysctlbyname="no"])
-AC_CHECK_FUNCS(host_statistics, [have_host_statistics="yes"], [have_host_statistics="no"])
-AC_CHECK_FUNCS(processor_info, [have_processor_info="yes"], [have_processor_info="no"])
-AC_CHECK_FUNCS(thread_info, [have_thread_info="yes"], [have_thread_info="no"])
-AC_CHECK_FUNCS(statfs, [have_statfs="yes"], [have_statfs="no"])
-AC_CHECK_FUNCS(statvfs, [have_statvfs="yes"], [have_statvfs="no"])
-AC_CHECK_FUNCS(getifaddrs, [have_getifaddrs="yes"], [have_getifaddrs="no"])
-AC_CHECK_FUNCS(getloadavg, [have_getloadavg="yes"], [have_getloadavg="no"])
-AC_CHECK_FUNCS(syslog, [have_syslog="yes"], [have_syslog="no"])
-AC_CHECK_FUNCS(getutent, [have_getutent="yes"], [have_getutent="no"])
-AC_CHECK_FUNCS(getutxent, [have_getutxent="yes"], [have_getutxent="no"])
+AC_CHECK_FUNCS([nanosleep], [],
+ AC_CHECK_LIB([rt], [nanosleep],
+ [nanosleep_needs_rt="yes"],
+ [
+ AC_CHECK_LIB([posix4], [nanosleep],
+ [nanosleep_needs_posix4="yes"],
+ [AC_MSG_ERROR([cannot find nanosleep])]
+ )
+ ]
+ )
+)
+
+AM_CONDITIONAL([BUILD_WITH_LIBRT], [test "x$clock_gettime_needs_rt" = "xyes" || test "x$nanosleep_needs_rt" = "xyes"])
+AM_CONDITIONAL([BUILD_WITH_LIBPOSIX4], [test "x$clock_gettime_needs_posix4" = "xyes" || test "x$nanosleep_needs_posix4" = "xyes"])
+
+AC_CHECK_FUNCS([getifaddrs], [have_getifaddrs="yes"], [have_getifaddrs="no"])
+AC_CHECK_FUNCS([getloadavg], [have_getloadavg="yes"], [have_getloadavg="no"])
+AC_CHECK_FUNCS([getutent], [have_getutent="yes"], [have_getutent="no"])
+AC_CHECK_FUNCS([getutxent], [have_getutxent="yes"], [have_getutxent="no"])
+AC_CHECK_FUNCS([host_statistics], [have_host_statistics="yes"], [have_host_statistics="no"])
+AC_CHECK_FUNCS([processor_info], [have_processor_info="yes"], [have_processor_info="no"])
+AC_CHECK_FUNCS([statfs], [have_statfs="yes"], [have_statfs="no"])
+AC_CHECK_FUNCS([statvfs], [have_statvfs="yes"], [have_statvfs="no"])
+AC_CHECK_FUNCS([sysctl], [have_sysctl="yes"], [have_sysctl="no"])
+AC_CHECK_FUNCS([sysctlbyname], [have_sysctlbyname="yes"], [have_sysctlbyname="no"])
+AC_CHECK_FUNCS([syslog], [have_syslog="yes"], [have_syslog="no"])
+AC_CHECK_FUNCS([thread_info], [have_thread_info="yes"], [have_thread_info="no"])
# Check for strptime {{{
-if test "x$GCC" = "xyes"
-then
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS -Wall -Wextra -Werror"
+if test "x$GCC" = "xyes"; then
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wall -Wextra -Werror"
fi
-AC_CHECK_FUNCS(strptime, [have_strptime="yes"], [have_strptime="no"])
-if test "x$have_strptime" = "xyes"
-then
- AC_CACHE_CHECK([whether strptime is exported by default],
- [c_cv_have_strptime_default],
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <time.h>
-]]],
-[[[
- struct tm stm;
- (void) strptime ("2010-12-30%13:42:42", "%Y-%m-%dT%T", &stm);
-]]]
- )],
- [c_cv_have_strptime_default="yes"],
- [c_cv_have_strptime_default="no"]))
+AC_CHECK_FUNCS([strptime], [have_strptime="yes"], [have_strptime="no"])
+if test "x$have_strptime" = "xyes"; then
+ AC_CACHE_CHECK([whether strptime is exported by default],
+ [c_cv_have_strptime_default],
+ [
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[#include <time.h>]],
+ [[
+ struct tm stm;
+ (void)strptime ("2010-12-30%13:42:42", "%Y-%m-%dT%T", &stm);
+ ]]
+ )
+ ],
+ [c_cv_have_strptime_default="yes"],
+ [c_cv_have_strptime_default="no"])
+ ]
+ )
fi
-if test "x$have_strptime" = "xyes" && test "x$c_cv_have_strptime_default" = "xno"
-then
- AC_CACHE_CHECK([whether strptime needs standards mode],
- [c_cv_have_strptime_standards],
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[[
-#ifndef _ISOC99_SOURCE
-# define _ISOC99_SOURCE 1
-#endif
-#ifndef _POSIX_C_SOURCE
-# define _POSIX_C_SOURCE 200112L
-#endif
-#ifndef _XOPEN_SOURCE
-# define _XOPEN_SOURCE 500
-#endif
-#include <time.h>
-]]],
-[[[
- struct tm stm;
- (void) strptime ("2010-12-30%13:42:42", "%Y-%m-%dT%T", &stm);
-]]]
- )],
- [c_cv_have_strptime_standards="yes"],
- [c_cv_have_strptime_standards="no"]))
- if test "x$c_cv_have_strptime_standards" = "xyes"
- then
- AC_DEFINE([STRPTIME_NEEDS_STANDARDS], 1, [Set to true if strptime is only exported in X/Open mode (GNU libc).])
- else
- have_strptime="no"
- fi
+if test "x$have_strptime" = "xyes" && test "x$c_cv_have_strptime_default" = "xno"; then
+ AC_CACHE_CHECK([whether strptime needs standards mode],
+ [c_cv_have_strptime_standards],
+ [
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #ifndef _ISOC99_SOURCE
+ # define _ISOC99_SOURCE 1
+ #endif
+ #ifndef _POSIX_C_SOURCE
+ # define _POSIX_C_SOURCE 200112L
+ #endif
+ #ifndef _XOPEN_SOURCE
+ # define _XOPEN_SOURCE 500
+ #endif
+ #include <time.h>
+ ]],
+ [[
+ struct tm stm;
+ (void)strptime ("2010-12-30%13:42:42", "%Y-%m-%dT%T", &stm);
+ ]]
+ )
+ ],
+ [c_cv_have_strptime_standards="yes"],
+ [c_cv_have_strptime_standards="no"]
+ )
+ ]
+ )
+
+ if test "x$c_cv_have_strptime_standards" = "xyes"; then
+ AC_DEFINE([STRPTIME_NEEDS_STANDARDS], [1],
+ [Set to true if strptime is only exported in X/Open mode (GNU libc).]
+ )
+ else
+ have_strptime="no"
+ fi
fi
-if test "x$GCC" = "xyes"
-then
- CFLAGS="$SAVE_CFLAGS"
+if test "x$GCC" = "xyes"; then
+ CFLAGS="$SAVE_CFLAGS"
fi
# }}} Check for strptime
CFLAGS="$SAVE_CFLAGS"
# }}} Check for timegm
-AC_CHECK_FUNCS(swapctl, [have_swapctl="yes"], [have_swapctl="no"])
+AC_MSG_CHECKING([for sysctl kern.cp_times])
+if test -x /sbin/sysctl; then
+ /sbin/sysctl kern.cp_times >/dev/null 2>&1
+ if test $? -eq 0; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_SYSCTL_KERN_CP_TIMES], [1], [Define if sysctl supports kern.cp_times])
+ else
+ AC_MSG_RESULT([no])
+ fi
+else
+ AC_MSG_RESULT([no])
+fi
+
+AC_MSG_CHECKING([for sysctl kern.cp_time])
+if test -x /sbin/sysctl; then
+ /sbin/sysctl kern.cp_time >/dev/null 2>&1
+ if test $? -eq 0
+ then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_SYSCTL_KERN_CP_TIME], [1], [Define if sysctl supports kern.cp_time])
+ else
+ AC_MSG_RESULT([no])
+ fi
+else
+ AC_MSG_RESULT([no])
+fi
+
+AC_CHECK_FUNCS([swapctl], [have_swapctl="yes"], [have_swapctl="no"])
if test "x$have_swapctl" = "xyes"; then
- AC_CACHE_CHECK([whether swapctl takes two arguments],
- [c_cv_have_swapctl_two_args],
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[[
-#if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64
-# undef _FILE_OFFSET_BITS
-# undef _LARGEFILE64_SOURCE
-#endif
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <sys/swap.h>
-#include <unistd.h>
-]]],
-[[[
-int num = swapctl(0, NULL);
-]]]
- )],
- [c_cv_have_swapctl_two_args="yes"],
- [c_cv_have_swapctl_two_args="no"]
- )
- )
- AC_CACHE_CHECK([whether swapctl takes three arguments],
- [c_cv_have_swapctl_three_args],
- AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM(
-[[[
-#if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64
-# undef _FILE_OFFSET_BITS
-# undef _LARGEFILE64_SOURCE
-#endif
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <sys/swap.h>
-#include <unistd.h>
-]]],
-[[[
-int num = swapctl(0, NULL, 0);
-]]]
- )],
- [c_cv_have_swapctl_three_args="yes"],
- [c_cv_have_swapctl_three_args="no"]
- )
- )
+ AC_CACHE_CHECK([whether swapctl takes two arguments],
+ [c_cv_have_swapctl_two_args],
+ [
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64
+ # undef _FILE_OFFSET_BITS
+ # undef _LARGEFILE64_SOURCE
+ #endif
+ #include <sys/stat.h>
+ #include <sys/param.h>
+ #include <sys/swap.h>
+ #include <unistd.h>
+ ]],
+ [[int num = swapctl(0, NULL);]]
+ )
+ ],
+ [c_cv_have_swapctl_two_args="yes"],
+ [c_cv_have_swapctl_two_args="no"]
+ )
+ ]
+ )
+
+ AC_CACHE_CHECK([whether swapctl takes three arguments],
+ [c_cv_have_swapctl_three_args],
+ [
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64
+ # undef _FILE_OFFSET_BITS
+ # undef _LARGEFILE64_SOURCE
+ #endif
+ #include <sys/stat.h>
+ #include <sys/param.h>
+ #include <sys/swap.h>
+ #include <unistd.h>
+ ]],
+ [[int num = swapctl(0, NULL, 0);]]
+ )
+ ],
+ [c_cv_have_swapctl_three_args="yes"],
+ [c_cv_have_swapctl_three_args="no"]
+ )
+ ]
+ )
fi
+
# Check for different versions of `swapctl' here..
if test "x$have_swapctl" = "xyes"; then
- if test "x$c_cv_have_swapctl_two_args" = "xyes"; then
- AC_DEFINE(HAVE_SWAPCTL_TWO_ARGS, 1,
- [Define if the function swapctl exists and takes two arguments.])
- fi
- if test "x$c_cv_have_swapctl_three_args" = "xyes"; then
- AC_DEFINE(HAVE_SWAPCTL_THREE_ARGS, 1,
- [Define if the function swapctl exists and takes three arguments.])
- fi
+ if test "x$c_cv_have_swapctl_two_args" = "xyes"; then
+ AC_DEFINE([HAVE_SWAPCTL_TWO_ARGS], [1], [Define if the function swapctl exists and takes two arguments.])
+ fi
+
+ if test "x$c_cv_have_swapctl_three_args" = "xyes"; then
+ AC_DEFINE([HAVE_SWAPCTL_THREE_ARGS], [1], [Define if the function swapctl exists and takes three arguments.])
+ fi
fi
# Check for NAN
-AC_ARG_WITH(nan-emulation, [AS_HELP_STRING([--with-nan-emulation], [use emulated NAN. For crosscompiling only.])],
-[
- if test "x$withval" = "xno"; then
- nan_type="none"
- else if test "x$withval" = "xyes"; then
- nan_type="zero"
- else
- nan_type="$withval"
- fi; fi
-],
-[nan_type="none"])
+AC_ARG_WITH([nan-emulation],
+ [AS_HELP_STRING([--with-nan-emulation], [use emulated NAN. For crosscompiling only.])],
+ [
+ if test "x$withval" = "xno"; then
+ nan_type="none"
+ else if test "x$withval" = "xyes"; then
+ nan_type="zero"
+ else
+ nan_type="$withval"
+ fi; fi
+ ],
+ [nan_type="none"]
+)
+
if test "x$nan_type" = "xnone"; then
AC_CACHE_CHECK([whether NAN is defined by default],
[c_cv_have_nan_default],
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <math.h>
-static double foo = NAN;
-]]],
-[[[
- if (isnan (foo))
- return 0;
- else
- return 1;
-]]]
- )],
- [c_cv_have_nan_default="yes"],
- [c_cv_have_nan_default="no"]
- )
+ [
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <stdlib.h>
+ #include <math.h>
+ static double foo = NAN;
+ ]],
+ [[
+ if (isnan (foo))
+ return 0;
+ return 1;
+ ]]
+ )
+ ],
+ [c_cv_have_nan_default="yes"],
+ [c_cv_have_nan_default="no"]
+ )
+ ]
)
- if test "x$c_cv_have_nan_default" = "xyes"
- then
- nan_type="default"
- fi
fi
+
+if test "x$c_cv_have_nan_default" = "xyes"; then
+ nan_type="default"
+fi
+
if test "x$nan_type" = "xnone"; then
AC_CACHE_CHECK([whether NAN is defined by __USE_ISOC99],
[c_cv_have_nan_isoc],
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#define __USE_ISOC99 1
-#include <math.h>
-static double foo = NAN;
-]]],
-[[[
- if (isnan (foo))
- return 0;
- else
- return 1;
-]]]
- )],
- [c_cv_have_nan_isoc="yes"],
- [c_cv_have_nan_isoc="no"]
- )
+ [
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <stdlib.h>
+ #define __USE_ISOC99 1
+ #include <math.h>
+ static double foo = NAN;
+ ]],
+ [[
+ if (isnan (foo))
+ return 0;
+ return 1;
+ ]]
+ )
+ ],
+ [c_cv_have_nan_isoc="yes"],
+ [c_cv_have_nan_isoc="no"]
+ )
+ ]
)
- if test "x$c_cv_have_nan_isoc" = "xyes"
- then
- nan_type="isoc99"
- fi
fi
+
+if test "x$c_cv_have_nan_isoc" = "xyes"; then
+ nan_type="isoc99"
+fi
+
if test "x$nan_type" = "xnone"; then
- SAVE_LDFLAGS=$LDFLAGS
+ SAVE_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -lm"
AC_CACHE_CHECK([whether NAN can be defined by 0/0],
[c_cv_have_nan_zero],
- AC_RUN_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <math.h>
-#ifdef NAN
-# undef NAN
-#endif
-#define NAN (0.0 / 0.0)
-#ifndef isnan
-# define isnan(f) ((f) != (f))
-#endif
-static double foo = NAN;
-]]],
-[[[
- if (isnan (foo))
- return 0;
- else
- return 1;
-]]]
- )],
- [c_cv_have_nan_zero="yes"],
- [c_cv_have_nan_zero="no"]
- )
+ [
+ AC_RUN_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <stdlib.h>
+ #include <math.h>
+ #ifdef NAN
+ # undef NAN
+ #endif
+ #define NAN (0.0 / 0.0)
+ #ifndef isnan
+ # define isnan(f) ((f) != (f))
+ #endif
+ static double foo = NAN;
+ ]],
+ [[
+ if (isnan (foo))
+ return 0;
+ return 1;
+ ]]
+ )
+ ],
+ [c_cv_have_nan_zero="yes"],
+ [c_cv_have_nan_zero="no"]
+ )
+ ]
)
LDFLAGS=$SAVE_LDFLAGS
- if test "x$c_cv_have_nan_zero" = "xyes"
- then
- nan_type="zero"
- fi
+fi
+
+if test "x$c_cv_have_nan_zero" = "xyes"; then
+ nan_type="zero"
fi
if test "x$nan_type" = "xdefault"; then
- AC_DEFINE(NAN_STATIC_DEFAULT, 1,
- [Define if NAN is defined by default and can initialize static variables.])
+ AC_DEFINE([NAN_STATIC_DEFAULT], [1],
+ [Define if NAN is defined by default and can initialize static variables.]
+ )
else if test "x$nan_type" = "xisoc99"; then
- AC_DEFINE(NAN_STATIC_ISOC, 1,
- [Define if NAN is defined by __USE_ISOC99 and can initialize static variables.])
+ AC_DEFINE([NAN_STATIC_ISOC], [1],
+ [Define if NAN is defined by __USE_ISOC99 and can initialize static variables.]
+ )
else if test "x$nan_type" = "xzero"; then
- AC_DEFINE(NAN_ZERO_ZERO, 1,
- [Define if NAN can be defined as (0.0 / 0.0)])
+ AC_DEFINE([NAN_ZERO_ZERO], [1],
+ [Define if NAN can be defined as (0.0 / 0.0)]
+ )
else
AC_MSG_ERROR([Didn't find out how to statically initialize variables to NAN. Sorry.])
fi; fi; fi
-AC_ARG_WITH(fp-layout, [AS_HELP_STRING([--with-fp-layout], [set the memory layout of doubles. For crosscompiling only.])],
-[
- if test "x$withval" = "xnothing"; then
- fp_layout_type="nothing"
- else if test "x$withval" = "xendianflip"; then
- fp_layout_type="endianflip"
- else if test "x$withval" = "xintswap"; then
- fp_layout_type="intswap"
- else
- AC_MSG_ERROR([Invalid argument for --with-fp-layout. Valid arguments are: nothing, endianflip, intswap]);
-fi; fi; fi
-],
-[fp_layout_type="unknown"])
+AC_ARG_WITH([fp-layout],
+ [
+ AS_HELP_STRING([--with-fp-layout],
+ [set the memory layout of doubles. For crosscompiling only.]
+ )
+ ],
+ [
+ if test "x$withval" = "xnothing"; then
+ fp_layout_type="nothing"
+ else if test "x$withval" = "xendianflip"; then
+ fp_layout_type="endianflip"
+ else if test "x$withval" = "xintswap"; then
+ fp_layout_type="intswap"
+ else
+ AC_MSG_ERROR([Invalid argument for --with-fp-layout. Valid arguments are: nothing, endianflip, intswap]);
+ fi; fi; fi
+ ],
+ [fp_layout_type="unknown"]
+)
if test "x$fp_layout_type" = "xunknown"; then
AC_CACHE_CHECK([if doubles are stored in x86 representation],
[c_cv_fp_layout_need_nothing],
- AC_RUN_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#if HAVE_STDBOOL_H
-# include <stdbool.h>
-#endif
-]]],
-[[[
- uint64_t i0;
- uint64_t i1;
- uint8_t c[8];
- double d;
-
- d = 8.642135e130;
- memcpy ((void *) &i0, (void *) &d, 8);
-
- i1 = i0;
- memcpy ((void *) c, (void *) &i1, 8);
-
- if ((c[0] == 0x2f) && (c[1] == 0x25)
- && (c[2] == 0xc0) && (c[3] == 0xc7)
- && (c[4] == 0x43) && (c[5] == 0x2b)
- && (c[6] == 0x1f) && (c[7] == 0x5b))
- return (0);
- else
- return (1);
-]]]
- )],
- [c_cv_fp_layout_need_nothing="yes"],
- [c_cv_fp_layout_need_nothing="no"]
- )
+ [
+ AC_RUN_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdint.h>
+ #include <inttypes.h>
+ #include <stdbool.h>
+ ]],
+ [[
+ uint64_t i0;
+ uint64_t i1;
+ uint8_t c[8];
+ double d;
+
+ d = 8.642135e130;
+ memcpy ((void *) &i0, (void *) &d, 8);
+
+ i1 = i0;
+ memcpy ((void *) c, (void *) &i1, 8);
+
+ if ((c[0] == 0x2f) && (c[1] == 0x25)
+ && (c[2] == 0xc0) && (c[3] == 0xc7)
+ && (c[4] == 0x43) && (c[5] == 0x2b)
+ && (c[6] == 0x1f) && (c[7] == 0x5b))
+ return 0;
+ return 1;
+ ]]
+ )
+ ],
+ [c_cv_fp_layout_need_nothing="yes"],
+ [c_cv_fp_layout_need_nothing="no"]
+ )
+ ]
)
- if test "x$c_cv_fp_layout_need_nothing" = "xyes"; then
- fp_layout_type="nothing"
- fi
fi
+
+if test "x$c_cv_fp_layout_need_nothing" = "xyes"; then
+ fp_layout_type="nothing"
+fi
+
if test "x$fp_layout_type" = "xunknown"; then
AC_CACHE_CHECK([if endianflip converts to x86 representation],
[c_cv_fp_layout_need_endianflip],
- AC_RUN_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#if HAVE_STDBOOL_H
-# include <stdbool.h>
-#endif
-#define endianflip(A) ((((uint64_t)(A) & 0xff00000000000000LL) >> 56) | \
- (((uint64_t)(A) & 0x00ff000000000000LL) >> 40) | \
- (((uint64_t)(A) & 0x0000ff0000000000LL) >> 24) | \
- (((uint64_t)(A) & 0x000000ff00000000LL) >> 8) | \
- (((uint64_t)(A) & 0x00000000ff000000LL) << 8) | \
- (((uint64_t)(A) & 0x0000000000ff0000LL) << 24) | \
- (((uint64_t)(A) & 0x000000000000ff00LL) << 40) | \
- (((uint64_t)(A) & 0x00000000000000ffLL) << 56))
-]]],
-[[[
- uint64_t i0;
- uint64_t i1;
- uint8_t c[8];
- double d;
-
- d = 8.642135e130;
- memcpy ((void *) &i0, (void *) &d, 8);
-
- i1 = endianflip (i0);
- memcpy ((void *) c, (void *) &i1, 8);
-
- if ((c[0] == 0x2f) && (c[1] == 0x25)
- && (c[2] == 0xc0) && (c[3] == 0xc7)
- && (c[4] == 0x43) && (c[5] == 0x2b)
- && (c[6] == 0x1f) && (c[7] == 0x5b))
- return (0);
- else
- return (1);
-]]]
- )],
- [c_cv_fp_layout_need_endianflip="yes"],
- [c_cv_fp_layout_need_endianflip="no"]
+ [
+ AC_RUN_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdint.h>
+ #include <inttypes.h>
+ #include <stdbool.h>
+ #define endianflip(A) ((((uint64_t)(A) & 0xff00000000000000LL) >> 56) | \
+ (((uint64_t)(A) & 0x00ff000000000000LL) >> 40) | \
+ (((uint64_t)(A) & 0x0000ff0000000000LL) >> 24) | \
+ (((uint64_t)(A) & 0x000000ff00000000LL) >> 8) | \
+ (((uint64_t)(A) & 0x00000000ff000000LL) << 8) | \
+ (((uint64_t)(A) & 0x0000000000ff0000LL) << 24) | \
+ (((uint64_t)(A) & 0x000000000000ff00LL) << 40) | \
+ (((uint64_t)(A) & 0x00000000000000ffLL) << 56))
+ ]],
+ [[
+ uint64_t i0;
+ uint64_t i1;
+ uint8_t c[8];
+ double d;
+
+ d = 8.642135e130;
+ memcpy ((void *) &i0, (void *) &d, 8);
+
+ i1 = endianflip (i0);
+ memcpy ((void *) c, (void *) &i1, 8);
+
+ if ((c[0] == 0x2f) && (c[1] == 0x25)
+ && (c[2] == 0xc0) && (c[3] == 0xc7)
+ && (c[4] == 0x43) && (c[5] == 0x2b)
+ && (c[6] == 0x1f) && (c[7] == 0x5b))
+ return 0;
+ return 1;
+ ]]
+ )
+ ],
+ [c_cv_fp_layout_need_endianflip="yes"],
+ [c_cv_fp_layout_need_endianflip="no"]
+ ]
)
)
- if test "x$c_cv_fp_layout_need_endianflip" = "xyes"; then
- fp_layout_type="endianflip"
- fi
fi
+
+if test "x$c_cv_fp_layout_need_endianflip" = "xyes"; then
+ fp_layout_type="endianflip"
+fi
+
if test "x$fp_layout_type" = "xunknown"; then
AC_CACHE_CHECK([if intswap converts to x86 representation],
[c_cv_fp_layout_need_intswap],
- AC_RUN_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#if HAVE_STDBOOL_H
-# include <stdbool.h>
-#endif
-#define intswap(A) ((((uint64_t)(A) & 0xffffffff00000000LL) >> 32) | \
- (((uint64_t)(A) & 0x00000000ffffffffLL) << 32))
-]]],
-[[[
- uint64_t i0;
- uint64_t i1;
- uint8_t c[8];
- double d;
-
- d = 8.642135e130;
- memcpy ((void *) &i0, (void *) &d, 8);
-
- i1 = intswap (i0);
- memcpy ((void *) c, (void *) &i1, 8);
-
- if ((c[0] == 0x2f) && (c[1] == 0x25)
- && (c[2] == 0xc0) && (c[3] == 0xc7)
- && (c[4] == 0x43) && (c[5] == 0x2b)
- && (c[6] == 0x1f) && (c[7] == 0x5b))
- return (0);
- else
- return (1);
-]]]
- )],
- [c_cv_fp_layout_need_intswap="yes"],
- [c_cv_fp_layout_need_intswap="no"]
- )
+ [
+ AC_RUN_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdint.h>
+ #include <inttypes.h>
+ #include <stdbool.h>
+ #define intswap(A) ((((uint64_t)(A) & 0xffffffff00000000LL) >> 32) | \
+ (((uint64_t)(A) & 0x00000000ffffffffLL) << 32))
+ ]],
+ [[
+ uint64_t i0;
+ uint64_t i1;
+ uint8_t c[8];
+ double d;
+
+ d = 8.642135e130;
+ memcpy ((void *) &i0, (void *) &d, 8);
+
+ i1 = intswap (i0);
+ memcpy ((void *) c, (void *) &i1, 8);
+
+ if ((c[0] == 0x2f) && (c[1] == 0x25)
+ && (c[2] == 0xc0) && (c[3] == 0xc7)
+ && (c[4] == 0x43) && (c[5] == 0x2b)
+ && (c[6] == 0x1f) && (c[7] == 0x5b))
+ return 0;
+ return 1;
+ ]]
+ )
+ ],
+ [c_cv_fp_layout_need_intswap="yes"],
+ [c_cv_fp_layout_need_intswap="no"]
+ )
+ ]
)
- if test "x$c_cv_fp_layout_need_intswap" = "xyes"; then
- fp_layout_type="intswap"
- fi
+fi
+
+if test "x$c_cv_fp_layout_need_intswap" = "xyes"; then
+ fp_layout_type="intswap"
fi
if test "x$fp_layout_type" = "xnothing"; then
- AC_DEFINE(FP_LAYOUT_NEED_NOTHING, 1,
- [Define if doubles are stored in x86 representation.])
+ AC_DEFINE([FP_LAYOUT_NEED_NOTHING], [1],
+ [Define if doubles are stored in x86 representation.]
+ )
else if test "x$fp_layout_type" = "xendianflip"; then
- AC_DEFINE(FP_LAYOUT_NEED_ENDIANFLIP, 1,
- [Define if endianflip is needed to convert to x86 representation.])
+ AC_DEFINE([FP_LAYOUT_NEED_ENDIANFLIP], [1],
+ [Define if endianflip is needed to convert to x86 representation.]
+ )
else if test "x$fp_layout_type" = "xintswap"; then
- AC_DEFINE(FP_LAYOUT_NEED_INTSWAP, 1,
- [Define if intswap is needed to convert to x86 representation.])
+ AC_DEFINE([FP_LAYOUT_NEED_INTSWAP], [1],
+ [Define if intswap is needed to convert to x86 representation.]
+ )
else
AC_MSG_ERROR([Didn't find out how doubles are stored in memory. Sorry.])
fi; fi; fi
+# For cpusleep plugin
+AC_CACHE_CHECK([whether clock_boottime and clock_monotonic are supported],
+ [c_cv_have_clock_boottime_monotonic],
+ [
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <time.h>]],
+ [[
+ struct timespec b, m;
+ clock_gettime(CLOCK_BOOTTIME, &b );
+ clock_gettime(CLOCK_MONOTONIC, &m );
+ ]]
+ )
+ ],
+ [c_cv_have_clock_boottime_monotonic="yes"],
+ [c_cv_have_clock_boottime_monotonic="no"]
+ )
+ ]
+)
+
# --with-useragent {{{
-AC_ARG_WITH(useragent, [AS_HELP_STRING([--with-useragent@<:@=AGENT@:>@], [User agent to use on http requests])],
-[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
- then
- AC_DEFINE_UNQUOTED(COLLECTD_USERAGENT, ["$withval"], [User agent for http requests])
+AC_ARG_WITH([useragent],
+ [AS_HELP_STRING([--with-useragent@<:@=AGENT@:>@], [User agent to use on http requests])],
+ [
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+ AC_DEFINE_UNQUOTED([COLLECTD_USERAGENT], ["$withval"], [User agent for http requests])
fi
-])
+ ]
+)
# }}}
# --with-data-max-name-len {{{
-AC_ARG_WITH(data-max-name-len, [AS_HELP_STRING([--with-data-max-name-len@<:@=VALUE@:>@], [Maximum length of data buffers])],
-[
- if test "x$withval" != "x" && test $withval -gt 0
- then
- AC_DEFINE_UNQUOTED(DATA_MAX_NAME_LEN, [$withval], [Maximum length of data buffers])
+AC_ARG_WITH([data-max-name-len],
+ [AS_HELP_STRING([--with-data-max-name-len@<:@=VALUE@:>@], [Maximum length of data buffers])],
+ [
+ if test "x$withval" != "x" && test $withval -gt 0; then
+ AC_DEFINE_UNQUOTED([DATA_MAX_NAME_LEN], [$withval], [Maximum length of data buffers])
else
- AC_MSG_ERROR([DATA_MAX_NAME_LEN must be a positive integer -- $withval given])
+ AC_MSG_ERROR([DATA_MAX_NAME_LEN must be a positive integer -- $withval given])
fi
-],
-[ AC_DEFINE(DATA_MAX_NAME_LEN, 128, [Maximum length of data buffers])]
+ ],
+ [AC_DEFINE([DATA_MAX_NAME_LEN], [128], [Maximum length of data buffers])]
)
# }}}
-have_getfsstat="no"
-AC_CHECK_FUNCS(getfsstat, [have_getfsstat="yes"])
-have_getvfsstat="no"
-AC_CHECK_FUNCS(getvfsstat, [have_getvfsstat="yes"])
-have_listmntent="no"
-AC_CHECK_FUNCS(listmntent, [have_listmntent="yes"])
-have_getmntent_r="no"
-AC_CHECK_FUNCS(getmntent_r, [have_getmntent_r="yes"])
-
-have_getmntent="no"
-AC_CHECK_FUNCS(getmntent, [have_getmntent="c"])
+AC_CHECK_FUNCS([getfsstat], [have_getfsstat="yes"], [have_getfsstat="no"])
+AC_CHECK_FUNCS(getvfsstat, [have_getvfsstat="yes"], [have_getvfsstat="no"])
+AC_CHECK_FUNCS(listmntent, [have_listmntent="yes"], [have_listmntent="no"])
+AC_CHECK_FUNCS(getmntent_r, [have_getmntent_r="yes"], [have_getmntent_r="no"])
+
+AC_CHECK_FUNCS(getmntent, [have_getmntent="libc"], [have_getmntent="no"])
if test "x$have_getmntent" = "xno"; then
- AC_CHECK_LIB(sun, getmntent, [have_getmntent="sun"])
+ AC_CHECK_LIB([sun], [getmntent],
+ [have_getmntent="sun"],
+ [have_gemntent="no"]
+ )
fi
+
if test "x$have_getmntent" = "xno"; then
- AC_CHECK_LIB(seq, getmntent, [have_getmntent="seq"])
+ AC_CHECK_LIB([seq], [getmntent],
+ [have_getmntent="seq"],
+ [have_getmntent="no"]
+ )
fi
+
if test "x$have_getmntent" = "xno"; then
- AC_CHECK_LIB(gen, getmntent, [have_getmntent="gen"])
+ AC_CHECK_LIB([gen], [getmntent],
+ [have_getmntent="gen"],
+ [have_getmntent="no"]
+ )
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"]
- )
- )
+if test "x$have_getmntent" = "xlibc"; then
+ AC_CACHE_CHECK([whether getmntent takes one argument],
+ [c_cv_have_one_getmntent],
+ [
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[#include "$srcdir/src/utils_mount.h"]],
+ [[
+ FILE *fh;
+ struct mntent *me;
+ fh = setmntent ("/etc/mtab", "r");
+ me = getmntent (fh);
+ return(me->mnt_passno);
+ ]]
+ )
+ ],
+ [c_cv_have_one_getmntent="yes"],
+ [c_cv_have_one_getmntent="no"]
+ )
+ ]
+ )
+
+ AC_CACHE_CHECK([whether getmntent takes two arguments],
+ [c_cv_have_two_getmntent],
+ [
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[#include "$srcdir/src/utils_mount.h"]],
+ [[
+ FILE *fh;
+ struct mnttab mt;
+ int status;
+ fh = fopen ("/etc/mnttab", "r");
+ status = getmntent (fh, &mt);
+ return(status);
+ ]]
+ )
+ ],
+ [c_cv_have_two_getmntent="yes"],
+ [c_cv_have_two_getmntent="no"]
+ )
+ ]
+ )
fi
# Check for different versions of `getmntent' here..
-if test "x$have_getmntent" = "xc"; then
- if test "x$c_cv_have_one_getmntent" = "xyes"; then
- AC_DEFINE(HAVE_ONE_GETMNTENT, 1,
- [Define if the function getmntent exists and takes one argument.])
- fi
- if test "x$c_cv_have_two_getmntent" = "xyes"; then
- AC_DEFINE(HAVE_TWO_GETMNTENT, 1,
- [Define if the function getmntent exists and takes two arguments.])
- fi
+if test "x$have_getmntent" = "xlibc"; then
+ if test "x$c_cv_have_one_getmntent" = "xyes"; then
+ AC_DEFINE([HAVE_ONE_GETMNTENT], [1],
+ [Define if the function getmntent exists and takes one argument.]
+ )
+ fi
+
+ if test "x$c_cv_have_two_getmntent" = "xyes"; then
+ AC_DEFINE([HAVE_TWO_GETMNTENT], [1],
+ [Define if the function getmntent exists and takes two arguments.]
+ )
+ fi
fi
+
if test "x$have_getmntent" = "xsun"; then
- AC_DEFINE(HAVE_SUN_GETMNTENT, 1,
- [Define if the function getmntent exists. It is the version from libsun.])
-fi
-if test "x$have_getmntent" = "xseq"; then
- AC_DEFINE(HAVE_SEQ_GETMNTENT, 1,
- [Define if the function getmntent exists. It is the version from libseq.])
+ AC_DEFINE([HAVE_SUN_GETMNTENT], [1],
+ [Define if the function getmntent exists. It is the version from libsun.]
+ )
fi
+
if test "x$have_getmntent" = "xgen"; then
- AC_DEFINE(HAVE_GEN_GETMNTENT, 1,
- [Define if the function getmntent exists. It is the version from libgen.])
+ AC_DEFINE([HAVE_GEN_GETMNTENT], [1],
+ [Define if the function getmntent exists. It is the version from libgen.]
+ )
fi
# Check for htonll
-AC_CACHE_CHECK([if have htonll defined],
- [c_cv_have_htonll],
- AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <sys/types.h>
-#include <netinet/in.h>
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-]]],
-[[[
- return htonll(0);
-]]]
- )],
- [c_cv_have_htonll="yes"],
- [c_cv_have_htonll="no"]
- )
+AC_CACHE_CHECK([whether htonll is defined],
+ [c_cv_have_htonll],
+ [
+ AC_LINK_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <inttypes.h>
+ #include <sys/types.h>
+ #include <netinet/in.h>
+ ]],
+ [[return htonll(0);]]
+ )
+ ],
+ [c_cv_have_htonll="yes"],
+ [c_cv_have_htonll="no"]
+ )
+ ]
)
-if test "x$c_cv_have_htonll" = "xyes"
-then
- AC_DEFINE(HAVE_HTONLL, 1, [Define if the function htonll exists.])
+
+if test "x$c_cv_have_htonll" = "xyes"; then
+ AC_DEFINE([HAVE_HTONLL], [1], [Define if the function htonll exists.])
fi
# Check for structures
AC_CHECK_MEMBERS([struct if_data.ifi_ibytes, struct if_data.ifi_opackets, struct if_data.ifi_ierrors],
- [AC_DEFINE(HAVE_STRUCT_IF_DATA, 1, [Define if struct if_data exists and is usable.])],
- [],
- [
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <net/if.h>
- ])
+ [AC_DEFINE([HAVE_STRUCT_IF_DATA], [1], [Define if struct if_data exists and is usable.])],
+ [],
+ [[
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <net/if.h>
+ ]]
+)
+
AC_CHECK_MEMBERS([struct net_device_stats.rx_bytes, struct net_device_stats.tx_packets, struct net_device_stats.rx_errors],
- [AC_DEFINE(HAVE_STRUCT_NET_DEVICE_STATS, 1, [Define if struct net_device_stats exists and is usable.])],
- [],
- [
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <linux/if.h>
- #include <linux/netdevice.h>
- ])
-AC_CHECK_MEMBERS([struct inet_diag_req.id, struct inet_diag_req.idiag_states],
- [AC_DEFINE(HAVE_STRUCT_LINUX_INET_DIAG_REQ, 1, [Define if struct inet_diag_req exists and is usable.])],
- [],
- [
- #include <linux/inet_diag.h>
- ])
+ [AC_DEFINE([HAVE_STRUCT_NET_DEVICE_STATS], [1], [Define if struct net_device_stats exists and is usable.])],
+ [],
+ [[
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <linux/if.h>
+ #include <linux/netdevice.h>
+ ]]
+)
+AC_CHECK_MEMBERS([struct inet_diag_req.id, struct inet_diag_req.idiag_states],
+ [AC_DEFINE([HAVE_STRUCT_LINUX_INET_DIAG_REQ], [1], [Define if struct inet_diag_req exists and is usable.])],
+ [],
+ [[#include <linux/inet_diag.h>]]
+)
AC_CHECK_MEMBERS([struct ip_mreqn.imr_ifindex], [],
- [],
- [
- #include <netinet/in.h>
- #include <net/if.h>
- ])
+ [],
+ [[
+ #include <netinet/in.h>
+ #include <net/if.h>
+ ]]
+)
AC_CHECK_MEMBERS([struct kinfo_proc.ki_pid, struct kinfo_proc.ki_rssize, struct kinfo_proc.ki_rusage],
- [
- AC_DEFINE(HAVE_STRUCT_KINFO_PROC_FREEBSD, 1,
- [Define if struct kinfo_proc exists in the FreeBSD variant.])
- have_struct_kinfo_proc_freebsd="yes"
- ],
- [
- have_struct_kinfo_proc_freebsd="no"
- ],
- [
-#include <kvm.h>
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <sys/user.h>
- ])
+ [
+ AC_DEFINE([HAVE_STRUCT_KINFO_PROC_FREEBSD], [1], [Define if struct kinfo_proc exists in the FreeBSD variant.])
+ have_struct_kinfo_proc_freebsd="yes"
+ ],
+ [],
+ [[
+ #include <kvm.h>
+ #include <sys/param.h>
+ #include <sys/sysctl.h>
+ #include <sys/user.h>
+ ]]
+)
AC_CHECK_MEMBERS([struct kinfo_proc.p_pid, struct kinfo_proc.p_vm_rssize],
- [
- AC_DEFINE(HAVE_STRUCT_KINFO_PROC_OPENBSD, 1,
- [Define if struct kinfo_proc exists in the OpenBSD variant.])
- have_struct_kinfo_proc_openbsd="yes"
- ],
- [
- have_struct_kinfo_proc_openbsd="no"
- ],
- [
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <kvm.h>
- ])
-
+ [
+ AC_DEFINE([HAVE_STRUCT_KINFO_PROC_OPENBSD], [1], [Define if struct kinfo_proc exists in the OpenBSD variant.])
+ have_struct_kinfo_proc_openbsd="yes"
+ ],
+ [],
+ [[
+ #include <sys/param.h>
+ #include <sys/sysctl.h>
+ #include <kvm.h>
+ ]]
+)
AC_CHECK_MEMBERS([struct kinfo_proc2.p_pid, struct kinfo_proc2.p_uru_maxrss],
- [
- AC_DEFINE(HAVE_STRUCT_KINFO_PROC2_NETBSD, 1,
- [Define if struct kinfo_proc2 exists in the NetBSD variant.])
- have_struct_kinfo_proc2_netbsd="yes"
- ],
- [
- have_struct_kinfo_proc2_netbsd="no"
- ],
- [
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <kvm.h>
- ])
-
-
-
-AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport], [], [],
-[#define _BSD_SOURCE
-#define _DEFAULT_SOURCE
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-# include <netinet/ip.h>
-#endif
-#if HAVE_NETINET_UDP_H
-# include <netinet/udp.h>
-#endif
-])
-AC_CHECK_MEMBERS([struct udphdr.dest, struct udphdr.source], [], [],
-[#define _BSD_SOURCE
-#define _DEFAULT_SOURCE
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#if HAVE_NETINET_IN_SYSTM_H
-# include <netinet/in_systm.h>
-#endif
-#if HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#if HAVE_NETINET_IP_H
-# include <netinet/ip.h>
-#endif
-#if HAVE_NETINET_UDP_H
-# include <netinet/udp.h>
-#endif
-])
+ [
+ AC_DEFINE([HAVE_STRUCT_KINFO_PROC2_NETBSD], [1], [Define if struct kinfo_proc2 exists in the NetBSD variant.])
+ have_struct_kinfo_proc2_netbsd="yes"
+ ],
+ [],
+ [[
+ #include <sys/param.h>
+ #include <sys/sysctl.h>
+ #include <kvm.h>
+ ]]
+)
+
+AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport],
+ [],
+ [],
+ [[
+ #define _BSD_SOURCE
+ #define _DEFAULT_SOURCE
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_NETINET_IN_SYSTM_H
+ # include <netinet/in_systm.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ #if HAVE_NETINET_IP_H
+ # include <netinet/ip.h>
+ #endif
+ #if HAVE_NETINET_UDP_H
+ # include <netinet/udp.h>
+ #endif
+ ]]
+)
+
+AC_CHECK_MEMBERS([struct udphdr.dest, struct udphdr.source],
+ [],
+ [],
+ [[
+ #define _BSD_SOURCE
+ #define _DEFAULT_SOURCE
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_NETINET_IN_SYSTM_H
+ # include <netinet/in_systm.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ #if HAVE_NETINET_IP_H
+ # include <netinet/ip.h>
+ #endif
+ #if HAVE_NETINET_UDP_H
+ # include <netinet/udp.h>
+ #endif
+ ]]
+)
AC_CHECK_MEMBERS([kstat_io_t.nwritten, kstat_io_t.writes, kstat_io_t.nwrites, kstat_io_t.wtime],
- [],
- [],
- [
-#if HAVE_KSTAT_H
-# include <kstat.h>
-#endif
- ])
+ [],
+ [],
+ [[# include <kstat.h>]]
+)
# check for pthread_setname_np
SAVE_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -lpthread"
AC_MSG_CHECKING([for pthread_setname_np])
- have_pthread_setname_np="no"
- AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[
-#define _GNU_SOURCE
-#include <pthread.h>
-]],
-[[
- pthread_setname_np((pthread_t) {0}, "conftest");
-]]
- )], [
- have_pthread_setname_np="yes"
- AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [pthread_setname_np() is available.])
- ])
+have_pthread_setname_np="no"
+AC_LINK_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #define _GNU_SOURCE
+ #include <pthread.h>
+ ]],
+ [[pthread_setname_np((pthread_t) {0}, "conftest");]]
+ )
+ ],
+ [
+ have_pthread_setname_np="yes"
+ AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [pthread_setname_np() is available.])
+ ]
+)
AC_MSG_RESULT([$have_pthread_setname_np])
# check for pthread_set_name_np(3) (FreeBSD)
AC_MSG_CHECKING([for pthread_set_name_np])
- have_pthread_set_name_np="no"
- AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[
-#include <pthread_np.h>
-]],
-[[
- pthread_set_name_np((pthread_t) {0}, "conftest");
-]]
- )], [
- have_pthread_set_name_np="yes"
- AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [pthread_set_name_np() is available.])
- ])
+have_pthread_set_name_np="no"
+AC_LINK_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[#include <pthread_np.h>]],
+ [[pthread_set_name_np((pthread_t) {0}, "conftest");]]
+ )
+ ],
+ [
+ have_pthread_set_name_np="yes"
+ AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [pthread_set_name_np() is available.])
+ ]
+)
AC_MSG_RESULT([$have_pthread_set_name_np])
LDFLAGS="$SAVE_LDFLAGS"
-#
-# Checks for libraries begin here
-#
+AC_CHECK_TYPES([struct ip6_ext],
+ [have_ip6_ext="yes"],
+ [have_ip6_ext="no"],
+ [[
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_NETINET_IN_SYSTM_H
+ # include <netinet/in_systm.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ #if HAVE_NETINET_IP6_H
+ # include <netinet/ip6.h>
+ #endif
+ ]]
+)
-with_libresolv="yes"
-AC_CHECK_LIB(resolv, res_search,
-[
- AC_DEFINE(HAVE_LIBRESOLV, 1, [Define to 1 if you have the 'resolv' library (-lresolv).])
-],
-[with_libresolv="no"])
-AM_CONDITIONAL(BUILD_WITH_LIBRESOLV, test "x$with_libresolv" = "xyes")
+if test "x$have_ip6_ext" = "xno"; then
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -DSOLARIS2=8"
+ AC_CHECK_TYPES([struct ip6_ext],
+ [have_ip6_ext="yes, with -DSOLARIS2=8"],
+ [have_ip6_ext="no"],
+ [[
+ #include <stdint.h>
+ #if HAVE_SYS_TYPES_H
+ # include <sys/types.h>
+ #endif
+ #if HAVE_NETINET_IN_SYSTM_H
+ # include <netinet/in_systm.h>
+ #endif
+ #if HAVE_NETINET_IN_H
+ # include <netinet/in.h>
+ #endif
+ #if HAVE_NETINET_IP6_H
+ # include <netinet/ip6.h>
+ #endif
+ ]]
+ )
+ if test "x$have_ip6_ext" = "xno"; then
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+fi
-dnl Check for HAL (hardware abstraction library)
-with_libhal="no"
-PKG_CHECK_MODULES([HAL], [hal],
- [
- SAVE_LIBS="$LIBS"
- LIBS="$HAL_LIBS $LIBS"
- AC_CHECK_LIB([hal], [libhal_device_property_exists],
- [
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$HAL_CFLAGS $CPPFLAGS"
- AC_CHECK_HEADERS([libhal.h],
- [
- with_libhal="yes"
- BUILD_WITH_LIBHAL_CFLAGS="$HAL_CFLAGS"
- BUILD_WITH_LIBHAL_LIBS="$HAL_LIBS"
- ])
- CPPFLAGS="$SAVE_CPPFLAGS"
- ],
- [ : ]
- )
- LIBS="$SAVE_LIBS"
- ],
- [ : ]
-)
-AC_SUBST(BUILD_WITH_LIBHAL_CFLAGS)
-AC_SUBST(BUILD_WITH_LIBHAL_LIBS)
+# libi2c-dev
+if test "x$ac_system" = "xLinux"; then
+ AC_CHECK_DECL([i2c_smbus_read_i2c_block_data],
+ [with_libi2c="yes"],
+ [with_libi2c="no (symbol i2c_smbus_read_i2c_block_data not found - have you installed libi2c-dev ?)"],
+ [[
+ #include <stdlib.h>
+ #include <linux/i2c-dev.h>
+ ]]
+ )
+else
+ with_libi2c="no (Linux only)"
+fi
+#
+# Checks for libraries begin here
+#
+# Check for libpthread
SAVE_LIBS="$LIBS"
AC_CHECK_LIB([pthread],
[pthread_create],
[],
- [AC_MSG_ERROR([Symbol 'pthread_create' not found in libpthread"])],
+ [AC_MSG_ERROR([Symbol 'pthread_create' not found in libpthread])],
[]
)
PTHREAD_LIBS="$LIBS"
LIBS="$SAVE_LIBS"
+AC_SUBST([PTHREAD_LIBS])
AC_CHECK_HEADERS([pthread.h],
[],
[AC_MSG_ERROR([pthread.h not found])]
)
-AC_SUBST([PTHREAD_LIBS])
m4_divert_once([HELP_WITH], [
-collectd additional packages:])
+Collectd additional packages:])
-if test "x$ac_system" = "xAIX"
-then
- with_perfstat="yes"
- with_procinfo="yes"
+if test "x$ac_system" = "xAIX"; then
+ with_perfstat="yes"
+ with_procinfo="yes"
else
- with_perfstat="no (AIX only)"
- with_procinfo="no (AIX only)"
+ with_perfstat="no (AIX only)"
+ with_procinfo="no (AIX only)"
fi
-if test "x$with_perfstat" = "xyes"
-then
- AC_CHECK_LIB(perfstat, perfstat_reset, [with_perfstat="yes"], [with_perfstat="no (perfstat not found)"], [])
-# AC_CHECK_HEADERS(sys/protosw.h libperfstat.h,, [with_perfstat="no (perfstat not found)"])
+if test "x$with_perfstat" = "xyes"; then
+ AC_CHECK_LIB([perfstat], [perfstat_reset],
+ [with_perfstat="yes"],
+ [with_perfstat="no (perfstat not found)"]
+ )
fi
-if test "x$with_perfstat" = "xyes"
-then
- AC_DEFINE(HAVE_PERFSTAT, 1, [Define to 1 if you have the 'perfstat' library (-lperfstat)])
- # struct members pertaining to donation have been added to libperfstat somewhere between AIX5.3ML5 and AIX5.3ML9
- AC_CHECK_MEMBER([perfstat_partition_type_t.b.donate_enabled], [], [], [[#include <libperfstat.h]])
- if test "x$av_cv_member_perfstat_partition_type_t_b_donate_enabled" = "xyes"
- then
- AC_DEFINE(PERFSTAT_SUPPORTS_DONATION, 1, [Define to 1 if your version of the 'perfstat' library supports donation])
- fi
+
+if test "x$with_perfstat" = "xyes"; then
+ AC_DEFINE([HAVE_PERFSTAT], [1], [Define to 1 if you have the 'perfstat' library (-lperfstat)])
+ # struct members pertaining to donation have been added to libperfstat somewhere between AIX5.3ML5 and AIX5.3ML9
+ AC_CHECK_MEMBER([perfstat_partition_type_t.b.donate_enabled],
+ [],
+ [],
+ [[#include <libperfstat.h]]
+ )
+ if test "x$av_cv_member_perfstat_partition_type_t_b_donate_enabled" = "xyes"; then
+ AC_DEFINE([PERFSTAT_SUPPORTS_DONATION], [1], [Define to 1 if your version of the 'perfstat' library supports donation])
+ fi
fi
-AM_CONDITIONAL(BUILD_WITH_PERFSTAT, test "x$with_perfstat" = "xyes")
+AM_CONDITIONAL([BUILD_WITH_PERFSTAT], [test "x$with_perfstat" = "xyes"])
# Processes plugin under AIX.
-if test "x$with_procinfo" = "xyes"
-then
- AC_CHECK_HEADERS(procinfo.h,, [with_procinfo="no (procinfo.h not found)"])
-fi
-if test "x$with_procinfo" = "xyes"
-then
- AC_DEFINE(HAVE_PROCINFO_H, 1, [Define to 1 if you have the procinfo.h])
+if test "x$with_procinfo" = "xyes"; then
+ AC_CHECK_HEADERS([procinfo.h],
+ [AC_DEFINE([HAVE_PROCINFO_H], [1], [Define to 1 if you have the procinfo.h])],
+ [with_procinfo="no (procinfo.h not found)"]
+ )
fi
-if test "x$ac_system" = "xSolaris"
-then
- with_kstat="yes"
- with_devinfo="yes"
+if test "x$ac_system" = "xSolaris"; then
+ with_kstat="yes"
+ with_devinfo="yes"
else
- with_kstat="no (Solaris only)"
- with_devinfo="no (Solaris only)"
+ with_kstat="no (Solaris only)"
+ with_devinfo="no (Solaris only)"
fi
-if test "x$with_kstat" = "xyes"
-then
- AC_CHECK_LIB(kstat, kstat_open, [with_kstat="yes"], [with_kstat="no (libkstat not found)"], [])
-fi
-if test "x$with_kstat" = "xyes"
-then
- AC_CHECK_LIB(devinfo, di_init, [with_devinfo="yes"], [with_devinfo="no (not found)"], [])
- AC_CHECK_HEADERS(kstat.h,, [with_kstat="no (kstat.h not found)"])
+if test "x$with_kstat" = "xyes"; then
+ AC_CHECK_LIB([kstat], [kstat_open],
+ [with_kstat="yes"],
+ [with_kstat="no (libkstat not found)"]
+ )
fi
-if test "x$with_kstat" = "xyes"
-then
- AC_DEFINE(HAVE_LIBKSTAT, 1,
- [Define to 1 if you have the 'kstat' library (-lkstat)])
+
+if test "x$with_kstat" = "xyes"; then
+ AC_CHECK_LIB([devinfo], [di_init],
+ [with_devinfo="yes"],
+ [with_devinfo="no (not found)"]
+ )
+ AC_CHECK_HEADERS([kstat.h],
+ [AC_DEFINE(HAVE_LIBKSTAT, [1], [Define to 1 if you have the 'kstat' library (-lkstat)])],
+ [with_kstat="no (kstat.h not found)"]
+ )
fi
-AM_CONDITIONAL(BUILD_WITH_LIBKSTAT, test "x$with_kstat" = "xyes")
-AM_CONDITIONAL(BUILD_WITH_LIBDEVINFO, test "x$with_devinfo" = "xyes")
-with_libiokit="no"
-if test "x$ac_system" = "xDarwin"
-then
- with_libiokit="yes"
+AM_CONDITIONAL([BUILD_WITH_LIBDEVINFO], [test "x$with_devinfo" = "xyes"])
+AM_CONDITIONAL([BUILD_WITH_LIBKSTAT], [test "x$with_kstat" = "xyes"])
+
+if test "x$ac_system" = "xDarwin"; then
+ with_libiokit="yes"
else
- with_libiokit="no"
+ with_libiokit="no"
fi
-AM_CONDITIONAL(BUILD_WITH_LIBIOKIT, test "x$with_libiokit" = "xyes")
+AM_CONDITIONAL([BUILD_WITH_LIBIOKIT], [test "x$with_libiokit" = "xyes"])
with_libkvm="no"
-AC_CHECK_LIB(kvm, kvm_getprocs, [with_kvm_getprocs="yes"], [with_kvm_getprocs="no"])
-if test "x$with_kvm_getprocs" = "xyes"
-then
- AC_DEFINE(HAVE_LIBKVM_GETPROCS, 1,
- [Define to 1 if you have the 'kvm' library with the 'kvm_getprocs' symbol (-lkvm)])
- with_libkvm="yes"
+AC_CHECK_LIB([kvm], [kvm_getprocs],
+ [with_kvm_getprocs="yes"],
+ [with_kvm_getprocs="no"]
+)
+
+if test "x$with_kvm_getprocs" = "xyes"; then
+ AC_DEFINE([HAVE_LIBKVM_GETPROCS], [1],
+ [Define to 1 if you have the 'kvm' library with the 'kvm_getprocs' symbol (-lkvm)]
+ )
+ with_libkvm="yes"
fi
-AM_CONDITIONAL(BUILD_WITH_LIBKVM_GETPROCS, test "x$with_kvm_getprocs" = "xyes")
-AC_CHECK_LIB(kvm, kvm_getswapinfo, [with_kvm_getswapinfo="yes"], [with_kvm_getswapinfo="no"])
-if test "x$with_kvm_getswapinfo" = "xyes"
-then
- AC_DEFINE(HAVE_LIBKVM_GETSWAPINFO, 1,
- [Define to 1 if you have the 'kvm' library with the 'kvm_getswapinfo' symbol (-lkvm)])
- with_libkvm="yes"
+AM_CONDITIONAL([BUILD_WITH_LIBKVM_GETPROCS], [test "x$with_kvm_getprocs" = "xyes"])
+
+AC_CHECK_LIB([kvm], [kvm_getswapinfo],
+ [with_kvm_getswapinfo="yes"],
+ [with_kvm_getswapinfo="no"]
+)
+
+if test "x$with_kvm_getswapinfo" = "xyes"; then
+ AC_DEFINE([HAVE_LIBKVM_GETSWAPINFO], [1],
+ [Define to 1 if you have the 'kvm' library with the 'kvm_getswapinfo' symbol (-lkvm)]
+ )
+ with_libkvm="yes"
fi
-AM_CONDITIONAL(BUILD_WITH_LIBKVM_GETSWAPINFO, test "x$with_kvm_getswapinfo" = "xyes")
-AC_CHECK_LIB(kvm, kvm_nlist, [with_kvm_nlist="yes"], [with_kvm_nlist="no"])
-if test "x$with_kvm_nlist" = "xyes"
-then
- AC_CHECK_HEADERS(bsd/nlist.h nlist.h)
- AC_DEFINE(HAVE_LIBKVM_NLIST, 1,
- [Define to 1 if you have the 'kvm' library with the 'kvm_nlist' symbol (-lkvm)])
- with_libkvm="yes"
+AM_CONDITIONAL([BUILD_WITH_LIBKVM_GETSWAPINFO], [test "x$with_kvm_getswapinfo" = "xyes"])
+
+AC_CHECK_LIB([kvm], [kvm_nlist],
+ [with_kvm_nlist="yes"],
+ [with_kvm_nlist="no"]
+)
+
+if test "x$with_kvm_nlist" = "xyes"; then
+ AC_CHECK_HEADERS([bsd/nlist.h nlist.h])
+ AC_DEFINE([HAVE_LIBKVM_NLIST], [1],
+ [Define to 1 if you have the 'kvm' library with the 'kvm_nlist' symbol (-lkvm)]
+ )
+ with_libkvm="yes"
fi
-AM_CONDITIONAL(BUILD_WITH_LIBKVM_NLIST, test "x$with_kvm_nlist" = "xyes")
-AC_CHECK_LIB(kvm, kvm_openfiles, [with_kvm_openfiles="yes"], [with_kvm_openfiles="no"])
-if test "x$with_kvm_openfiles" = "xyes"
-then
- AC_DEFINE(HAVE_LIBKVM_NLIST, 1,
- [Define to 1 if you have the 'kvm' library with the 'kvm_openfiles' symbol (-lkvm)])
- with_libkvm="yes"
+AM_CONDITIONAL([BUILD_WITH_LIBKVM_NLIST], [test "x$with_kvm_nlist" = "xyes"])
+
+AC_CHECK_LIB([kvm], [kvm_openfiles],
+ [with_kvm_openfiles="yes"],
+ [with_kvm_openfiles="no"]
+)
+
+if test "x$with_kvm_openfiles" = "xyes"; then
+ AC_DEFINE([HAVE_LIBKVM_NLIST], [1],
+ [Define to 1 if you have the 'kvm' library with the 'kvm_openfiles' symbol (-lkvm)]
+ )
+ with_libkvm="yes"
fi
-AM_CONDITIONAL(BUILD_WITH_LIBKVM_OPENFILES, test "x$with_kvm_openfiles" = "xyes")
# --with-libaquaero5 {{{
-AC_ARG_WITH(libaquaero5, [AS_HELP_STRING([--with-libaquaero5@<:@=PREFIX@:>@], [Path to aquatools-ng source code.])],
-[
- if test "x$withval" = "xyes"
- then
- with_libaquaero5="yes"
- else if test "x$withval" = "xno"
- then
- with_libaquaero5="no"
- else
- with_libaquaero5="yes"
- LIBAQUAERO5_CFLAGS="$LIBAQUAERO5_CFLAGS -I$withval/src"
- LIBAQUAERO5_LDFLAGS="$LIBAQUAERO5_LDFLAGS -L$withval/obj"
- fi; fi
-],
-[with_libaquaero5="yes"])
+AC_ARG_WITH([libaquaero5],
+ [AS_HELP_STRING([--with-libaquaero5@<:@=PREFIX@:>@], [Path to aquatools-ng source code.])],
+ [
+ if test "x$withval" = "xyes"; then
+ with_libaquaero5="yes"
+ else if test "x$withval" = "xno"; then
+ with_libaquaero5="no"
+ else
+ with_libaquaero5="yes"
+ LIBAQUAERO5_CFLAGS="$LIBAQUAERO5_CFLAGS -I$withval/src"
+ LIBAQUAERO5_LDFLAGS="$LIBAQUAERO5_LDFLAGS -L$withval/obj"
+ fi; fi
+ ],
+ [with_libaquaero5="yes"]
+)
SAVE_CPPFLAGS="$CPPFLAGS"
SAVE_LDFLAGS="$LDFLAGS"
-
CPPFLAGS="$CPPFLAGS $LIBAQUAERO5_CFLAGS"
LDFLAGS="$LDFLAGS $LIBAQUAERO5_LDFLAGS"
-if test "x$with_libaquaero5" = "xyes"
-then
- if test "x$LIBAQUAERO5_CFLAGS" != "x"
- then
- AC_MSG_NOTICE([libaquaero5 CPPFLAGS: $LIBAQUAERO5_CFLAGS])
- fi
- AC_CHECK_HEADERS(libaquaero5.h,
- [with_libaquaero5="yes"],
- [with_libaquaero5="no (libaquaero5.h not found)"])
-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_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)"]
+ )
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)"])
-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_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)"]
+ )
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=$?
+
+ if test $curl_config_status -ne 0; then
+ with_libcurl="no ($with_curl_config failed)"
+ else
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_curl_cflags"
- AC_CHECK_HEADERS(curl/curl.h, [], [with_libcurl="no (curl/curl.h not found)"], [])
+ AC_CHECK_HEADERS([curl/curl.h],
+ [with_libcurl="yes"],
+ [with_libcurl="no (curl/curl.h not found)"]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
- fi
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ fi
fi
-if test "x$with_libcurl" = "xyes"
-then
- with_curl_libs=`$with_curl_config --libs 2>/dev/null`
- curl_config_status=$?
-
- if test $curl_config_status -ne 0
- then
- with_libcurl="no ($with_curl_config failed)"
- else
- AC_CHECK_LIB(curl, curl_easy_init,
- [with_libcurl="yes"],
- [with_libcurl="no (symbol 'curl_easy_init' not found)"],
- [$with_curl_libs])
- AC_CHECK_DECL(CURLOPT_USERNAME,
- [have_curlopt_username="yes"],
- [have_curlopt_username="no"],
- [[#include <curl/curl.h>]])
- AC_CHECK_DECL(CURLOPT_TIMEOUT_MS,
- [have_curlopt_timeout="yes"],
- [have_curlopt_timeout="no"],
- [[#include <curl/curl.h>]])
- fi
-fi
-if test "x$with_libcurl" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- SAVE_LDFLAGS="$LDFLAGS"
- CPPFLAGS="$CPPFLAGS $with_curl_cflags"
- LDFLAGS="$LDFLAGS $with_curl_libs"
- AC_CACHE_CHECK([for CURLINFO_APPCONNECT_TIME],
- [c_cv_have_curlinfo_appconnect_time],
- AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[
-#include <curl/curl.h>
-]],
-[[
-int val = CURLINFO_APPCONNECT_TIME;
-return val;
-]]
- )],
- [c_cv_have_curlinfo_appconnect_time="yes"],
- [c_cv_have_curlinfo_appconnect_time="no"]
- )
- )
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
-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$with_libcurl" = "xyes"; then
+ with_curl_libs=`$with_curl_config --libs 2>/dev/null`
+ curl_config_status=$?
+
+ if test $curl_config_status -ne 0; then
+ with_libcurl="no ($with_curl_config failed)"
+ else
+ AC_CHECK_LIB([curl], [curl_easy_init],
+ [with_libcurl="yes"],
+ [with_libcurl="no (symbol 'curl_easy_init' not found)"],
+ [$with_curl_libs]
+ )
+
+ AC_CHECK_DECL([CURLOPT_USERNAME],
+ [have_curlopt_username="yes"],
+ [have_curlopt_username="no"],
+ [[#include <curl/curl.h>]]
+ )
+
+ AC_CHECK_DECL(CURLOPT_TIMEOUT_MS,
+ [have_curlopt_timeout="yes"],
+ [have_curlopt_timeout="no"],
+ [[#include <curl/curl.h>]]
+ )
+ fi
fi
-if test "x$with_libcurl" = "xyes"
-then
- 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
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_curl_cflags"
+ LDFLAGS="$LDFLAGS $with_curl_libs"
+ AC_CACHE_CHECK([for CURLINFO_APPCONNECT_TIME],
+ [c_cv_have_curlinfo_appconnect_time],
+ [
+ AC_LINK_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[#include <curl/curl.h>]],
+ [[
+ int val = CURLINFO_APPCONNECT_TIME;
+ return val;
+ ]]
+ )
+ ],
+ [c_cv_have_curlinfo_appconnect_time="yes"],
+ [c_cv_have_curlinfo_appconnect_time="no"]
+ )
+ ]
+ )
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+
+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$have_curlopt_username" = "xyes"
- then
- AC_DEFINE(HAVE_CURLOPT_USERNAME, 1, [Define if libcurl supports CURLOPT_USERNAME option.])
- fi
+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_timeout" = "xyes"
- then
- AC_DEFINE(HAVE_CURLOPT_TIMEOUT_MS, 1, [Define if libcurl supports CURLOPT_TIMEOUT_MS 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
fi
+
+AC_SUBST(BUILD_WITH_LIBCURL_CFLAGS)
+AC_SUBST(BUILD_WITH_LIBCURL_LIBS)
# }}}
# --with-libdbi {{{
-with_libdbi_cppflags=""
-with_libdbi_ldflags=""
-AC_ARG_WITH(libdbi, [AS_HELP_STRING([--with-libdbi@<:@=PREFIX@:>@], [Path to libdbi.])],
-[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
- then
- with_libdbi_cppflags="-I$withval/include"
- with_libdbi_ldflags="-L$withval/lib"
- with_libdbi="yes"
- else
- with_libdbi="$withval"
- fi
-],
-[
- with_libdbi="yes"
-])
-if test "x$with_libdbi" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libdbi_cppflags"
+AC_ARG_WITH([libdbi],
+ [AS_HELP_STRING([--with-libdbi@<:@=PREFIX@:>@], [Path to libdbi.])],
+ [
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+ with_libdbi_cppflags="-I$withval/include"
+ with_libdbi_ldflags="-L$withval/lib"
+ with_libdbi="yes"
+ else
+ with_libdbi="$withval"
+ fi
+ ],
+ [with_libdbi="yes"]
+)
+
+if test "x$with_libdbi" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libdbi_cppflags"
+
+ AC_CHECK_HEADERS([dbi/dbi.h],
+ [with_libdbi="yes"],
+ [with_libdbi="no (dbi/dbi.h not found)"]
+ )
- AC_CHECK_HEADERS(dbi/dbi.h, [with_libdbi="yes"], [with_libdbi="no (dbi/dbi.h not found)"])
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+
+if test "x$with_libdbi" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_libdbi_ldflags"
- CPPFLAGS="$SAVE_CPPFLAGS"
+ 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
- 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)"])
+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-libdpdk {{{
+AC_ARG_VAR([LIBDPDK_CPPFLAGS], [Preprocessor flags for libdpdk])
+AC_ARG_VAR([LIBDPDK_CFLAGS], [Compiler flags for libdpdk])
+AC_ARG_VAR([LIBDPDK_LDFLAGS], [Linker flags for libdpdk])
+AC_ARG_VAR([LIBDPDK_LIBS], [Libraries to link for libdpdk])
+
+AC_ARG_WITH([libdpdk],
+ [AS_HELP_STRING([--without-libdpdk], [Disable libdpdk.])],
+ [with_libdpdk="$withval"],
+ [with_libdpdk="yes"]
+)
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
+if test "x$with_libdpdk" != "xno"; then
+ PKG_CHECK_MODULES([DPDK], [libdpdk], [],
+ [AC_MSG_NOTICE([no DPDK pkg-config, using defaults])])
+ if test "x$LIBDPDK_CPPFLAGS" = "x"; then
+ LIBDPDK_CPPFLAGS="-I/usr/include/dpdk"
+ fi
+ if test "x$LIBDPDK_CFLAGS" = "x"; then
+ LIBDPDK_CFLAGS="$DPDK_CFLAGS"
+ LIBDPDK_CPPFLAGS="$LIBDPDK_CPPFLAGS $DPDK_CFLAGS"
+ fi
+ if test "x$LIBDPDK_LIBS" = "x"; then
+ if test "x$DPDK_LIBS" != "x"; then
+ LIBDPDK_LIBS="$DPDK_LIBS"
+ else
+ LIBDPDK_LIBS="-ldpdk"
+ fi
+ fi
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$LIBDPDK_CPPFLAGS $CPPFLAGS"
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$LIBDPDK_CFLAGS $CFLAGS"
+ AC_CHECK_HEADERS([rte_config.h],
+ [
+ with_libdpdk="yes"
+ AC_PREPROC_IFELSE(
+ [
+ AC_LANG_SOURCE(
+ [[
+ #include <rte_version.h>
+ #if RTE_VERSION < RTE_VERSION_NUM(16,7,0,0)
+ #error "required DPDK >= 16.07"
+ #endif
+ ]]
+ )
+ ],
+ [dpdk_keepalive="yes"],
+ [dpdk_keepalive="no (DPDK version < 16.07)"]
+ )
+ ],
+ [with_libdpdk="no (rte_config.h not found)"]
+ )
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ CFLAGS="$SAVE_CFLAGS"
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")
+
+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-libesmtp {{{
-AC_ARG_WITH(libesmtp, [AS_HELP_STRING([--with-libesmtp@<:@=PREFIX@:>@], [Path to libesmtp.])],
-[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
- then
- LDFLAGS="$LDFLAGS -L$withval/lib"
- CPPFLAGS="$CPPFLAGS -I$withval/include -D_THREAD_SAFE"
- with_libesmtp="yes"
- else
- with_libesmtp="$withval"
- fi
-],
-[
- with_libesmtp="yes"
-])
-if test "x$with_libesmtp" = "xyes"
-then
- AC_CHECK_LIB(esmtp, smtp_create_session,
- [
- AC_DEFINE(HAVE_LIBESMTP, 1, [Define to 1 if you have the esmtp library (-lesmtp).])
- ], [with_libesmtp="no (libesmtp not found)"])
-fi
-if test "x$with_libesmtp" = "xyes"
-then
- AC_CHECK_HEADERS(libesmtp.h,
- [
- AC_DEFINE(HAVE_LIBESMTP_H, 1, [Define to 1 if you have the <libesmtp.h> header file.])
- ], [with_libesmtp="no (libesmtp.h not found)"])
+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"]
+)
+
+if test "x$with_libesmtp" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libesmtp_cppflags"
+
+ 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
- collect_libesmtp=1
-else
- collect_libesmtp=0
+
+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
-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")
+
+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"
-])
+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
+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"
CPPFLAGS="$CPPFLAGS $GANGLIA_CPPFLAGS"
LDFLAGS="$LDFLAGS $GANGLIA_LDFLAGS"
-if test "x$with_libganglia" = "xyes"
-then
- AC_CHECK_HEADERS(gm_protocol.h,
- [
- AC_DEFINE(HAVE_GM_PROTOCOL_H, 1,
- [Define to 1 if you have the <gm_protocol.h> header file.])
- ], [with_libganglia="no (gm_protocol.h not found)"])
+if test "x$with_libganglia" = "xyes"; then
+ AC_CHECK_HEADERS([gm_protocol.h],
+ [with_libganglia="yes"],
+ [with_libganglia="no (gm_protocol.h not found)"]
+ )
fi
-if test "x$with_libganglia" = "xyes"
-then
- AC_CHECK_LIB(ganglia, xdr_Ganglia_value_msg,
- [
- AC_DEFINE(HAVE_LIBGANGLIA, 1,
- [Define to 1 if you have the ganglia library (-lganglia).])
- ], [with_libganglia="no (symbol xdr_Ganglia_value_msg not found)"])
+if test "x$with_libganglia" = "xyes"; then
+ AC_CHECK_LIB([ganglia], [xdr_Ganglia_value_msg],
+ [with_libganglia="yes"],
+ [with_libganglia="no (symbol xdr_Ganglia_value_msg not found)"]
+ )
fi
CPPFLAGS="$SAVE_CPPFLAGS"
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"
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"]
+)
- AC_CHECK_HEADERS(gps.h, [with_libgps="yes"], [with_libgps="no (gps.h not found)"])
+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)"]
+ )
- 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"
+
+ AC_CHECK_LIB([gps], [gps_open],
+ [with_libgps="yes"],
+ [with_libgps="no (symbol gps_open not found)"]
+ )
+
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
- CFLAGS="$SAVE_CFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
+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
-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")
+
+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])
fi
fi
-if test "x$with_libgrpcpp" = "xyes"
-then
+if test "x$with_libgrpcpp" = "xyes"; then
AC_LANG_PUSH(C++)
SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS $CPPFLAGS"
- AC_CHECK_HEADERS([grpc++/grpc++.h], [],
+ AC_CHECK_HEADERS([grpc++/grpc++.h],
+ [with_libgrpcpp="yes"],
[with_libgrpcpp="no (<grpc++/grpc++.h> not found)"]
)
CPPFLAGS="$SAVE_CPPFLAGS"
AC_LANG_POP(C++)
fi
-if test "x$with_libgrpcpp" = "xyes"
-then
+
+if test "x$with_libgrpcpp" = "xyes"; then
AC_LANG_PUSH(C++)
SAVE_CPPFLAGS="$CPPFLAGS"
SAVE_LDFLAGS="$LDFLAGS"
SAVE_LIBS="$LIBS"
CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS $CPPFLAGS"
LDFLAGS="$with_libgrpcpp_ldflags"
- if test "x$GRPCPP_LIBS" = "x"
- then
+ if test "x$GRPCPP_LIBS" = "x"; then
LIBS="-lgrpc++"
else
LIBS="$GRPCPP_LIBS"
fi
AC_LINK_IFELSE(
- [AC_LANG_PROGRAM(
- [[#include <grpc++/grpc++.h>]],
- [[grpc::ServerBuilder sb;]]
- )],
+ [
+ AC_LANG_PROGRAM(
+ [[#include <grpc++/grpc++.h>]],
+ [[grpc::ServerBuilder sb;]]
+ )
+ ],
[
with_libgrpcpp="yes"
- if test "x$GRPCPP_LIBS" = "x"
- then
+ if test "x$GRPCPP_LIBS" = "x"; then
GRPCPP_LIBS="-lgrpc++"
fi
],
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"
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 {{{
-AC_ARG_VAR([LIBDPDK_CPPFLAGS], [Preprocessor flags for libdpdk])
-AC_ARG_VAR([LIBDPDK_CFLAGS], [Compiler flags for libdpdk])
-AC_ARG_VAR([LIBDPDK_LDFLAGS], [Linker flags for libdpdk])
-AC_ARG_VAR([LIBDPDK_LIBS], [Libraries to link for libdpdk])
+# --with-java {{{
+with_java_home="$JAVA_HOME"
+if test "x$with_java_home" = "x"; then
+ with_java_home="/usr/lib/jvm"
+fi
-AC_ARG_WITH([libdpdk],
- [AS_HELP_STRING([--without-libdpdk], [Disable libdpdk.])],
- [with_libdpdk="$withval"],
- [with_libdpdk="yes"]
+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_libdpdk" != "xno"; then
- PKG_CHECK_MODULES([DPDK], [libdpdk], [],
- [AC_MSG_NOTICE([no DPDK pkg-config, using defaults])])
- if test "x$LIBDPDK_CPPFLAGS" = "x"; then
- LIBDPDK_CPPFLAGS="-I/usr/include/dpdk"
- fi
- if test "x$LIBDPDK_CFLAGS" = "x"; then
- LIBDPDK_CFLAGS="$DPDK_CFLAGS"
- LIBDPDK_CPPFLAGS="$LIBDPDK_CPPFLAGS $DPDK_CFLAGS"
- fi
- if test "x$LIBDPDK_LIBS" = "x"; then
- if test "x$DPDK_LIBS" != "x"; then
- LIBDPDK_LIBS="$DPDK_LIBS"
+AX_COMPARE_VERSION([$am__api_version],[lt],[1.12],
+ [JAVA_TIMESTAMP_FILE="classdist_noinst.stamp"],
+ [JAVA_TIMESTAMP_FILE="classnoinst.stamp"])
+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
- LIBDPDK_LIBS="-ldpdk"
+ AC_MSG_RESULT([not found])
fi
- fi
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$LIBDPDK_CPPFLAGS $CPPFLAGS"
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$LIBDPDK_CFLAGS $CFLAGS"
- AC_CHECK_HEADERS([rte_config.h],
- [
- with_libdpdk="yes"
- AC_PREPROC_IFELSE(
- [
- AC_LANG_SOURCE(
- [[
- #include <rte_version.h>
- #if RTE_VERSION < RTE_VERSION_NUM(16,7,0,0)
- #error "required DPDK >= 16.07"
- #endif
- ]]
- )
- ],
- [dpdk_keepalive="yes"],
- [dpdk_keepalive="no (DPDK version < 16.07)"]
- )
- ],
- [with_libdpdk="no (rte_config.h not found)"]
- )
- CPPFLAGS="$SAVE_CPPFLAGS"
- CFLAGS="$SAVE_CFLAGS"
-fi
+ 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$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
-# }}}
-
-# --with-java {{{
-with_java_home="$JAVA_HOME"
-if test "x$with_java_home" = "x"
-then
- with_java_home="/usr/lib/jvm"
+if test "x$JAVA_CPPFLAGS" != "x"; then
+ AC_MSG_NOTICE([Building with JAVA_CPPFLAGS set to: $JAVA_CPPFLAGS])
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
-fi
-
-if test "x$JAVA_CPPFLAGS" != "x"
-then
- AC_MSG_NOTICE([Building with JAVA_CPPFLAGS set to: $JAVA_CPPFLAGS])
+if test "x$JAVA_CFLAGS" != "x"; then
+ AC_MSG_NOTICE([Building with JAVA_CFLAGS set to: $JAVA_CFLAGS])
fi
-if test "x$JAVA_CFLAGS" != "x"
-then
- AC_MSG_NOTICE([Building with JAVA_CFLAGS set to: $JAVA_CFLAGS])
+if test "x$JAVA_LDFLAGS" != "x"; then
+ AC_MSG_NOTICE([Building with JAVA_LDFLAGS set to: $JAVA_LDFLAGS])
fi
-if test "x$JAVA_LDFLAGS" != "x"
-then
- AC_MSG_NOTICE([Building with JAVA_LDFLAGS set to: $JAVA_LDFLAGS])
+if test "x$JAVA_LIBS" != "x"; then
+ AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS])
fi
-if test "x$JAVA_LIBS" != "x"
-then
- AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS])
+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")
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")
-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")
-fi
-if test "x$JAR" = "x"
-then
- with_java="no (jar not found)"
+
+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)"
fi
SAVE_CPPFLAGS="$CPPFLAGS"
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"
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])
+AC_SUBST([JAVA_TIMESTAMP_FILE])
+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"
CPPFLAGS="$CPPFLAGS $LIBLDAP_CPPFLAGS"
LDFLAGS="$LDFLAGS $LIBLDAP_LDFLAGS"
-if test "x$with_libldap" = "xyes"
-then
- if test "x$LIBLDAP_CPPFLAGS" != "x"
- then
- AC_MSG_NOTICE([libldap CPPFLAGS: $LIBLDAP_CPPFLAGS])
- fi
- AC_CHECK_HEADERS(ldap.h,
- [with_libldap="yes"],
- [with_libldap="no ('ldap.h' not found)"])
+if test "x$with_libldap" = "xyes"; then
+ if test "x$LIBLDAP_CPPFLAGS" != "x"; then
+ AC_MSG_NOTICE([libldap CPPFLAGS: $LIBLDAP_CPPFLAGS])
+ fi
+
+ AC_CHECK_HEADERS([ldap.h],
+ [with_libldap="yes"],
+ [with_libldap="no ('ldap.h' not found)"]
+ )
fi
-if test "x$with_libldap" = "xyes"
-then
- if test "x$LIBLDAP_LDFLAGS" != "x"
- then
- AC_MSG_NOTICE([libldap LDFLAGS: $LIBLDAP_LDFLAGS])
- fi
- AC_CHECK_LIB(ldap, ldap_initialize,
- [with_libldap="yes"],
- [with_libldap="no (symbol 'ldap_initialize' not found)"])
+if test "x$with_libldap" = "xyes"; then
+ if test "x$LIBLDAP_LDFLAGS" != "x"; then
+ AC_MSG_NOTICE([libldap LDFLAGS: $LIBLDAP_LDFLAGS])
+ fi
+
+ AC_CHECK_LIB([ldap], [ldap_initialize],
+ [with_libldap="yes"],
+ [with_libldap="no (symbol 'ldap_initialize' not found)"]
+ )
fi
CPPFLAGS="$SAVE_CPPFLAGS"
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 {{{
PKG_CHECK_MODULES([LUA], [lua-5.3],
[with_liblua="yes"],
[
- PKG_CHECK_MODULES([LUA], [lua5.3],
+ PKG_CHECK_MODULES([LUA], [lua5.3],
[with_liblua="yes"],
[
PKG_CHECK_MODULES([LUA], [lua-5.2],
# }}}
# --with-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"]
+)
+
+if test "x$with_libmemcached" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags"
- AC_CHECK_HEADERS(libmemcached/memcached.h, [with_libmemcached="yes"], [with_libmemcached="no (libmemcached/memcached.h not found)"])
+ AC_CHECK_HEADERS([libmemcached/memcached.h],
+ [with_libmemcached="yes"],
+ [with_libmemcached="no (libmemcached/memcached.h not found)"]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
+ 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"
+
+ AC_CHECK_LIB([memcached], [memcached_create],
+ [with_libmemcached="yes"],
+ [with_libmemcached="no (Symbol 'memcached_create' not found)"]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
+ 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 {{{
with_libmicrohttpd_ldflags=""
AC_ARG_WITH([libmicrohttpd], [AS_HELP_STRING([--with-libmicrohttpd@<:@=PREFIX@:>@], [Path to libmicrohttpd.])],
[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
- then
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
with_libmicrohttpd_cppflags="-I$withval/include"
with_libmicrohttpd_ldflags="-L$withval/lib"
with_libmicrohttpd="yes"
fi
- if test "x$withval" = "xno"
- then
+ if test "x$withval" = "xno"; then
with_libmicrohttpd="no (disabled on command line)"
fi
],
[withval="yes"]
)
-if test "x$withval" = "xyes"
-then
-PKG_CHECK_MODULES([MICROHTTPD], [libmicrohttpd],
- [with_libmicrohttpd="yes"],
- [with_libmicrohttpd="no (pkg-config could not find libmicrohttpd)"]
-)
+if test "x$withval" = "xyes"; then
+ PKG_CHECK_MODULES([MICROHTTPD], [libmicrohttpd],
+ [with_libmicrohttpd="yes"],
+ [with_libmicrohttpd="no (pkg-config could not find libmicrohttpd)"]
+ )
fi
-if test "x$MICROHTTPD_LIBS" = "x"
-then
+if test "x$MICROHTTPD_LIBS" = "x"; then
MICROHTTPD_LIBS="-lmicrohttpd"
fi
LDFLAGS="$with_libmicrohttpd_ldflags $LDFLAGS"
LIBS="$LIBS $MICROHTTPD_LIBS"
-if test "x$with_libmicrohttpd" = "xyes"
-then
+if test "x$with_libmicrohttpd" = "xyes"; then
AC_CHECK_HEADERS([microhttpd.h],
- [with_libmicrohttpd="yes"],
- [with_libmicrohttpd="no (<microhttpd.h> not found)"])
+ [with_libmicrohttpd="yes"],
+ [with_libmicrohttpd="no (<microhttpd.h> not found)"]
+ )
fi
-if test "x$with_libmicrohttpd" = "xyes"
-then
+if test "x$with_libmicrohttpd" = "xyes"; then
AC_CHECK_LIB([microhttpd], [MHD_start_daemon],
- [with_libmicrohttpd="yes"],
- [with_libmicrohttpd="no (libmicrohttpd not found)"])
+ [with_libmicrohttpd="yes"],
+ [with_libmicrohttpd="no (libmicrohttpd not found)"]
+ )
fi
CPPFLAGS="$SAVE_CPPFLAGS"
# }}}
# --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
-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
+ 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
-# 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" = "xuse_pkgconfig"; then
+ with_libmodbus_cflags="`$PKG_CONFIG --cflags 'libmodbus'`"
+ if test $? -ne 0; then
+ with_libmodbus="no ($PKG_CONFIG failed)"
+ fi
- AC_CHECK_HEADERS(modbus.h, [], [with_libmodbus="no (modbus.h not found)"])
+ with_libmodbus_libs="`$PKG_CONFIG --libs 'libmodbus'`"
+ if test $? -ne 0; then
+ with_libmodbus="no ($PKG_CONFIG failed)"
+ fi
+fi
- CPPFLAGS="$SAVE_CPPFLAGS"
+if test "x$with_libmodbus" = "xuse_pkgconfig"; then
+ with_libmodbus="yes"
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_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libmodbus_cflags"
- AC_CHECK_LIB(modbus, modbus_connect,
- [with_libmodbus="yes"],
- [with_libmodbus="no (symbol modbus_connect not found)"])
+ AC_CHECK_HEADERS([modbus.h],
+ [with_libmodbus="yes"],
+ [with_libmodbus="no (modbus.h not found)"]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
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
+ 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)"]
+ )
+
+ 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"
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"]
+)
+
+if test "x$with_libmosquitto" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags"
- AC_CHECK_HEADERS(mosquitto.h, [with_libmosquitto="yes"], [with_libmosquitto="no (mosquitto.h not found)"])
+ AC_CHECK_HEADERS([mosquitto.h],
+ [with_libmosquitto="yes"],
+ [with_libmosquitto="no (mosquitto.h not found)"]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
-if test "x$with_libmosquitto" = "xyes"
-then
- SAVE_LDFLAGS="$LDFLAGS"
- SAVE_CPPFLAGS="$CPPFLAGS"
- LDFLAGS="$LDFLAGS $with_libmosquitto_ldflags"
- CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags"
- AC_CHECK_LIB(mosquitto, mosquitto_connect, [with_libmosquitto="yes"], [with_libmosquitto="no (libmosquitto not found)"])
+if test "x$with_libmosquitto" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_libmosquitto_ldflags"
+
+ AC_CHECK_LIB([mosquitto], [mosquitto_connect],
+ [with_libmosquitto="yes"],
+ [with_libmosquitto="no (libmosquitto not found)"]
+ )
- LDFLAGS="$SAVE_LDFLAGS"
- CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
fi
-if test "x$with_libmosquitto" = "xyes"
-then
- BUILD_WITH_LIBMOSQUITTO_CPPFLAGS="$with_libmosquitto_cppflags"
- BUILD_WITH_LIBMOSQUITTO_LDFLAGS="$with_libmosquitto_ldflags"
- BUILD_WITH_LIBMOSQUITTO_LIBS="-lmosquitto"
- AC_SUBST(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS)
- AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LDFLAGS)
- AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LIBS)
+
+if test "x$with_libmosquitto" = "xyes"; then
+ BUILD_WITH_LIBMOSQUITTO_CPPFLAGS="$with_libmosquitto_cppflags"
+ BUILD_WITH_LIBMOSQUITTO_LDFLAGS="$with_libmosquitto_ldflags"
+ BUILD_WITH_LIBMOSQUITTO_LIBS="-lmosquitto"
fi
+
+AC_SUBST([BUILD_WITH_LIBMOSQUITTO_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBMOSQUITTO_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBMOSQUITTO_LIBS])
# }}}
# --with-libmysql {{{
with_mysql_config="mysql_config"
-with_mysql_cflags=""
-with_mysql_libs=""
-AC_ARG_WITH(libmysql, [AS_HELP_STRING([--with-libmysql@<:@=PREFIX@:>@], [Path to libmysql.])],
-[
- if test "x$withval" = "xno"
- then
- with_libmysql="no"
- else if test "x$withval" = "xyes"
- then
- with_libmysql="yes"
- else
- if test -f "$withval" && test -x "$withval";
- then
- with_mysql_config="$withval"
- else if test -x "$withval/bin/mysql_config"
- then
- with_mysql_config="$withval/bin/mysql_config"
- fi; fi
- with_libmysql="yes"
- fi; fi
-],
-[
- with_libmysql="yes"
-])
-if test "x$with_libmysql" = "xyes"
-then
- with_mysql_cflags=`$with_mysql_config --include 2>/dev/null`
- mysql_config_status=$?
-
- if test $mysql_config_status -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"])
-
- 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$have_mysql_mysql_h" = "xnono"
- then
- with_libmysql="no (mysql.h not found)"
- 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
-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)
+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`
+ if test $? -ne 0; then
+ with_libmysql="no ($with_mysql_config failed)"
+ else
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_mysql_cflags"
+
+ AC_CHECK_HEADERS([mysql.h],
+ [have_mysql_h="yes"],
+ [have_mysql_h="no"]
+ )
+
+ 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" != "xyes" && test "x$have_mysql_mysql_h" != "xyes"; then
+ with_libmysql="no (mysql.h not found)"
+ fi
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ fi
+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"
fi
-AM_CONDITIONAL(BUILD_WITH_LIBMYSQL, test "x$with_libmysql" = "xyes")
+
+AC_SUBST([BUILD_WITH_LIBMYSQL_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBMYSQL_LIBS])
# }}}
# --with-libmnl {{{
-with_libmnl_cflags=""
-with_libmnl_libs=""
-AC_ARG_WITH(libmnl, [AS_HELP_STRING([--with-libmnl@<:@=PREFIX@:>@], [Path to libmnl.])],
-[
- echo "libmnl: withval = $withval"
- if test "x$withval" = "xyes"
- then
- with_libmnl="yes"
- else if test "x$withval" = "xno"
- then
- with_libmnl="no"
- else
- if test -d "$withval/include"
- then
- with_libmnl_cflags="-I$withval/include"
- with_libmnl_libs="-L$withval/lib -lmnl"
- with_libmnl="yes"
- else
- AC_MSG_ERROR("no such directory: $withval/include")
- fi
- fi; fi
-],
-[
- if test "x$ac_system" = "xLinux"
- then
- with_libmnl="yes"
- else
- with_libmnl="no (Linux only library)"
- fi
-])
-if test "x$with_libmnl" = "xyes"
-then
- if $PKG_CONFIG --exists libmnl 2>/dev/null; then
- with_libmnl_cflags="$with_libmnl_ldflags `$PKG_CONFIG --cflags libmnl`"
- with_libmnl_libs="$with_libmnl_libs `$PKG_CONFIG --libs libmnl`"
- fi
-
- AC_CHECK_HEADERS(libmnl.h libmnl/libmnl.h,
- [
- with_libmnl="yes"
- break
- ], [],
-[#include <stdio.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>])
- AC_CHECK_HEADERS(linux/gen_stats.h linux/pkt_sched.h, [], [],
-[#include <stdio.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <sys/socket.h>])
-
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[
-#include <stdio.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-]],
-[[
-int retval = TCA_STATS2;
-return (retval);
-]]
- )],
- [AC_DEFINE([HAVE_TCA_STATS2], [1], [True if the enum-member TCA_STATS2 exists])])
-
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
-[[
-#include <stdio.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-]],
-[[
-int retval = TCA_STATS;
-return (retval);
-]]
- )],
- [AC_DEFINE([HAVE_TCA_STATS], 1, [True if the enum-member TCA_STATS exists])])
-fi
-if test "x$with_libmnl" = "xyes"
-then
- AC_CHECK_MEMBERS([struct rtnl_link_stats64.tx_window_errors],
- [AC_DEFINE(HAVE_RTNL_LINK_STATS64, 1, [Define if struct rtnl_link_stats64 exists and is usable.])],
- [],
- [
- #include <linux/if_link.h>
- ])
-fi
-if test "x$with_libmnl" = "xyes"
-then
- AC_CHECK_LIB(mnl, mnl_nlmsg_get_payload,
- [with_libmnl="yes"],
- [with_libmnl="no (symbol 'mnl_nlmsg_get_payload' not found)"],
- [$with_libmnl_libs])
+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
+ ]
+)
+
+if test "x$with_libmnl" = "xyes"; then
+ if $PKG_CONFIG --exists libmnl 2>/dev/null; then
+ with_libmnl_cflags="$with_libmnl_ldflags `$PKG_CONFIG --cflags libmnl`"
+ with_libmnl_libs="$with_libmnl_libs `$PKG_CONFIG --libs libmnl`"
+ fi
+
+ AC_CHECK_HEADERS([libmnl.h libmnl/libmnl.h],
+ [
+ with_libmnl="yes"
+ break
+ ],
+ [],
+ [[
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <asm/types.h>
+ #include <sys/socket.h>
+ #include <linux/netlink.h>
+ #include <linux/rtnetlink.h>]]
+ )
+
+ AC_CHECK_HEADERS([linux/gen_stats.h linux/pkt_sched.h],
+ [],
+ [],
+ [[
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <asm/types.h>
+ #include <sys/socket.h>
+ ]]
+ )
+
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <asm/types.h>
+ #include <sys/socket.h>
+ #include <linux/netlink.h>
+ #include <linux/rtnetlink.h>
+ ]],
+ [[
+ int retval = TCA_STATS2;
+ return retval;
+ ]]
+ )
+ ],
+ [AC_DEFINE([HAVE_TCA_STATS2], [1], [True if the enum-member TCA_STATS2 exists])]
+ )
+
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <asm/types.h>
+ #include <sys/socket.h>
+ #include <linux/netlink.h>
+ #include <linux/rtnetlink.h>
+ ]],
+ [[
+ int retval = TCA_STATS;
+ return retval;
+ ]]
+ )
+ ],
+ [AC_DEFINE([HAVE_TCA_STATS], 1, [True if the enum-member TCA_STATS exists])]
+ )
+
+ AC_CHECK_MEMBERS([struct rtnl_link_stats64.tx_window_errors],
+ [AC_DEFINE(HAVE_RTNL_LINK_STATS64, 1, [Define if struct rtnl_link_stats64 exists and is usable.])],
+ [],
+ [[#include <linux/if_link.h>]]
+ )
+
+ AC_CHECK_LIB([mnl], [mnl_nlmsg_get_payload],
+ [with_libmnl="yes"],
+ [with_libmnl="no (symbol 'mnl_nlmsg_get_payload' not found)"],
+ [$with_libmnl_libs]
+ )
fi
-if test "x$with_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_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]
+ )
- 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"
+ 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 {{{
-AC_ARG_WITH(libnetsnmp, [AS_HELP_STRING([--with-libnetsnmp@<:@=PREFIX@:>@], [Path to the Net-SNMPD library.])],
-[
- if test "x$withval" = "xno"
- then
- with_libnetsnmp="no"
- else if test "x$withval" = "xyes"
- then
- with_libnetsnmp="yes"
- else
- with_libnetsnmp_cppflags="-I$withval/include"
- with_libnetsnmp_ldflags="-I$withval/lib"
- with_libnetsnmp="yes"
- fi; fi
-],
-[with_libnetsnmp="yes"])
-if test "x$with_libnetsnmp" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libnetsnmp_cppflags"
+AC_ARG_WITH([libnetsnmp],
+ [AS_HELP_STRING([--with-libnetsnmp@<:@=PREFIX@:>@], [Path to libnetsnmp.])],
+ [
+ if test "x$withval" = "xno"; then
+ with_libnetsnmp="no"
+ else if test "x$withval" = "xyes"; then
+ with_libnetsnmp="yes"
+ else
+ with_libnetsnmp_cppflags="-I$withval/include"
+ with_libnetsnmp_ldflags="-I$withval/lib"
+ with_libnetsnmp="yes"
+ fi; fi
+ ],
+ [with_libnetsnmp="yes"]
+)
+
+if test "x$with_libnetsnmp" = "xyes"; 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)"]
+ )
+
+ AC_CHECK_HEADERS([net-snmp/net-snmp-includes.h],
+ [with_libnetsnmp="yes"],
+ [with_libnetsnmp="no (net-snmp/net-snmp-includes.h not found)"],
+ [[
+ #if HAVE_NET_SNMP_NET_SNMP_CONFIG_H
+ # include <net-snmp/net-snmp-config.h>
+ #endif
+ ]]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
-if test "x$with_libnetsnmp" = "xyes"
-then
- SAVE_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $with_libnetsnmp_ldflags"
- AC_CHECK_LIB(netsnmp, init_snmp,
- [with_libnetsnmp="yes"],
- [with_libnetsnmp="no (libnetsnmp not found)"],
- [$with_snmp_libs])
+if test "x$with_libnetsnmp" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_libnetsnmp_ldflags"
+
+ AC_CHECK_LIB([netsnmp], [init_snmp],
+ [with_libnetsmp="yes"],
+ [with_libnetsnmp="no (libnetsnmp not found)"]
+ )
- LDFLAGS="$SAVE_LDFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
fi
-if test "x$with_libnetsnmp" = "xyes"
-then
- BUILD_WITH_LIBNETSNMP_CPPFLAGS="$with_libnetsnmp_cppflags"
- BUILD_WITH_LIBNETSNMP_LDFLAGS="$with_libnetsnmp_ldflags"
- BUILD_WITH_LIBNETSNMP_LIBS="-lnetsnmp"
+
+if test "x$with_libnetsnmp" = "xyes"; then
+ BUILD_WITH_LIBNETSNMP_CPPFLAGS="$with_libnetsnmp_cppflags"
+ BUILD_WITH_LIBNETSNMP_LDFLAGS="$with_libnetsnmp_ldflags"
+ BUILD_WITH_LIBNETSNMP_LIBS="-lnetsnmp"
fi
-AC_SUBST(BUILD_WITH_LIBNETSNMP_CPPFLAGS)
-AC_SUBST(BUILD_WITH_LIBNETSNMP_LDFLAGS)
-AC_SUBST(BUILD_WITH_LIBNETSNMP_LIBS)
+
+AC_SUBST([BUILD_WITH_LIBNETSNMP_CPPFLAGS])
+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"
-])
+# --with-libnetsmpagent {{{
+AC_ARG_WITH([libnetsnmpagent],
+ [AS_HELP_STRING([--with-libnetsnmpagent@<:@=PREFIX@:>@], [Path to libnetsnmpagent.])],
+ [
+ if test "x$withval" = "xno"; then
+ with_libnetsnmpagent="no"
+ else if test "x$withval" = "xyes"; then
+ with_libnetsnmpagent="yes"
+ else
+ with_libnetsnmpagent_cppflags="-I$withval/include"
+ with_libnetsnmpagent_ldflags="-I$withval/lib"
+ with_libnetsnmpagent="yes"
+ fi; fi
+ ],
+ [with_libnetsnmpagent="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"
-])
+if test "x$with_libnetsnmpagent" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libnetsnmpagent_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)"
+ AC_CHECK_HEADERS([net-snmp/agent/net-snmp-agent-includes.h],
+ [],
+ [with_libnetsnmpagent="no (net-snmp/agent/net-snmp-agent-includes.h not found)"],
+ [[
+ #if HAVE_NET_SNMP_NET_SNMP_CONFIG_H
+ # include <net-snmp/net-snmp-config.h>
+ #endif
+ #if HAVE_NET_SNMP_NET_SNMP_INCLUDES_H
+ # include <net-snmp/net-snmp-includes.h>
+ #endif
+ ]]
+ )
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
+
+if test "x$with_libnetsnmpagent" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_libnetsnmpagent_ldflags"
+
+ # older versions of libnetsnmpagent fail to link
+ # against the helpers library, so do that explicitly
+ AC_CHECK_LIB([netsnmphelpers], [netsnmp_init_helpers],
+ [libnetsnmphelpers="-lnetsnmphelpers"],
+ [libnetsnmphelpers=""]
+ )
+
+ AC_CHECK_LIB([netsnmpagent], [init_agent],
+ [with_libnetsnmpagent="yes"],
+ [with_libnetsnmpagent="no (libnetsnmpagent not found)"],
+ [$libnetsnmphelpers]
+ )
+
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+
+if test "x$with_libnetsnmpagent" = "xyes"; then
+ BUILD_WITH_LIBNETSNMPAGENT_LIBS="-lnetsnmpagent $libnetsnmphelpers"
+fi
+
+AC_SUBST([BUILD_WITH_LIBNETSNMPAGENT_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBNETSNMPAGENT_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBNETSNMPAGENT_LIBS])
# }}}
# --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)"])
-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_HEADERS([oping.h],
+ [with_liboping="yes"],
+ [with_liboping="no (oping.h not found)"]
+ )
+fi
+
+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"
- CPPFLAGS="$SAVE_CPPFLAGS"
- LIBS="$SAVE_LIBS"
+ AC_CHECK_FUNC([OCIEnvCreate],
+ [with_oracle="yes"],
+ [with_oracle="no (Symbol 'OCIEnvCreate' not found)"]
+ )
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LIBS="$SAVE_LIBS"
fi
-if test "x$with_oracle" = "xyes"
-then
- BUILD_WITH_ORACLE_CPPFLAGS="$with_oracle_cppflags"
- BUILD_WITH_ORACLE_LIBS="$with_oracle_libs"
- AC_SUBST(BUILD_WITH_ORACLE_CPPFLAGS)
- AC_SUBST(BUILD_WITH_ORACLE_LIBS)
+
+if test "x$with_oracle" = "xyes"; then
+ BUILD_WITH_ORACLE_CPPFLAGS="$with_oracle_cppflags"
+ BUILD_WITH_ORACLE_LIBS="$with_oracle_libs"
fi
+
+AC_SUBST([BUILD_WITH_ORACLE_CPPFLAGS])
+AC_SUBST([BUILD_WITH_ORACLE_LIBS])
# }}}
# --with-libowcapi {{{
-with_libowcapi_cppflags=""
-with_libowcapi_ldflags=""
-AC_ARG_WITH(libowcapi, [AS_HELP_STRING([--with-libowcapi@<:@=PREFIX@:>@], [Path to libowcapi.])],
-[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
- then
- with_libowcapi_cppflags="-I$withval/include"
- with_libowcapi_ldflags="-L$withval/lib"
- with_libowcapi="yes"
- else
- with_libowcapi="$withval"
- fi
-],
-[
- with_libowcapi="yes"
-])
-if test "x$with_libowcapi" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libowcapi_cppflags"
+AC_ARG_WITH([libowcapi],
+ [AS_HELP_STRING([--with-libowcapi@<:@=PREFIX@:>@], [Path to libowcapi.])],
+ [
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+ with_libowcapi_cppflags="-I$withval/include"
+ with_libowcapi_ldflags="-L$withval/lib"
+ with_libowcapi="yes"
+ else
+ with_libowcapi="$withval"
+ fi
+ ],
+ [with_libowcapi="yes"]
+)
+
+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 <pcap.h>
-]]],
-[[[
- int val = PCAP_ERROR_IFACE_NOT_UP;
- return(val);
-]]]
- )],
- [c_cv_libpcap_have_pcap_error_iface_not_up="yes"],
- [c_cv_libpcap_have_pcap_error_iface_not_up="no"]))
+
+if test "x$with_libpcap" = "xyes"; then
+ AC_CACHE_CHECK([whether libpcap has PCAP_ERROR_IFACE_NOT_UP],
+ [c_cv_libpcap_have_pcap_error_iface_not_up],
+ [
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[#include <pcap.h>]],
+ [[
+ int val = PCAP_ERROR_IFACE_NOT_UP;
+ return(val);
+ ]]
+ )
+ ],
+ [c_cv_libpcap_have_pcap_error_iface_not_up="yes"],
+ [c_cv_libpcap_have_pcap_error_iface_not_up="no"]
+ )
+ ]
+ )
fi
-if test "x$c_cv_libpcap_have_pcap_error_iface_not_up" != "xyes"
-then
- with_libpcap="no (pcap.h misses PCAP_ERROR_IFACE_NOT_UP)"
+
+if test "x$c_cv_libpcap_have_pcap_error_iface_not_up" != "xyes"; then
+ with_libpcap="no (pcap.h misses PCAP_ERROR_IFACE_NOT_UP)"
+fi
+
+if test "x$with_libpcap" = "xyes"; then
+ BUILD_WITH_LIBPCAP_CPPFLAGS="$with_libpcap_cppflags"
+ BUILD_WITH_LIBPCAP_LDFLAGS="$with_libpcap_ldflags"
+ BUILD_WITH_LIBPCAP_LIBS="-lpcap"
fi
-AM_CONDITIONAL(BUILD_WITH_LIBPCAP, test "x$with_libpcap" = "xyes")
+
+AC_SUBST([BUILD_WITH_LIBPCAP_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBPCAP_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBPCAP_LIBS])
# }}}
# --with-libperl {{{
-perl_interpreter="perl"
-AC_ARG_WITH(libperl, [AS_HELP_STRING([--with-libperl@<:@=PREFIX@:>@], [Path to libperl.])],
-[
- if test -f "$withval" && test -x "$withval"
- then
- perl_interpreter="$withval"
- with_libperl="yes"
- else if test "x$withval" != "xno" && test "x$withval" != "xyes"
- then
- LDFLAGS="$LDFLAGS -L$withval/lib"
- CPPFLAGS="$CPPFLAGS -I$withval/include"
- perl_interpreter="$withval/bin/perl"
- with_libperl="yes"
- else
- with_libperl="$withval"
- fi; fi
-],
-[
- with_libperl="yes"
-])
+AC_ARG_WITH([libperl],
+ [AS_HELP_STRING([--with-libperl@<:@=PREFIX@:>@], [Path to libperl.])],
+ [
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ with_libperl="yes"
+ else
+ with_libperl="$withval"
+ fi
+ ],
+ [with_libperl="yes"]
+)
-AC_MSG_CHECKING([for perl])
-perl_interpreter=`which "$perl_interpreter" 2> /dev/null`
-if test -x "$perl_interpreter"
-then
- AC_MSG_RESULT([yes ($perl_interpreter)])
-else
- perl_interpreter=""
- AC_MSG_RESULT([no])
-fi
+AC_ARG_VAR([PERL], [path to Perl interpreter])
+AC_PATH_PROG([PERL], [perl])
-AC_SUBST(PERL, "$perl_interpreter")
+if test "x$PERL" = "x"; then
+ with_libperl="no (no Perl interpreter found)"
+fi
-if test "x$with_libperl" = "xyes" \
- && test -n "$perl_interpreter"
-then
+if test "x$with_libperl" = "xyes"; then
SAVE_CFLAGS="$CFLAGS"
SAVE_LIBS="$LIBS"
-dnl ARCHFLAGS="" -> disable multi -arch on OSX (see Config_heavy.pl:fetch_string)
- PERL_CFLAGS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e perl_inc`
- PERL_LIBS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e ldopts`
+ dnl ARCHFLAGS="" -> disable multi -arch on OSX (see Config_heavy.pl:fetch_string)
+ PERL_CFLAGS=`ARCHFLAGS="" $PERL -MExtUtils::Embed -e perl_inc`
+ PERL_LIBS=`ARCHFLAGS="" $PERL -MExtUtils::Embed -e ldopts`
CFLAGS="$CFLAGS $PERL_CFLAGS"
LIBS="$LIBS $PERL_LIBS"
AC_CACHE_CHECK([for libperl],
[c_cv_have_libperl],
- AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[[
-#define PERL_NO_GET_CONTEXT
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
-]]],
-[[[
- dTHX;
- load_module (PERL_LOADMOD_NOIMPORT,
- newSVpv ("Collectd::Plugin::FooBar", 24),
- Nullsv);
-]]]
- )],
- [c_cv_have_libperl="yes"],
- [c_cv_have_libperl="no"]
- )
+ [
+ AC_LINK_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #define PERL_NO_GET_CONTEXT
+ #include <EXTERN.h>
+ #include <perl.h>
+ #include <XSUB.h>
+ ]],
+ [[
+ dTHX;
+ load_module (PERL_LOADMOD_NOIMPORT,
+ newSVpv ("Collectd::Plugin::FooBar", 24),
+ Nullsv);
+ ]]
+ )
+ ],
+ [c_cv_have_libperl="yes"],
+ [c_cv_have_libperl="no"]
+ )
+ ]
)
- if test "x$c_cv_have_libperl" = "xyes"
- then
- AC_DEFINE(HAVE_LIBPERL, 1, [Define if libperl is present and usable.])
- AC_SUBST(PERL_CFLAGS)
- AC_SUBST(PERL_LIBS)
- else
- with_libperl="no"
+ 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"
+ CFLAGS="$CFLAGS $PERL_CFLAGS"
+ LIBS="$LIBS $PERL_LIBS"
+
+ AC_CACHE_CHECK([if Perl supports ithreads],
+ [c_cv_have_perl_ithreads],
+ [
+ AC_LINK_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <EXTERN.h>
+ #include <perl.h>
+ #include <XSUB.h>
+
+ #if !defined(USE_ITHREADS)
+ # error "Perl does not support ithreads!"
+ #endif /* !defined(USE_ITHREADS) */
+ ]],
+ []
+ )
+ ],
+ [c_cv_have_perl_ithreads="yes"],
+ [c_cv_have_perl_ithreads="no"]
+ )
+ ]
+ )
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")
+fi
-if test "x$with_libperl" = "xyes"
-then
- SAVE_CFLAGS="$CFLAGS"
- SAVE_LIBS="$LIBS"
- CFLAGS="$CFLAGS $PERL_CFLAGS"
- LIBS="$LIBS $PERL_LIBS"
-
- AC_CACHE_CHECK([if perl supports ithreads],
- [c_cv_have_perl_ithreads],
- AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
+if 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"
-#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"]
- )
- )
+ AC_CACHE_CHECK([for broken Perl_load_module()],
+ [c_cv_have_broken_perl_load_module],
+ [
+ AC_LINK_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #define PERL_NO_GET_CONTEXT
+ #include <EXTERN.h>
+ #include <perl.h>
+ #include <XSUB.h>
+ ]],
+ [[
+ dTHX;
+ load_module (PERL_LOADMOD_NOIMPORT,
+ newSVpv ("Collectd::Plugin::FooBar", 24),
+ Nullsv);
+ ]]
+ )
+ ],
+ [c_cv_have_broken_perl_load_module="no"],
+ [c_cv_have_broken_perl_load_module="yes"]
+ )
+ ]
+ )
+
+ CFLAGS="$SAVE_CFLAGS"
+ LIBS="$SAVE_LIBS"
+fi
+
+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 <EXTERN.h>
+ #include <perl.h>
+ #include <XSUB.h>
+ ]]
+ )
- if test "x$c_cv_have_perl_ithreads" = "xyes"
- then
- AC_DEFINE(HAVE_PERL_ITHREADS, 1, [Define if Perl supports ithreads.])
- fi
+ 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"
+ CFLAGS="$SAVE_CFLAGS"
+ LIBS="$SAVE_LIBS"
fi
+AC_SUBST([PERL_CFLAGS])
+AC_SUBST([PERL_LIBS])
-if test "x$with_libperl" = "xyes"
-then
- SAVE_CFLAGS="$CFLAGS"
- SAVE_LIBS="$LIBS"
- # trigger an error if Perl_load_module*() uses __attribute__nonnull__(3)
- # (see issues #41 and #42)
- CFLAGS="$CFLAGS $PERL_CFLAGS -Wall -Werror"
- LIBS="$LIBS $PERL_LIBS"
-
- AC_CACHE_CHECK([for broken Perl_load_module()],
- [c_cv_have_broken_perl_load_module],
- AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[[
-#define PERL_NO_GET_CONTEXT
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
-]]],
-[[[
- dTHX;
- load_module (PERL_LOADMOD_NOIMPORT,
- newSVpv ("Collectd::Plugin::FooBar", 24),
- Nullsv);
-]]]
- )],
- [c_cv_have_broken_perl_load_module="no"],
- [c_cv_have_broken_perl_load_module="yes"]
- )
- )
+# }}}
+
+# --with-libpq {{{
+with_pg_config="pg_config"
+AC_ARG_WITH([libpq],
+ [AS_HELP_STRING([--with-libpq@<:@=PREFIX@:>@], [Path to libpq.])],
+ [
+ if test "x$withval" = "xno" || test "x$withval" = "xyes"; then
+ with_libpq="$withval"
+ else
+ if test -f "$withval" && test -x "$withval"; then
+ with_pg_config="$withval"
+ else if test -x "$withval/bin/pg_config"; then
+ with_pg_config="$withval/bin/pg_config"
+ fi; fi
+ with_libpq="yes"
+ fi
+ ],
+ [with_libpq="yes"]
+)
+
+if test "x$with_libpq" = "xyes"; then
+ with_libpq_includedir=`$with_pg_config --includedir 2> /dev/null`
+ pg_config_status=$?
+
+ if test $pg_config_status -eq 0; then
+ if test -n "$with_libpq_includedir"; then
+ for dir in $with_libpq_includedir; do
+ with_libpq_cppflags="$with_libpq_cppflags -I$dir"
+ done
+ fi
+ else
+ AC_MSG_WARN([$with_pg_config returned with status $pg_config_status])
+ fi
+
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libpq_cppflags"
+
+ AC_CHECK_HEADERS([libpq-fe.h],
+ [with_libpq="yes"],
+ [with_libpq="no (libpq-fe.h not found)"]
+ )
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+
+if test "x$with_libpq" = "xyes"; then
+ with_libpq_libdir=`$with_pg_config --libdir 2> /dev/null`
+ pg_config_status=$?
+
+ if test $pg_config_status -eq 0
+ then
+ if test -n "$with_libpq_libdir"; then
+ for dir in $with_libpq_libdir; do
+ with_libpq_ldflags="$with_libpq_ldflags -L$dir"
+ done
+ fi
+ else
+ AC_MSG_WARN([$with_pg_config returned with status $pg_config_status])
+ fi
+
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_libpq_ldflags"
+
+ AC_CHECK_LIB([pq], [PQserverVersion],
+ [with_libpq="yes"],
+ [with_libpq="no (symbol 'PQserverVersion' not found)"])
+
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+
+if test "x$with_libpq" = "xyes"; then
+ BUILD_WITH_LIBPQ_CPPFLAGS="$with_libpq_cppflags"
+ BUILD_WITH_LIBPQ_LDFLAGS="$with_libpq_ldflags"
+ BUILD_WITH_LIBPQ_LIBS="-lpq"
+fi
+
+AC_SUBST([BUILD_WITH_LIBPQ_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBPQ_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBPQ_LIBS])
+# }}}
+
+# --with-libpqos {{{
+AC_ARG_WITH([libpqos],
+ [AS_HELP_STRING([--with-libpqos@<:@=PREFIX@:>@], [Path to libpqos.])],
+ [
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+ with_libpqos_cppflags="-I$withval/include"
+ with_libpqos_ldflags="-L$withval/lib"
+ with_libpqos="yes"
+ else
+ with_libpqos="$withval"
+ fi
+ ],
+ [with_libpqos="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_libpqos" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libpqos_cppflags"
-if test "x$with_libperl" = "xyes"
-then
- SAVE_CFLAGS="$CFLAGS"
- SAVE_LIBS="$LIBS"
- CFLAGS="$CFLAGS $PERL_CFLAGS"
- LIBS="$LIBS $PERL_LIBS"
-
- AC_CHECK_MEMBER(
- [struct mgvtbl.svt_local],
- [have_struct_mgvtbl_svt_local="yes"],
- [have_struct_mgvtbl_svt_local="no"],
- [
-#include <EXTERN.h>
-#include <perl.h>
-#include <XSUB.h>
- ])
-
- if test "x$have_struct_mgvtbl_svt_local" = "xyes"
- then
- AC_DEFINE(HAVE_PERL_STRUCT_MGVTBL_SVT_LOCAL, 1,
- [Define if Perl's struct mgvtbl has member svt_local.])
- fi
-
- CFLAGS="$SAVE_CFLAGS"
- LIBS="$SAVE_LIBS"
+ AC_CHECK_HEADERS([pqos.h],
+ [with_libpqos="yes"],
+ [with_libpqos="no (pqos.h not found)"]
+ )
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
-# }}}
-# --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=$?
+if test "x$with_libpqos" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_libpqos_ldflags"
- 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_LIB([pqos], [pqos_init],
+ [with_libpqos="yes"],
+ [with_libpqos="no (Can't find libpqos)"]
+ )
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libpq_cppflags"
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
- AC_CHECK_HEADERS(libpq-fe.h, [],
- [with_libpq="no (libpq-fe.h not found)"], [])
+if test "x$with_libpqos" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libpqos_cppflags"
+ AC_PREPROC_IFELSE(
+ [
+ AC_LANG_SOURCE(
+ [[
+ #include <pqos.h>
+ #if PQOS_VERSION < 106
+ #error "required PQOS version >= 1.06"
+ #endif
+ ]]
+ )
+ ],
+ [with_libpqos="yes"],
+ [with_libpqos="no (pqos library version 1.06 or higher is required)"]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
-if test "x$with_libpq" = "xyes"
-then
- with_libpq_libdir=`$with_pg_config --libdir 2> /dev/null`
- pg_config_status=$?
-
- if test $pg_config_status -eq 0
- then
- if test -n "$with_libpq_libdir"; then
- for dir in $with_libpq_libdir; do
- with_libpq_ldflags="$with_libpq_ldflags -L$dir"
- done
- fi
- else
- AC_MSG_WARN([$with_pg_config returned with status $pg_config_status])
- fi
-
- SAVE_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $with_libpq_ldflags"
-
- AC_CHECK_LIB(pq, PQconnectdb,
- [with_libpq="yes"],
- [with_libpq="no (symbol 'PQconnectdb' not found)"])
-
- AC_CHECK_LIB(pq, PQserverVersion,
- [with_libpq="yes"],
- [with_libpq="no (symbol 'PQserverVersion' not found)"])
-
- LDFLAGS="$SAVE_LDFLAGS"
-fi
-if test "x$with_libpq" = "xyes"
-then
- BUILD_WITH_LIBPQ_CPPFLAGS="$with_libpq_cppflags"
- BUILD_WITH_LIBPQ_LDFLAGS="$with_libpq_ldflags"
- AC_SUBST(BUILD_WITH_LIBPQ_CPPFLAGS)
- AC_SUBST(BUILD_WITH_LIBPQ_LDFLAGS)
+
+if test "x$with_libpqos" = "xyes"; then
+ BUILD_WITH_LIBPQOS_CPPFLAGS="$with_libpqos_cppflags"
+ BUILD_WITH_LIBPQOS_LDFLAGS="$with_libpqos_ldflags"
+ BUILD_WITH_LIBPQOS_LIBS="-lpqos"
fi
-AM_CONDITIONAL(BUILD_WITH_LIBPQ, test "x$with_libpq" = "xyes")
+
+AC_SUBST([BUILD_WITH_LIBPQOS_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBPQOS_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBPQOS_LIBS])
# }}}
-# --with-libpqos {{{
-with_libpqos_cppflags=""
-with_libpqos_ldflags=""
-AC_ARG_WITH(libpqos, [AS_HELP_STRING([--with-libpqos@<:@=PREFIX@:>@], [Path to libpqos.])],
-[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
- then
- with_libpqos_cppflags="-I$withval/include"
- with_libpqos_ldflags="-L$withval/lib"
- with_libpqos="yes"
- else
- with_libpqos="$withval"
- fi
-],
-[
- with_libpqos="yes"
-])
-if test "x$with_libpqos" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libpqos_cppflags"
+# --with-libjevents {{{
+with_libjevents_cppflags=""
+with_libjevents_ldflags=""
+AC_ARG_WITH([libjevents],
+ [AS_HELP_STRING([--with-libjevents@<:@=PREFIX@:>@], [Path to libjevents.])],
+ [
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+ with_libjevents_cppflags="-I$withval/include"
+ with_libjevents_ldflags="-L$withval/lib"
+ with_libjevents="yes"
+ else
+ with_libjevents="$withval"
+ fi
+ ],
+ [with_libjevents="yes"]
+)
+
+if test "x$with_libjevents" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libjevents_cppflags"
- AC_CHECK_HEADERS(pqos.h, [with_libpqos="yes"], [with_libpqos="no (pqos.h not found)"])
+ AC_CHECK_HEADERS([jevents.h], [with_libjevents="yes"], [with_libjevents="no (jevents.h not found)"])
- CPPFLAGS="$SAVE_CPPFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
-if test "x$with_libpqos" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- SAVE_LDFLAGS="$LDFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libpqos_cppflags"
- LDFLAGS="$LDFLAGS $with_libpqos_ldflags"
+if test "x$with_libjevents" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_libjevents_ldflags"
- AC_CHECK_LIB(pqos, pqos_init, [with_libpqos="yes"], [with_libpqos="no (Can't find libpqos)"])
+ AC_CHECK_LIB([jevents], [json_events], [with_libjevents="yes"], [with_libjevents="no (Can't find libjevents)"])
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
-fi
-if test "x$with_libpqos" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libpqos_cppflags"
- AC_RUN_IFELSE([AC_LANG_PROGRAM(
- [[#include <pqos.h>]],
- [[return !(PQOS_VERSION >= 106)]])],
- [with_libpqos="yes"], [with_libpqos="no (pqos library version 1.06 or higher is required)"])
- CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
fi
-if test "x$with_libpqos" = "xyes"
-then
- BUILD_WITH_LIBPQOS_CPPFLAGS="$with_libpqos_cppflags"
- BUILD_WITH_LIBPQOS_LDFLAGS="$with_libpqos_ldflags"
- BUILD_WITH_LIBPQOS_LIBS="-lpqos"
- AC_SUBST(BUILD_WITH_LIBPQOS_CPPFLAGS)
- AC_SUBST(BUILD_WITH_LIBPQOS_LDFLAGS)
- AC_SUBST(BUILD_WITH_LIBPQOS_LIBS)
+if test "x$with_libjevents" = "xyes"; then
+ BUILD_WITH_LIBJEVENTS_CPPFLAGS="$with_libjevents_cppflags"
+ BUILD_WITH_LIBJEVENTS_LDFLAGS="$with_libjevents_ldflags"
+ BUILD_WITH_LIBJEVENTS_LIBS="-ljevents"
fi
+AC_SUBST([BUILD_WITH_LIBJEVENTS_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBJEVENTS_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBJEVENTS_LIBS])
# }}}
# --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"
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"
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"
[
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"
],
[with_libprotobuf_c="no (<protobuf-c.h> not found)"]
)
+
CPPFLAGS="$SAVE_CPPFLAGS"
],
[with_libprotobuf_c="no (libprotobuf-c not found)"]
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"
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])
CPPFLAGS="$LIBPYTHON_CPPFLAGS $CPPFLAGS"
LDFLAGS="$LIBPYTHON_LDFLAGS $LDFLAGS"
LIBS="$LIBPYTHON_LIBS $LIBS"
+
AC_CHECK_HEADERS([Python.h],
[
AC_MSG_CHECKING([for libpython])
],
[with_libpython="no"]
)
+
CPPFLAGS="$SAVE_CPPFLAGS"
LDFLAGS="$SAVE_LDFLAGS"
LIBS="$SAVE_LIBS"
# }}} --with-libpython
# --with-librabbitmq {{{
-with_librabbitmq_cppflags=""
-with_librabbitmq_ldflags=""
-AC_ARG_WITH(librabbitmq, [AS_HELP_STRING([--with-librabbitmq@<:@=PREFIX@:>@], [Path to librabbitmq.])],
-[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
- then
- with_librabbitmq_cppflags="-I$withval/include"
- with_librabbitmq_ldflags="-L$withval/lib"
- with_librabbitmq="yes"
- else
- with_librabbitmq="$withval"
- fi
-],
-[
- with_librabbitmq="yes"
-])
-SAVE_CPPFLAGS="$CPPFLAGS"
-SAVE_LDFLAGS="$LDFLAGS"
-CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
-LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags"
-if test "x$with_librabbitmq" = "xyes"
-then
- AC_CHECK_HEADERS(amqp.h, [with_librabbitmq="yes"], [with_librabbitmq="no (amqp.h not found)"])
+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"]
+)
+
+if test "x$with_librabbitmq" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
+
+ AC_CHECK_HEADERS([amqp.h],
+ [with_librabbitmq="yes"],
+ [with_librabbitmq="no (amqp.h not found)"]
+ )
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
-if test "x$with_librabbitmq" = "xyes"
-then
- # librabbitmq up to version 0.9.1 provides "library_errno", later
- # versions use "library_error". The library does not provide a version
- # macro :( Use "AC_CHECK_MEMBERS" (plural) for automatic defines.
- AC_CHECK_MEMBERS([amqp_rpc_reply_t.library_errno],,,
- [
-#if HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-#if HAVE_STDIO_H
-# include <stdio.h>
-#endif
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#include <amqp.h>
- ])
+
+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 :(.
+
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
+
+ AC_CHECK_MEMBERS([amqp_rpc_reply_t.library_errno],
+ [],
+ [],
+ [[
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <stdint.h>
+ #include <inttypes.h>
+ #include <amqp.h>
+ ]]
+ )
+ CPPFLAGS="$SAVE_CPPFLAGS"
+
+ 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)"]
+ )
+
+ LDFLAGS="$SAVE_LDFLAGS"
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)"])
+
+if test "x$with_librabbitmq" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+ SAVE_LIBS="$LIBS"
+ CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
+ LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags"
+ LIBS="-lrabbitmq"
+
+ AC_CHECK_HEADERS([amqp_tcp_socket.h amqp_socket.h])
+ AC_CHECK_FUNC([amqp_tcp_socket_new],
+ [
+ AC_DEFINE([HAVE_AMQP_TCP_SOCKET], [1],
+ [Define if librabbitmq provides the new TCP socket interface.])
+ ]
+ )
+
+ AC_CHECK_DECLS([amqp_socket_close],
+ [],
+ [],
+ [[
+ #include <amqp.h>
+ #ifdef HAVE_AMQP_TCP_SOCKET_H
+ # include <amqp_tcp_socket.h>
+ #endif
+ #ifdef HAVE_AMQP_SOCKET_H
+ # include <amqp_socket.h>
+ #endif
+ ]]
+ )
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+ LIBS="$SAVE_LIBS"
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.])
+
+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"
-AM_CONDITIONAL(BUILD_WITH_LIBRABBITMQ, test "x$with_librabbitmq" = "xyes")
-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
-
- AC_CHECK_DECLS(amqp_socket_close,
- [amqp_socket_close_decl="yes"], [amqp_socket_close_decl="no"],
- [[
-#include <amqp.h>
-#ifdef HAVE_AMQP_TCP_SOCKET_H
-# include <amqp_tcp_socket.h>
-#endif
-#ifdef HAVE_AMQP_SOCKET_H
-# include <amqp_socket.h>
-#endif
- ]])
+AC_SUBST(BUILD_WITH_LIBRABBITMQ_CPPFLAGS)
+AC_SUBST(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
+AC_SUBST(BUILD_WITH_LIBRABBITMQ_LIBS)
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
- LIBS="$SAVE_LIBS"
-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"
+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"]
+)
+
+if test "x$with_librdkafka" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_librdkafka_cppflags"
-CPPFLAGS="$CPPFLAGS $with_librdkafka_cppflags"
-LDFLAGS="$LDFLAGS $with_librdkafka_ldflags"
+ AC_CHECK_HEADERS([librdkafka/rdkafka.h],
+ [with_librdkafka="yes"],
+ [with_librdkafka="no (librdkafka/rdkafka.h not found)"]
+ )
-if test "x$with_librdkafka" = "xyes"
-then
- 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_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"])
+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
- 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.])
+
+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
-CPPFLAGS="$SAVE_CPPFLAGS"
-LDFLAGS="$SAVE_LDFLAGS"
-AM_CONDITIONAL(BUILD_WITH_LIBRDKAFKA, test "x$with_librdkafka" = "xyes")
+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"
- 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"])
+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"]
+)
-SAVE_CPPFLAGS="$CPPFLAGS"
-SAVE_LDFLAGS="$LDFLAGS"
+if test "x$with_librouteros" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_librouteros_cppflags"
-CPPFLAGS="$CPPFLAGS $LIBROUTEROS_CPPFLAGS"
-LDFLAGS="$LDFLAGS $LIBROUTEROS_LDFLAGS"
+ AC_CHECK_HEADERS([routeros_api.h],
+ [with_librouteros="yes"],
+ [with_librouteros="no (routeros_api.h not found)"]
+ )
-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)"])
-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)"])
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
-CPPFLAGS="$SAVE_CPPFLAGS"
-LDFLAGS="$SAVE_LDFLAGS"
+if test "x$with_librouteros" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_librouteros_ldflags"
-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)
+ 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
-AM_CONDITIONAL(BUILD_WITH_LIBROUTEROS, test "x$with_librouteros" = "xyes")
+
+AC_SUBST([BUILD_WITH_LIBROUTEROS_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBROUTEROS_LDFLAGS])
# }}}
# --with-librrd {{{
-librrd_cflags=""
-librrd_ldflags=""
librrd_threadsafe="no"
librrd_rrdc_update="no"
-AC_ARG_WITH(librrd,
+AC_ARG_WITH([librrd],
[AS_HELP_STRING([--with-librrd@<:@=PREFIX@:>@], [Path to rrdtool.])],
[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
- then
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
librrd_cflags="-I$withval/include"
librrd_ldflags="-L$withval/lib"
with_librrd="yes"
[with_librrd="yes"]
)
-if test "x$with_librrd" = "xyes"
-then
+if test "x$with_librrd" = "xyes"; then
SAVE_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS $librrd_ldflags"
PKG_CHECK_MODULES([RRD], [librrd >= 1.6.0],
CPPFLAGS="$SAVE_CPPFLAGS"
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"
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"
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
+ ]
+)
+
+if test "x$with_libsensors" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_sensors_cppflags"
- AC_CHECK_HEADERS(sensors/sensors.h, [], [with_libsensors="no (sensors/sensors.h not found)"])
+ AC_CHECK_HEADERS([sensors/sensors.h],
+ [with_libsensors="yes"],
+ [with_libsensors="no (sensors/sensors.h not found)"]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
+ 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"
+
+ AC_CHECK_LIB([sensors], [sensors_init],
+ [with_libsensors="yes"],
+ [with_libsensors="no (libsensors not found)"]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
+ 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 {{{
# }}}
# --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"
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)"
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"
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"
LIBS="-lstatgrab $LIBS"
AC_CACHE_CHECK([if libstatgrab >= 0.90],
- [c_cv_have_libstatgrab_0_90],
- AC_LINK_IFELSE([AC_LANG_PROGRAM(
-[[[
-#include <stdio.h>
-#include <statgrab.h>
-]]],
-[[[
- if (sg_init()) return 0;
-]]]
- )],
- [c_cv_have_libstatgrab_0_90="no"],
- [c_cv_have_libstatgrab_0_90="yes"]
+ [c_cv_have_libstatgrab_0_90],
+ [
+ AC_LINK_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <stdio.h>
+ #include <statgrab.h>
+ ]],
+ [[
+ if (sg_init()) return 0;
+ ]]
)
+ ],
+ [c_cv_have_libstatgrab_0_90="no"],
+ [c_cv_have_libstatgrab_0_90="yes"]
+ )
+ ]
)
CFLAGS="$SAVE_CFLAGS"
LIBS="$SAVE_LIBS"
fi
-AM_CONDITIONAL(BUILD_WITH_LIBSTATGRAB, test "x$with_libstatgrab" = "xyes")
-if test "x$with_libstatgrab" = "xyes"
-then
- AC_DEFINE(HAVE_LIBSTATGRAB, 1, [Define to 1 if you have the 'statgrab' library (-lstatgrab)])
+AM_CONDITIONAL([BUILD_WITH_LIBSTATGRAB], [test "x$with_libstatgrab" = "xyes"])
+
+if test "x$with_libstatgrab" = "xyes"; then
+ AC_DEFINE([HAVE_LIBSTATGRAB], [1],
+ [Define to 1 if you have the 'statgrab' library (-lstatgrab)]
+ )
+
+ if test "x$c_cv_have_libstatgrab_0_90" = "xyes"; then
+ AC_DEFINE([HAVE_LIBSTATGRAB_0_90], [1],
+ [Define to 1 if libstatgrab version >= 0.90]
+ )
+ fi
+
BUILD_WITH_LIBSTATGRAB_CFLAGS="$with_libstatgrab_cflags"
BUILD_WITH_LIBSTATGRAB_LDFLAGS="$with_libstatgrab_ldflags"
- AC_SUBST(BUILD_WITH_LIBSTATGRAB_CFLAGS)
- AC_SUBST(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
- if test "x$c_cv_have_libstatgrab_0_90" = "xyes"
- then
- AC_DEFINE(HAVE_LIBSTATGRAB_0_90, 1, [Define to 1 if libstatgrab version >= 0.90])
- fi
+
fi
+
+AC_SUBST([BUILD_WITH_LIBSTATGRAB_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBSTATGRAB_LDFLAGS])
# }}}
# --with-libtokyotyrant {{{
-with_libtokyotyrant_cppflags=""
-with_libtokyotyrant_ldflags=""
-with_libtokyotyrant_libs=""
-AC_ARG_WITH(libtokyotyrant, [AS_HELP_STRING([--with-libtokyotyrant@<:@=PREFIX@:>@], [Path to libtokyotyrant.])],
-[
- if test "x$withval" = "xno"
- then
- with_libtokyotyrant="no"
- else if test "x$withval" = "xyes"
- then
- with_libtokyotyrant="yes"
- else
- with_libtokyotyrant_cppflags="-I$withval/include"
- with_libtokyotyrant_ldflags="-L$withval/include"
- with_libtokyotyrant_libs="-ltokyotyrant"
- with_libtokyotyrant="yes"
- fi; fi
-],
-[
- with_libtokyotyrant="yes"
-])
+AC_ARG_WITH([libtokyotyrant],
+ [AS_HELP_STRING([--with-libtokyotyrant@<:@=PREFIX@:>@], [Path to libtokyotyrant.])],
+ [
+ if test "x$withval" = "xno" || test "x$withval" = "xyes"; then
+ with_libtokyotyrant="$withval"
+ else
+ with_libtokyotyrant_cppflags="-I$withval/include"
+ with_libtokyotyrant_ldflags="-L$withval/include"
+ with_libtokyotyrant_libs="-ltokyotyrant"
+ with_libtokyotyrant="yes"
+ fi
+ ],
+ [with_libtokyotyrant="yes"]
+)
-if test "x$with_libtokyotyrant" = "xyes"
-then
- if $PKG_CONFIG --exists tokyotyrant
- then
+if test "x$with_libtokyotyrant" = "xyes"; then
+ if $PKG_CONFIG --exists tokyotyrant; then
with_libtokyotyrant_cppflags="$with_libtokyotyrant_cppflags `$PKG_CONFIG --cflags tokyotyrant`"
with_libtokyotyrant_ldflags="$with_libtokyotyrant_ldflags `$PKG_CONFIG --libs-only-L tokyotyrant`"
with_libtokyotyrant_libs="$with_libtokyotyrant_libs `$PKG_CONFIG --libs-only-l tokyotyrant`"
fi
fi
-SAVE_CPPFLAGS="$CPPFLAGS"
-SAVE_LDFLAGS="$LDFLAGS"
-CPPFLAGS="$CPPFLAGS $with_libtokyotyrant_cppflags"
-LDFLAGS="$LDFLAGS $with_libtokyotyrant_ldflags"
+if test "x$with_libtokyotyrant" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libtokyotyrant_cppflags"
-if test "x$with_libtokyotyrant" = "xyes"
-then
- AC_CHECK_HEADERS(tcrdb.h,
- [
- AC_DEFINE(HAVE_TCRDB_H, 1,
- [Define to 1 if you have the <tcrdb.h> header file.])
- ], [with_libtokyotyrant="no (tcrdb.h not found)"])
-fi
+ AC_CHECK_HEADERS([tcrdb.h],
+ [with_libtokyotyrant="yes"],
+ [with_libtokyotyrant="no (tcrdb.h not found)"]
+ )
-if test "x$with_libtokyotyrant" = "xyes"
-then
- AC_CHECK_LIB(tokyotyrant, tcrdbrnum,
- [
- AC_DEFINE(HAVE_LIBTOKYOTYRANT, 1,
- [Define to 1 if you have the tokyotyrant library (-ltokyotyrant).])
- ],
- [with_libtokyotyrant="no (symbol tcrdbrnum not found)"],
- [$with_libtokyotyrant_libs])
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
-CPPFLAGS="$SAVE_CPPFLAGS"
-LDFLAGS="$SAVE_LDFLAGS"
+if test "x$with_libtokyotyrant" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_libtokyotyrant_ldflags"
-if test "x$with_libtokyotyrant" = "xyes"
-then
+ AC_CHECK_LIB([tokyotyrant], [tcrdbrnum],
+ [with_libtokyotyrant="yes"],
+ [with_libtokyotyrant="no (symbol tcrdbrnum not found)"],
+ [$with_libtokyotyrant_libs]
+ )
+
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+
+if test "x$with_libtokyotyrant" = "xyes"; then
BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS="$with_libtokyotyrant_cppflags"
BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS="$with_libtokyotyrant_ldflags"
BUILD_WITH_LIBTOKYOTYRANT_LIBS="$with_libtokyotyrant_libs"
- AC_SUBST(BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS)
- AC_SUBST(BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS)
- AC_SUBST(BUILD_WITH_LIBTOKYOTYRANT_LIBS)
fi
-AM_CONDITIONAL(BUILD_WITH_LIBTOKYOTYRANT, test "x$with_libtokyotyrant" = "xyes")
+AC_SUBST([BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBTOKYOTYRANT_LIBS])
# }}}
# --with-libudev {{{
-with_libudev_cflags=""
-with_libudev_ldflags=""
-AC_ARG_WITH(libudev, [AS_HELP_STRING([--with-libudev@<:@=PREFIX@:>@], [Path to libudev.])],
-[
- if test "x$withval" = "xno"
- then
- with_libudev="no"
- else
- with_libudev="yes"
- if test "x$withval" != "xyes"
- then
- with_libudev_cflags="-I$withval/include"
- with_libudev_ldflags="-L$withval/lib"
- with_libudev="yes"
- fi
- fi
-],
-[
- if test "x$ac_system" = "xLinux"
- then
- with_libudev="yes"
- else
- with_libudev="no (Linux only library)"
- fi
-])
-if test "x$with_libudev" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libudev_cflags"
+AC_ARG_WITH([libudev],
+ [AS_HELP_STRING([--with-libudev@<:@=PREFIX@:>@], [Path to libudev.])],
+ [
+ if test "x$withval" = "xno" || test "x$withval" = "xyes"; then
+ with_libudev="$withval"
+ else
+ with_libudev_cppflags="-I$withval/include"
+ with_libudev_ldflags="-L$withval/lib"
+ with_libudev="yes"
+ fi
+ ],
+ [
+ if test "x$ac_system" = "xLinux"; then
+ with_libudev="yes"
+ else
+ with_libudev="no (Linux only library)"
+ fi
+ ]
+)
+
+if test "x$with_libudev" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libudev_cppflags"
- AC_CHECK_HEADERS(libudev.h, [], [with_libudev="no (libudev.h not found)"])
+ AC_CHECK_HEADERS([libudev.h],
+ [with_libudev="yes"],
+ [with_libudev="no (libudev.h not found)"]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
-if test "x$with_libudev" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- SAVE_LDFLAGS="$LDFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libudev_cflags"
- LDFLAGS="$LDFLAGS $with_libudev_ldflags"
- AC_CHECK_LIB(udev, udev_new,
- [
- AC_DEFINE(HAVE_LIBUDEV, 1, [Define to 1 if you have the udev library (-ludev).])
- ],
- [with_libudev="no (libudev not found)"])
+if test "x$with_libudev" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_libudev_ldflags"
+
+ AC_CHECK_LIB([udev], [udev_new],
+ [with_libudev="yes"],
+ [with_libudev="no (libudev not found)"]
+ )
+
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
+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
-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")
+
+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
-fi
-if test "x$with_libupsclient" = "xuse_libupsclient_config"
-then
- with_libupsclient="yes"
+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"
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
-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
+ 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
-# 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" = "xuse_pkgconfig"; then
+ with_libupsclient_cflags="`$PKG_CONFIG --cflags 'libupsclient'`"
+ if test $? -ne 0; then
+ with_libupsclient="no ($PKG_CONFIG failed)"
+ fi
- AC_CHECK_HEADERS(upsclient.h, [], [with_libupsclient="no (upsclient.h not found)"])
+ with_libupsclient_libs="`$PKG_CONFIG --libs 'libupsclient'`"
+ if test $? -ne 0; then
+ with_libupsclient="no ($PKG_CONFIG failed)"
+ fi
+fi
- CPPFLAGS="$SAVE_CPPFLAGS"
+if test "x$with_libupsclient" = "xuse_pkgconfig"; then
+ with_libupsclient="yes"
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_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags"
- AC_CHECK_LIB(upsclient, upscli_connect,
- [with_libupsclient="yes"],
- [with_libupsclient="no (symbol upscli_connect not found)"])
+ AC_CHECK_HEADERS([upsclient.h],
+ [with_libupsclient="yes"],
+ [with_libupsclient="no (upsclient.h not found)"]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
-if test "x$with_libupsclient" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags"
- AC_CHECK_TYPES([UPSCONN_t, UPSCONN], [], [],
-[#include <stdlib.h>
-#include <stdio.h>
-#include <upsclient.h>])
+if test "x$with_libupsclient" = "xyes"; then
+ SAVE_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_init],
+ [AC_DEFINE([HAVE_UPSCLI_INIT], [1], [Define when upscli_init() (since version 2-7) is available.])]
+ )
+
+ AC_CHECK_LIB([upsclient], [upscli_tryconnect],
+ [AC_DEFINE([HAVE_UPSCLI_TRYCONNECT], [1], [Define when upscli_tryconnect() (since version 2.6.2) is available.])]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
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
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libupsclient_cflags"
+
+ AC_CHECK_TYPES([UPSCONN_t, UPSCONN],
+ [],
+ [],
+ [[
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <upsclient.h>
+ ]]
+ )
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+
+if test "x$with_libupsclient" = "xyes"; then
+ BUILD_WITH_LIBUPSCLIENT_CFLAGS="$with_libupsclient_cflags"
+ BUILD_WITH_LIBUPSCLIENT_LIBS="$with_libupsclient_libs"
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"]
+)
+
+if test "x$with_libxenctrl" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags"
- AC_CHECK_HEADERS(xenctrl.h, [with_libxenctrl="yes"], [with_libxenctrl="no (xenctrl.h not found)"])
+ AC_CHECK_HEADERS([xenctrl.h],
+ [with_libxenctrl="yes"],
+ [with_libxenctrl="no (xenctrl.h not found)"]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
+ 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"]
+)
+
+if test "x$with_libyajl" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libyajl_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_parse.h, [with_libyajl="yes"], [with_libyajl="no (yajl/yajl_parse.h not found)"])
- AC_CHECK_HEADERS(yajl/yajl_version.h)
+ AC_CHECK_HEADERS([yajl/yajl_version.h])
- CPPFLAGS="$SAVE_CPPFLAGS"
+ 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"
+
+ 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
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
+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
-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")
+
+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
-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
+ $PKG_CONFIG --exists 'varnishapi' 2>/dev/null
+ if test $? -ne 0; then
+ with_libvarnish="no (pkg-config doesn't know varnishapi)"
+ fi
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"
+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
- CPPFLAGS="$CPPFLAGS $with_libvarnish_cflags"
+ with_libvarnish_libs="`$PKG_CONFIG --libs 'varnishapi'`"
+ if test $? -ne 0; then
+ with_libvarnish="no ($PKG_CONFIG failed)"
+ fi
+fi
+if test "x$with_libvarnish" = "xuse_pkgconfig"; then
+ with_libvarnish="yes"
+fi
- 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)"])])])
+if test "x$with_libvarnish" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libvarnish_cflags"
+
+ $PKG_CONFIG --atleast-version=5.2 'varnishapi' 2>/dev/null
+ if test $? -eq 0; then
+ AC_DEFINE([HAVE_VARNISH_V5], [1], [Varnish 5 API support])
+ else
+ 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)"]
+ )
+ ]
+ )
+ ]
+ )
+ fi
- 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
-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
+ 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="yes"],
+ [with_libxml2="no (libxml/parser.h not found)"]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
-if test "x$with_libxml2" = "xyes"
-then
- SAVE_CFLAGS="$CFLAGS"
- SAVE_LDFLAGS="$LDFLAGS"
- CFLAGS="$CFLAGS $with_libxml2_cflags"
- LDFLAGS="$LDFLAGS $with_libxml2_ldflags"
+if test "x$with_libxml2" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_libxml2_ldflags"
- AC_CHECK_LIB(xml2, xmlXPathEval,
- [with_libxml2="yes"],
- [with_libxml2="no (symbol xmlXPathEval not found)"])
+ AC_CHECK_LIB([xml2], [xmlXPathEval],
+ [with_libxml2="yes"],
+ [with_libxml2="no (symbol xmlXPathEval not found)"]
+ )
- CFLAGS="$SAVE_CFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
fi
-dnl Add the right compiler flags and libraries.
+
if test "x$with_libxml2" = "xyes"; then
- BUILD_WITH_LIBXML2_CFLAGS="$with_libxml2_cflags"
- BUILD_WITH_LIBXML2_LIBS="$with_libxml2_ldflags"
- AC_SUBST(BUILD_WITH_LIBXML2_CFLAGS)
- AC_SUBST(BUILD_WITH_LIBXML2_LIBS)
+ BUILD_WITH_LIBXML2_CFLAGS="$with_libxml2_cflags"
+ BUILD_WITH_LIBXML2_LIBS="$with_libxml2_ldflags"
fi
-if test "x$with_libvirt" = "xyes"
-then
- with_libvirt_cflags="`$PKG_CONFIG --cflags libvirt`"
- if test $? -ne 0
- then
- with_libvirt="no"
- fi
- with_libvirt_ldflags="`$PKG_CONFIG --libs libvirt`"
- if test $? -ne 0
- then
- with_libvirt="no"
- fi
-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)"])
+AC_SUBST([BUILD_WITH_LIBXML2_CFLAGS])
+AC_SUBST([BUILD_WITH_LIBXML2_LIBS])
- CPPFLAGS="$SAVE_CPPFLAGS"
+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_CFLAGS="$CFLAGS"
- SAVE_LDFLAGS="$LDFLAGS"
- CFLAGS="$CFLAGS $with_libvirt_cflags"
- LDFLAGS="$LDFLAGS $with_libvirt_ldflags"
+if test "x$with_libvirt" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libvirt_cflags"
+
+ AC_CHECK_HEADERS([libvirt/libvirt.h],
+ [with_libvirt="yes"],
+ [with_libvirt="no (libvirt/libvirt.h not found)"]
+ )
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+
+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=""
+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])
- $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])
+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
- 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])
-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])
-fi
-
-if test "x$with_libopenipmipthread" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libopenipmipthread_cflags"
-
- AC_CHECK_HEADERS(OpenIPMI/ipmi_smi.h,
- [with_libopenipmipthread="yes"],
- [with_libopenipmipthread="no (OpenIPMI/ipmi_smi.h not found)"],
-[#include <OpenIPMI/ipmiif.h>
-#include <OpenIPMI/ipmi_err.h>
-#include <OpenIPMI/ipmi_posix.h>
-#include <OpenIPMI/ipmi_conn.h>
-])
+if test "x$with_libopenipmipthread" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libopenipmipthread_cflags"
+
+ AC_CHECK_HEADERS([OpenIPMI/ipmi_smi.h],
+ [with_libopenipmipthread="yes"],
+ [with_libopenipmipthread="no (OpenIPMI/ipmi_smi.h not found)"],
+ [[
+ #include <OpenIPMI/ipmiif.h>
+ #include <OpenIPMI/ipmi_err.h>
+ #include <OpenIPMI/ipmi_posix.h>
+ #include <OpenIPMI/ipmi_conn.h>
+ ]]
+ )
- CPPFLAGS="$SAVE_CPPFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
-if test "x$with_libopenipmipthread" = "xyes"
-then
- BUILD_WITH_OPENIPMI_CFLAGS="$with_libopenipmipthread_cflags"
- BUILD_WITH_OPENIPMI_LIBS="$with_libopenipmipthread_ldflags"
- AC_SUBST(BUILD_WITH_OPENIPMI_CFLAGS)
- AC_SUBST(BUILD_WITH_OPENIPMI_LIBS)
+if test "x$with_libopenipmipthread" = "xyes"; then
+ BUILD_WITH_OPENIPMI_CFLAGS="$with_libopenipmipthread_cflags"
+ BUILD_WITH_OPENIPMI_LIBS="$with_libopenipmipthread_ldflags"
fi
+
+AC_SUBST([BUILD_WITH_OPENIPMI_CFLAGS])
+AC_SUBST([BUILD_WITH_OPENIPMI_LIBS])
# }}}
# --with-libatasmart {{{
-with_libatasmart_cppflags=""
-with_libatasmart_ldflags=""
-AC_ARG_WITH(libatasmart, [AS_HELP_STRING([--with-libatasmart@<:@=PREFIX@:>@], [Path to libatasmart.])],
-[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
- then
- with_libatasmart_cppflags="-I$withval/include"
- with_libatasmart_ldflags="-L$withval/lib"
- with_libatasmart="yes"
- else
- with_libatasmart="$withval"
- fi
-],
-[
- if test "x$ac_system" = "xLinux"
- then
- with_libatasmart="yes"
- else
- with_libatasmart="no (Linux only library)"
- fi
-])
-if test "x$with_libatasmart" = "xyes"
-then
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_libatasmart_cppflags"
+AC_ARG_WITH([libatasmart],
+ [AS_HELP_STRING([--with-libatasmart@<:@=PREFIX@:>@], [Path to libatasmart.])],
+ [
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+ with_libatasmart_cppflags="-I$withval/include"
+ with_libatasmart_ldflags="-L$withval/lib"
+ with_libatasmart="yes"
+ else
+ with_libatasmart="$withval"
+ fi
+ ],
+ [
+ if test "x$ac_system" = "xLinux"; then
+ with_libatasmart="yes"
+ else
+ with_libatasmart="no (Linux only library)"
+ fi
+ ]
+)
- AC_CHECK_HEADERS(atasmart.h, [with_libatasmart="yes"], [with_libatasmart="no (atasmart.h not found)"])
+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)"])
- 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"
+
+ AC_CHECK_LIB([atasmart], [sk_disk_open],
+ [with_libatasmart="yes"],
+ [with_libatasmart="no (Symbol 'sk_disk_open' not found)"]
+ )
+
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
+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
-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")
+
+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
#
# 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)
[
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)
plugin_df="no"
plugin_disk="no"
plugin_drbd="no"
+plugin_dpdkevents="no"
plugin_dpdkstat="no"
plugin_entropy="no"
plugin_ethstat="no"
plugin_gps="no"
plugin_grpc="no"
plugin_hugepages="no"
+plugin_intel_pmu="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"
plugin_serial="no"
plugin_smart="no"
plugin_swap="no"
+plugin_synproxy="no"
plugin_tape="no"
plugin_tcpconns="no"
plugin_ted="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$have_cpuid_h" = "xyes"; then
- plugin_turbostat="yes"
- fi
-
- if test "x$c_cv_have_clock_boottime_monotonic" = "xyes"
- then
- plugin_cpusleep="yes"
- fi
-fi
-
-if test "x$ac_system" = "xOpenBSD"
-then
- plugin_tcpconns="yes"
+if test "x$ac_system" = "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_synproxy="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$ac_cv_header_linux_ip_vs_h" = "xyes"; then
+ plugin_ipvs="yes"
+ fi
+
+ if 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" = "xNetBSD"
-then
- plugin_disk="yes"
- plugin_entropy="yes"
- plugin_irq="yes"
- plugin_processes="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"
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"
+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"
-fi
-
-# libi2c-dev
-if test "x$ac_system" = "xLinux"
-then
-AC_CHECK_DECL(i2c_smbus_read_i2c_block_data,
- [with_libi2c="yes"],
- [with_libi2c="no (symbol i2c_smbus_read_i2c_block_data not found - have you installed libi2c-dev ?)"],
- [[#include <stdlib.h>
- #include <linux/i2c-dev.h>]])
-else
- with_libi2c="no (Linux only)"
+if test "x$with_devinfo" = "xyes" && test "x$with_kstat" = "xyes"; then
+ plugin_cpu="yes"
+ plugin_disk="yes"
+ plugin_interface="yes"
+ plugin_memory="yes"
+ plugin_tape="yes"
fi
-if test "x$with_libi2c" = "xyes"
-then
- plugin_barometer="yes"
+if test "x$with_libi2c" = "xyes"; then
+ plugin_barometer="yes"
fi
# libstatgrab
-if test "x$with_libstatgrab" = "xyes"
-then
- plugin_cpu="yes"
- plugin_disk="yes"
- plugin_interface="yes"
- plugin_load="yes"
- plugin_memory="yes"
- plugin_swap="yes"
- plugin_users="yes"
+if test "x$with_libstatgrab" = "xyes"; then
+ plugin_cpu="yes"
+ plugin_disk="yes"
+ plugin_interface="yes"
+ plugin_load="yes"
+ plugin_memory="yes"
+ plugin_swap="yes"
+ plugin_users="yes"
+fi
+
+if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"; then
+ plugin_ascent="yes"
+ if test "x$have_strptime" = "xyes"; then
+ plugin_bind="yes"
+ fi
fi
-if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"
-then
- plugin_ascent="yes"
- if test "x$have_strptime" = "xyes"
- then
- plugin_bind="yes"
- fi
+if test "x$with_libopenipmipthread" = "xyes"; then
+ plugin_ipmi="yes"
fi
-if test "x$with_libopenipmipthread" = "xyes"
-then
- plugin_ipmi="yes"
+if test "x$with_libcurl" = "xyes" && test "x$with_libyajl" = "xyes"; then
+ plugin_curl_json="yes"
fi
-if test "x$with_libcurl" = "xyes" && test "x$with_libyajl" = "xyes"
-then
- plugin_curl_json="yes"
+if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"; then
+ plugin_curl_xml="yes"
fi
-if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"
-then
- plugin_curl_xml="yes"
+if test "x$with_libyajl" = "xyes"; then
+ plugin_ceph="yes"
fi
-if test "x$with_libyajl" = "xyes"
-then
- plugin_ceph="yes"
+if test "x$have_processor_info" = "xyes"; then
+ plugin_cpu="yes"
fi
-if test "x$have_processor_info" = "xyes"
-then
- plugin_cpu="yes"
+if test "x$have_sysctl" = "xyes"; then
+ plugin_cpu="yes"
+ plugin_memory="yes"
+ plugin_uptime="yes"
+ if test "x$ac_system" = "xDarwin"; then
+ plugin_swap="yes"
+ fi
fi
-if test "x$have_sysctl" = "xyes"
-then
- plugin_cpu="yes"
- plugin_memory="yes"
- plugin_uptime="yes"
- if test "x$ac_system" = "xDarwin"
- then
- plugin_swap="yes"
- fi
-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
-fi
-
-if test "x$have_linux_sockios_h$have_linux_ethtool_h" = "xyesyes"
-then
- plugin_ethstat="yes"
+if test "x$plugin_df" = "xyes"; then
+ plugin_df="no"
+ if test "x$have_statfs" = "xyes"; then
+ plugin_df="yes"
+ fi
+
+ if test "x$have_statvfs" = "xyes"; then
+ plugin_df="yes"
+ fi
fi
-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$have_linux_sockios_h" = "xyes" && test "x$have_linux_ethtool_h" = "xyes"; then
+ plugin_ethstat="yes"
fi
-if test "x$have_getifaddrs" = "xyes"
-then
- plugin_interface="yes"
+if test "x$with_libgps" = "xyes"; then
+ plugin_gps="yes"
fi
-if test "x$with_libgps" = "xyes"
-then
- plugin_gps="yes"
+if test "x$with_libgrpcpp" = "xyes" && test "x$with_libprotobuf" = "xyes" && test "x$have_protoc3" = "xyes" && test "x$GRPC_CPP_PLUGIN" != "x"; then
+ plugin_grpc="yes"
fi
-if test "x$have_getloadavg" = "xyes"
-then
- plugin_load="yes"
+if test "x$have_getifaddrs" = "xyes"; then
+ plugin_interface="yes"
fi
-if test "x$with_libyajl" = "xyes"
-then
- plugin_log_logstash="yes"
+if test "x$have_getloadavg" = "xyes"; then
+ plugin_load="yes"
fi
-if test "x$c_cv_have_libperl$c_cv_have_perl_ithreads" = "xyesyes"
-then
- plugin_perl="yes"
+if test "x$with_libyajl" = "xyes"; then
+ plugin_log_logstash="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$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
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
+if test "x$with_libdpdk" = "xyes"; then
+ plugin_dpdkevents="$dpdk_keepalive"
plugin_dpdkstat="yes"
fi
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], [])
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])
AC_PLUGIN([grpc], [$plugin_grpc], [gRPC plugin])
AC_PLUGIN([hddtemp], [yes], [Query hddtempd])
AC_PLUGIN([hugepages], [$plugin_hugepages], [Hugepages statistics])
+AC_PLUGIN([intel_pmu], [$with_libjevents], [Intel performance monitor plugin])
AC_PLUGIN([intel_rdt], [$with_libpqos], [Intel RDT monitor plugin])
AC_PLUGIN([interface], [$plugin_interface], [Interface traffic statistics])
AC_PLUGIN([ipc], [$plugin_ipc], [IPC statistics])
AC_PLUGIN([match_timediff], [yes], [The timediff match])
AC_PLUGIN([match_value], [yes], [The value match])
AC_PLUGIN([mbmon], [yes], [Query mbmond])
+AC_PLUGIN([mcelog], [$plugin_mcelog], [Machine Check Exceptions notifications])
AC_PLUGIN([md], [$have_linux_raid_md_u_h], [md (Linux software RAID) devices])
AC_PLUGIN([memcachec], [$with_libmemcached], [memcachec statistics])
AC_PLUGIN([memcached], [yes], [memcached statistics])
AC_PLUGIN([openldap], [$with_libldap], [OpenLDAP statistics])
AC_PLUGIN([openvpn], [yes], [OpenVPN client statistics])
AC_PLUGIN([oracle], [$with_oracle], [Oracle plugin])
+AC_PLUGIN([ovs_events], [$plugin_ovs_events], [OVS events plugin])
+AC_PLUGIN([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.
AC_PLUGIN([sigrok], [$with_libsigrok], [sigrok acquisition sources])
AC_PLUGIN([smart], [$plugin_smart], [SMART statistics])
AC_PLUGIN([snmp], [$with_libnetsnmp], [SNMP querying plugin])
+AC_PLUGIN([snmp_agent], [$with_libnetsnmpagent], [SNMP agent plugin])
AC_PLUGIN([statsd], [yes], [StatsD plugin])
AC_PLUGIN([swap], [$plugin_swap], [Swap usage statistics])
+AC_PLUGIN([synproxy], [$plugin_synproxy], [Synproxy stats plugin])
AC_PLUGIN([syslog], [$have_syslog], [Syslog logging plugin])
AC_PLUGIN([table], [yes], [Parsing of tabular data])
AC_PLUGIN([tail], [yes], [Parsing of logfiles])
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"
+if test "x$enable_debug" = "xyes"; then
+ 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=""
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)
-
-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)"
-fi
-
-if test "x$ip_vs_h_needs_kernel_cflags" = "xyes"
-then
- enable_ipvs="$enable_ipvs (needs $KERNEL_CFLAGS)"
-fi
+AC_SUBST([LOAD_PLUGIN_RRDTOOL])
+AC_SUBST([LOAD_PLUGIN_NETWORK])
+AC_SUBST([LOAD_PLUGIN_CSV])
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"
-then
- AC_MSG_CHECKING([for the ExtUtils::MakeMaker module])
- if $PERL -MExtUtils::MakeMaker -e '' 2>/dev/null; then
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- with_perl_bindings="no (ExtUtils::MakeMaker not found)"
- fi
+if test "x$with_perl_bindings" = "xyes"; then
+ AC_MSG_CHECKING([for the ExtUtils::MakeMaker module])
+ if $PERL -MExtUtils::MakeMaker -e '' 2>/dev/null; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ with_perl_bindings="no (ExtUtils::MakeMaker not found)"
+ fi
fi
-if test "x$with_perl_bindings" = "xyes"
-then
- PERL_BINDINGS="perl"
+if test "x$with_perl_bindings" = "xyes"; then
+ 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`
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()
AC_MSG_RESULT([Configuration:])
AC_MSG_RESULT([ Build:])
AC_MSG_RESULT([ Platform . . . . . . $ac_system])
+AC_MSG_RESULT([ Compiler vendor . . . $ax_cv_c_compiler_vendor])
AC_MSG_RESULT([ CC . . . . . . . . . $CC])
AC_MSG_RESULT([ CFLAGS . . . . . . . $AM_CFLAGS $CFLAGS])
AC_MSG_RESULT([ CXXFLAGS . . . . . . $AM_CXXFLAGS $CXXFLAGS])
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])
AC_MSG_RESULT([ libiptc . . . . . . . $with_libiptc])
+AC_MSG_RESULT([ libjevents . . . . . $with_libjevents])
AC_MSG_RESULT([ libjvm . . . . . . . $with_java])
AC_MSG_RESULT([ libkstat . . . . . . $with_kstat])
AC_MSG_RESULT([ libkvm . . . . . . . $with_libkvm])
AC_MSG_RESULT([ libmysql . . . . . . $with_libmysql])
AC_MSG_RESULT([ libnetapp . . . . . . $with_libnetapp])
AC_MSG_RESULT([ libnetsnmp . . . . . $with_libnetsnmp])
+AC_MSG_RESULT([ libnetsnmpagent . . . $with_libnetsnmpagent])
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])
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])
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_pmu . . . . . . $enable_intel_pmu])
+AC_MSG_RESULT([ intel_rdt . . . . . . $enable_intel_rdt])
AC_MSG_RESULT([ interface . . . . . . $enable_interface])
AC_MSG_RESULT([ ipc . . . . . . . . . $enable_ipc])
AC_MSG_RESULT([ ipmi . . . . . . . . $enable_ipmi])
AC_MSG_RESULT([ match_timediff . . . $enable_match_timediff])
AC_MSG_RESULT([ match_value . . . . . $enable_match_value])
AC_MSG_RESULT([ mbmon . . . . . . . . $enable_mbmon])
+AC_MSG_RESULT([ mcelog . . . . . . . $enable_mcelog])
AC_MSG_RESULT([ md . . . . . . . . . $enable_md])
AC_MSG_RESULT([ memcachec . . . . . . $enable_memcachec])
AC_MSG_RESULT([ memcached . . . . . . $enable_memcached])
AC_MSG_RESULT([ openldap . . . . . . $enable_openldap])
AC_MSG_RESULT([ openvpn . . . . . . . $enable_openvpn])
AC_MSG_RESULT([ oracle . . . . . . . $enable_oracle])
+AC_MSG_RESULT([ ovs_events . . . . . $enable_ovs_events])
+AC_MSG_RESULT([ ovs_stats . . . . . . $enable_ovs_stats])
AC_MSG_RESULT([ perl . . . . . . . . $enable_perl])
AC_MSG_RESULT([ pf . . . . . . . . . $enable_pf])
AC_MSG_RESULT([ pinba . . . . . . . . $enable_pinba])
AC_MSG_RESULT([ sigrok . . . . . . . $enable_sigrok])
AC_MSG_RESULT([ smart . . . . . . . . $enable_smart])
AC_MSG_RESULT([ snmp . . . . . . . . $enable_snmp])
+AC_MSG_RESULT([ snmp_agent . . . . . $enable_snmp_agent])
AC_MSG_RESULT([ statsd . . . . . . . $enable_statsd])
AC_MSG_RESULT([ swap . . . . . . . . $enable_swap])
+AC_MSG_RESULT([ synproxy . . . . . . $enable_synproxy])
AC_MSG_RESULT([ syslog . . . . . . . $enable_syslog])
AC_MSG_RESULT([ table . . . . . . . . $enable_table])
AC_MSG_RESULT([ tail_csv . . . . . . $enable_tail_csv])
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 :
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)
--- /dev/null
+# Example configuration for PHP-FPM
+<Plugin "curl_json">
+ <URL "http://nginx-status/php-fpm-status?json">
+ Plugin "phpfpm"
+ Instance "main"
+ <Key "accepted conn">
+ Type "total_requests"
+ Instance "accepted"
+ </Key>
+ <Key "slow requests">
+ Type "total_requests"
+ Instance "slow"
+ </Key>
+ <Key "listen queue">
+ Type "queue_length"
+ Instance "listen"
+ </Key>
+ <Key "active processes">
+ Type "vs_processes"
+ Instance "active"
+ </Key>
+ <Key "total processes">
+ Type "vs_processes"
+ Instance "total"
+ </Key>
+ </URL>
+</Plugin>
--- /dev/null
+APT::Install-Recommends "0";
+APT::Install-Suggests "0";
+APT::Get::Assume-Yes "1";
+APT::Get::AutomaticRemove "1";
--- /dev/null
+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"]
--- /dev/null
+LoadPlugin logfile
+<Plugin logfile>
+ LogLevel "info"
+ File STDOUT
+ Timestamp true
+ PrintSeverity true
+</Plugin>
+
+LoadPlugin unixsock
+<Plugin unixsock>
+ SocketGroup "nogroup"
+</Plugin>
+
+<Include "/etc/collectd/collectd.conf.d">
+ Filter "*.conf"
+</Include>
--- /dev/null
+LoadPlugin cpu
+LoadPlugin memory
+LoadPlugin disk
+LoadPlugin df
--- /dev/null
+rootprefix.so
--- /dev/null
+rootfs_prefix.so: rootfs_prefix.c
+ $(CC) -Wall -Werror -fPIC -shared -o rootfs_prefix.so rootfs_prefix.c -ldl
--- /dev/null
+#define _GNU_SOURCE
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <error.h>
+#include <stdio.h>
+#include <string.h>
+
+#define PREFIX "/rootfs"
+#define BUFSIZE 256
+
+const char *add_prefix(const char *orig, char *prefixed) {
+ if ((strncmp(orig, "/proc", strlen("/proc")) != 0) &&
+ (strncmp(orig, "/sys", strlen("/sys")) != 0))
+ return orig;
+
+ int status = snprintf(prefixed, BUFSIZE, "%s%s", PREFIX, orig);
+ if (status < 1) {
+ error(status, errno, "adding '%s' prefix to file path failed: '%s' -> '%s'",
+ PREFIX, orig, prefixed);
+ return orig;
+ } else if ((unsigned int)status >= BUFSIZE) {
+ error(status, ENAMETOOLONG,
+ "'%s' got truncated when adding '%s' prefix: '%s'", orig, PREFIX,
+ prefixed);
+ return orig;
+ } else {
+ return (const char *)prefixed;
+ }
+}
+
+FILE *fopen(const char *path, const char *mode) {
+ char filename[BUFSIZE] = "\0";
+
+ FILE *(*original_fopen)(const char *, const char *);
+ original_fopen = dlsym(RTLD_NEXT, "fopen");
+
+ return (*original_fopen)(add_prefix(path, filename), mode);
+}
+
+DIR *opendir(const char *name) {
+ char filename[BUFSIZE] = "\0";
+
+ DIR *(*original_opendir)(const char *);
+ original_opendir = dlsym(RTLD_NEXT, "opendir");
+
+ return (*original_opendir)(add_prefix(name, filename));
+}
+
+int *open(const char *pathname, int flags) {
+ char filename[BUFSIZE] = "\0";
+
+ int *(*original_open)(const char *, int);
+ original_open = dlsym(RTLD_NEXT, "open");
+
+ return (*original_open)(add_prefix(pathname, filename), flags);
+}
--- /dev/null
+#!/bin/sh
+
+# This script sends files to a web service using POST requests and reads back
+# the correctly formatted source files. This allows to apply clang-format
+# without having to install the tool locally.
+
+if test $# -lt 1; then
+ echo "Usage $0 <file> [<file> ...]"
+ exit 1
+fi
+
+for i in "$@"; do
+ d="`dirname "${i}"`"
+ o="`TMPDIR="${d}" mktemp format.XXXXXX`"
+
+ curl --silent --data-binary "@-" https://format.collectd.org/ <"${i}" >"${o}"
+ if test $? -eq 0; then
+ cat "${o}" >"${i}"
+ fi
+ rm -f "${o}"
+done
#
# - fetch the desired collectd release file from https://collectd.org/files/
# and save it in your ~/rpmbuild/SOURCES/ directory (or build your own out of
-# the git repository: ./build.sh && ./configure && make-dist-bz2)
+# the git repository: ./build.sh && ./configure && make dist)
#
# - copy this file in your ~/rpmbuild/SPECS/ directory. Make sure the
# "Version:" tag matches the version from the tarball.
%define with_lvm 0%{!?_without_lvm:1}
%define with_madwifi 0%{!?_without_madwifi:1}
%define with_mbmon 0%{!?_without_mbmon:1}
+%define with_mcelog 0%{!?_without_mcelog:1}
%define with_md 0%{!?_without_md:1}
%define with_memcachec 0%{!?_without_memcachec:1}
%define with_memcached 0%{!?_without_memcached:1}
%define with_olsrd 0%{!?_without_olsrd:1}
%define with_openldap 0%{!?_without_openldap:1}
%define with_openvpn 0%{!?_without_openvpn:1}
+%define with_ovs_events 0%{!?_without_ovs_events:1}
+%define with_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}
%define with_serial 0%{!?_without_serial:1}
%define with_smart 0%{!?_without_smart:1}
%define with_snmp 0%{!?_without_snmp:1}
+%define with_snmp_agent 0%{!?_without_snmp_agent:1}
%define with_statsd 0%{!?_without_statsd:1}
%define with_swap 0%{!?_without_swap:1}
+%define with_synproxy 0%{!?_without_synproxy:0}
%define with_syslog 0%{!?_without_syslog:1}
%define with_table 0%{!?_without_table:1}
%define with_tail 0%{!?_without_tail:1}
%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_pmu disabled, requires libjevents
+%define with_intel_pmu 0%{!?_without_intel_pmu:0}
# plugin intel_rdt disabled, requires intel-cmt-cat
%define with_intel_rdt 0%{!?_without_intel_rdt:0}
# plugin mic disabled, requires Mic
%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
Summary: Statistics collection and monitoring daemon
Name: collectd
Version: 5.7.1
-Release: 3%{?dist}
+Release: 8%{?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 <collectd@verplant.org>
%if 0%{?fedora} || 0%{?rhel} >= 7
provided via SMART and queried by the external hddtemp daemon.
%endif
+%if %{with_intel_pmu}
+%package intel_pmu
+Summary: Intel PMU plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+%description intel_pmu
+The intel_pmu plugin reads performance counters provided by the Linux
+kernel perf interface.
+%endif
+
%if %{with_intel_rdt}
%package intel_rdt
Summary: Intel RDT plugin for collectd
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
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
This plugin for collectd allows querying of network equipment using SNMP.
%endif
+%if %{with_snmp_agent}
+%package snmp_agent
+Summary: SNMP AgentX plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: net-snmp-devel
+%description snmp_agent
+This plugin for collectd to support AgentX integration.
+%endif
+
%if %{with_varnish}
%package varnish
Summary: Varnish plugin for collectd
%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
%define _with_hugepages --disable-hugepages
%endif
+%if %{with_intel_pmu}
+%define _with_intel_pmu --enable-intel_pmu
+%else
+%define _with_intel_pmu --disable-intel_pmu
+%endif
+
%if %{with_intel_rdt}
%define _with_intel_rdt --enable-intel_rdt
%else
%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
%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
%define _with_snmp --disable-snmp
%endif
+%if %{with_snmp_agent}
+%define _with_snmp_agent --enable-snmp_agent
+%else
+%define _with_snmp_agent --disable-snmp_agent
+%endif
+
%if %{with_statsd}
%define _with_statsd --enable-statsd
%else
%define _with_swap --disable-swap
%endif
+%if %{with_synproxy}
+%define _with_synproxy --enable-synproxy
+%else
+%define _with_synproxy --disable-synproxy
+%endif
+
%if %{with_syslog}
%define _with_syslog --enable-syslog
%else
%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 \
%{?_with_disk} \
%{?_with_dns} \
%{?_with_drbd} \
+ %{?_with_dpdkevents} \
%{?_with_dpdkstat} \
%{?_with_email} \
%{?_with_entropy} \
%{?_with_grpc} \
%{?_with_hddtemp} \
%{?_with_hugepages} \
+ %{?_with_intel_pmu} \
%{?_with_intel_rdt} \
%{?_with_interface} \
%{?_with_ipc} \
%{?_with_lvm} \
%{?_with_madwifi} \
%{?_with_mbmon} \
+ %{?_with_mcelog} \
%{?_with_md} \
%{?_with_memcachec} \
%{?_with_memcached} \
%{?_with_openldap} \
%{?_with_openvpn} \
%{?_with_oracle} \
+ %{?_with_ovs_events} \
+ %{?_with_ovs_stats} \
%{?_with_perl} \
%{?_with_pf} \
%{?_with_pinba} \
%{?_with_sigrok} \
%{?_with_smart} \
%{?_with_snmp} \
+ %{?_with_snmp_agent} \
%{?_with_statsd} \
%{?_with_swap} \
+ %{?_with_synproxy} \
%{?_with_syslog} \
%{?_with_table} \
%{?_with_tail_csv} \
%if %{with_drbd}
%{_libdir}/%{name}/drbd.so
%endif
-%if %{with_dpdkstat}
-%{_libdir}/%{name}/dpdkstat.so
-%endif
%if %{with_ethstat}
%{_libdir}/%{name}/ethstat.so
%endif
%if %{with_mbmon}
%{_libdir}/%{name}/mbmon.so
%endif
+%if %{with_mcelog}
+%{_libdir}/%{name}/mcelog.so
+%endif
%if %{with_md}
%{_libdir}/%{name}/md.so
%endif
%if %{with_swap}
%{_libdir}/%{name}/swap.so
%endif
+%if %{with_synproxy}
+%{_libdir}/%{name}/synproxy.so
+%endif
%if %{with_syslog}
%{_libdir}/%{name}/syslog.so
%endif
%{_includedir}/collectd/network_buffer.h
%{_includedir}/collectd/lcc_features.h
%{_libdir}/pkgconfig/libcollectdclient.pc
+%{_includedir}/collectd/network_parse.h
+%{_includedir}/collectd/server.h
+%{_includedir}/collectd/types.h
%{_libdir}/libcollectdclient.so
%files -n libcollectdclient
%{_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
%{_libdir}/%{name}/hddtemp.so
%endif
+%if %{with_intel_pmu}
+%files intel_pmu
+%{_libdir}/%{name}/intel_pmu.so
+%endif
+
%if %{with_intel_rdt}
%files intel_rdt
%{_libdir}/%{name}/intel_rdt.so
%{_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
%{_libdir}/%{name}/snmp.so
%endif
+%if %{with_snmp_agent}
+%files snmp_agent
+%{_libdir}/%{name}/snmp_agent.so
+%endif
+
%if %{with_varnish}
%files varnish
%{_libdir}/%{name}/varnish.so
%doc contrib/
%changelog
-* Sun Mar 05 2017 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.1-2
+* Thu Sep 28 2017 xakru <calvinxakru@gmail.com> - 5.7.1-8
+- Add new libcollectdclient/network_parse
+- Add new libcollectdclient/server
+- Add new libcollectdclient/types
+- Add new synproxy plugin
+
+* Fri Aug 18 2017 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.1-7
+- Add new intel_pmu plugin
+
+* Sun Mar 05 2017 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.1-6
+- Move recently added plugins to subpackages
+
+* Sun Mar 05 2017 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.1-5
+- Add new ovs_stats plugin
+
+* Sun Mar 05 2017 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.1-4
- Don't enable XFS support on RHEL6, it is missing for i386
+* Sun Mar 05 2017 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.1-3
+- Add dpdkevents plugin, disabled by default
+
* Wed Feb 22 2017 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.1-2
- Enable XFS support in df plugin
- Fix bogus date in changelog
* Sun Jan 01 2017 Marc Fournier <marc.fournier@camptocamp.com> - 5.7.1-1
- New upstream version
+* Sat Dec 31 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.0-4
+- Add new ovs_events plugin
+
+* Sat Dec 31 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.0-3
+- Add new mcelog plugin
+
* Tue Nov 29 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.7.0-2
- Disable redis plugin on RHEL 6, hiredis has been retired from EPEL6
# ceph CAP_DAC_OVERRIDE
# dns CAP_NET_RAW
# exec CAP_SETUID CAP_SETGID
+# intel_rdt CAP_SYS_RAWIO
+# intel_pmu CAP_SYS_ADMIN
# iptables CAP_NET_ADMIN
# ping CAP_NET_RAW
# smart CAP_SYS_RAWIO
# By default, drop all capabilities:
CapabilityBoundingSet=
-# Tell systemd it will receive a notification from collectd over it's control
+# Tell systemd it will receive a notification from collectd over its control
# socket once the daemon is ready. See systemd.service(5) for more details.
Type=notify
* 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
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:
* 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
--- /dev/null
+Inside the virt plugin
+======================
+
+Originally written: 20161111
+
+Last updated: 20161124
+
+This document will explain the new domain tag support introduced
+in the virt plugin, and will provide one important use case for this feature.
+In the reminder of this document, we consider
+
+* libvirt <= 2.0.0
+* QEMU <= 2.6.0
+
+
+Domain tags and domains partitioning across virt reader instances
+-----------------------------------------------------------------
+
+The virt plugin gained the `Instances` option. It allows to start
+more than one reader instance, so the the libvirt domains could be queried
+by more than one reader thread.
+The default value for `Instances` is `1`.
+With default settings, the plugin will behave in a fully transparent,
+backward compatible way.
+It is recommended to set this value to one multiple of the
+daemon `ReadThreads` value.
+
+Each reader instance will query only a subset of the libvirt domain.
+The subset is identified as follows:
+
+1. Each virt reader instance is named `virt-$NUM`, where `NUM` is
+ the progressive order of instances. If you configure `Instances 3`
+ you will have `virt-0`, `virt-1`, `virt-2`. Please note: the `virt-0`
+ instance is special, and will always be available.
+2. Each virt reader instance will iterate over all the libvirt active domains,
+ and will look for one `tag` attribute (see below) in the domain metadata section.
+3. Each virt reader instance will take care *only* of the libvirt domains whose
+ tag matches with its own
+4. The special `virt-0` instance will take care of all the libvirt domains with
+ no tags, or with tags which are not in the set \[virt-0 ... virt-$NUM\]
+
+Collectd will just use the domain tags, but never enforces or requires them.
+It is up to an external entity, like a software management system,
+to attach and manage the tags to the domain.
+
+Please note that unless you have such tag-aware management sofware,
+it most likely make no sense to enable more than one reader instance on your
+setup.
+
+
+Libvirt tag metadata format
+----------------------------
+
+This is the snipped to be added to libvirt domains:
+
+ <ovirtmap:tag xmlns:ovirtmap="http://ovirt.org/ovirtmap/tag/1.0">
+ $TAG
+ </ovirtmap:tag>
+
+it must be included in the <metadata> section.
+
+Check the `src/virt_test.c` file for really minimal example of libvirt domains.
+
+
+Examples
+--------
+
+### Example one: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=5, using 5 different tags
+
+
+ libvirt domain name - tag - read instance - reason
+ domain-A virt-0 0 tag match
+ domain-B virt-1 1 tag match
+ domain-C virt-2 2 tag match
+ domain-D virt-3 3 tag match
+ domain-E virt-4 4 tag match
+ domain-F virt-0 0 tag match
+ domain-G virt-1 1 tag match
+ domain-H virt-2 2 tag match
+ domain-I virt-3 3 tag match
+ domain-J virt-4 4 tag match
+
+
+ Because the domain where properly tagged, all the read instances have even load. Please note that the the virt plugin
+ knows nothing, and should know nothing, about *how* the libvirt domain are tagged. This is entirely up to the
+ management system.
+
+
+Example two: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=3, using 5 different tags
+
+
+ libvirt domain name - tag - read instance - reason
+ domain-A virt-0 0 tag match
+ domain-B virt-1 1 tag match
+ domain-C virt-2 2 tag match
+ domain-D virt-3 0 adopted by instance #0
+ domain-E virt-4 0 adopted by instance #0
+ domain-F virt-0 0 rag match
+ domain-G virt-1 1 tag match
+ domain-H virt-2 2 tag match
+ domain-I virt-3 0 adopted by instance #0
+ domain-J virt-4 0 adopted by instance #0
+
+
+ In this case we have uneven load, but no domain is ignored.
+
+
+### Example three: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=5, using 3 different tags
+
+
+ libvirt domain name - tag - read instance - reason
+ domain-A virt-0 0 tag match
+ domain-B virt-1 1 tag match
+ domain-C virt-2 2 tag match
+ domain-D virt-0 0 tag match
+ domain-E virt-1 1 tag match
+ domain-F virt-2 2 tag match
+ domain-G virt-0 0 tag match
+ domain-H virt-1 1 tag match
+ domain-I virt-2 2 tag match
+ domain-J virt-0 0 tag match
+
+
+ Once again we have uneven load and two idle read instances, but besides that no domain is left unmonitored
+
+
+### Example four: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=5, partial tagging
+
+
+ libvirt domain name - tag - read instance - reason
+ domain-A virt-0 0 tag match
+ domain-B virt-1 1 tag match
+ domain-C virt-2 2 tag match
+ domain-D virt-0 0 tag match
+ domain-E 0 adopted by instance #0
+ domain-F 0 adopted by instance #0
+ domain-G 0 adopted by instance #0
+ domain-H 0 adopted by instance #0
+ domain-I 0 adopted by instance #0
+ domain-J 0 adopted by instance #0
+
+
+The lack of tags causes uneven load, but no domain are unmonitored.
+
+
+Possible extensions - custom tag format
+---------------------------------------
+
+The aformentioned approach relies on fixed tag format, `virt-$N`. The algorithm works fine with any tag, which
+is just one string, compared for equality. However, using custom strings for tags creates the need for a mapping
+between tags and the read instances.
+This mapping needs to be updated as long as domain are created or destroyed, and the virt plugin needs to be
+notified of the changes.
+
+This adds a significant amount of complexity, with little gain with respect to the fixed schema adopted initially.
+For this reason, the introdution of dynamic, custom mapping was not implemented.
+
+
+Dealing with datacenters: libvirt, qemu, shared storage
+-------------------------------------------------------
+
+When used in a datacenter, QEMU is most often configured to use shared storage. This is
+the default configuration of datacenter management solutions like [oVirt](http://www.ovirt.org).
+The actual shared storage could be implemented on top of NFS for small installations, or most likely
+ISCSI or Fiber Channel. The key takeaway is that the storage is accessed over the network,
+not using e.g. the SATA or PCI bus of any given host, so any network issue could cause
+one or more storage operations to delay, or to be lost entirely.
+
+In that case, the userspace process that requested the operation can end up in the D state,
+and become unresponsive, and unkillable.
+
+
+Dealing with unresponsive domains
+---------------------------------
+
+All the above considered, one robust management or monitoring application must deal with the fact that
+the libvirt API can block for a long time, or forever. This is not an issue or a bug of one specific
+API, but it is rather a byproduct of how libvirt and QEMU interact.
+
+Whenever we query more than one VM, we should take care to avoid that one blocked VM prevent other,
+well behaving VMs to be queried. We don't want one rogue VM to disrupt well-behaving VMs.
+Unfortunately, any way we enumerate VMs, either implicitely, using the libvirt bulk stats API,
+or explicitely, listing all libvirt domains and query each one in turn, we may unpredictably encounter
+one unresponsive VM.
+
+There are many possible approaches to deal with this issue. The virt plugin supports
+a simple but effective approach partitioning the domains, as follows.
+
+1. The virt plugin always register one or more `read` callbacks. The `zero` read callback is guaranteed to
+ be always present, so it performs special duties (more details later)
+ Each callback will be named 'virt-$N', where `N` ranges from 0 (zero) to M-1, where M is the number of instances configured.
+ `M` equals to `5` by default, because this is the same default number of threads in the libvirt worker pool.
+2. Each of the read callbacks queries libvirt for the list of all the active domains, and retrieves the libvirt domain metadata.
+ Both of those operations are safe wrt domain blocked in I/O (they affect only the libvirtd daemon).
+3. Each of the read callbacks extracts the `tag` from the domain metadata using a well-known format (see below).
+ Each of the read callbacks discards any domain which has no tag, or whose tag doesn't match with the read callback tag.
+3.a. The read callback tag equals to the read callback name, thus `virt-$N`. Remember that `virt-0` is guaranteed to be
+ always present.
+3.b. Since the `virt-0` reader is always present, it will take care of domains with no tag, or with unrecognized tag.
+ One unrecognized tag is any tag which has not the scheme `virt-$N`.
+4. Each read callback only samples the subset of domains with matching tag. The `virt-0` reader will possibly do more,
+ but worst case the load will be unbalanced, no domain will be left unsampled.
+
+To make this approach work, some entity must attach the tags to the libvirt domains, in such a way that all
+the domains which run on a given host and insist on the same network-based storage share the same tag.
+This minimizes the disruption, because when using the shared storage, if one domain becomes unresponsive because
+of unavailable storage, the most likely thing to happen is that others domain using the same storage will soon become
+unavailable; should the box run other libvirt domains using other network-based storage, they could be monitored
+safely.
+
+In case of [oVirt](http://www.ovirt.org), the aforementioned tagging is performed by the host agent.
+
+Please note that this approach is ineffective if the host completely lose network access to the storage network.
+In this case, however, no recovery is possible and no damage limitation is possible.
+
+Lastly, please note that if the virt plugin is configured with instances=1, it behaves exactly like before.
+
+
+Addendum: high level overview: libvirt client, libvirt daemon, qemu
+--------------------------------------------------------------------
+
+Let's review how the client application (collectd + virt plugin), the libvirtd daemon and the
+QEMU processes interact with each other.
+
+The libvirt daemon talks to QEMU using the JSON QMP protcol over one unix domain socket.
+The details of the protocol are not important now, but the key part is that the protocol
+is a simple request/response, meaning that libvirtd must serialize all the interactions
+with the QEMU monitor, and must protects its endpoint with a lock.
+No out of order request/responses are possible (e.g. no pipelining or async replies).
+This means that if for any reason one QMP request could not be completed, any other caller
+trying to access the QEMU monitor will block until the blocked caller returns.
+
+To retrieve some key informations, most notably about the block device state or the balloon
+device state, the libvirtd daemon *must* use the QMP protocol.
+
+The QEMU core, including the handling of the QMP protocol, is single-threaded.
+All the above combined make it possible for a client to block forever waiting for one QMP
+request, if QEMU itself is blocked. The most likely cause of block is I/O, and this is especially
+true considering how QEMU is used in a datacenter.
+
--- /dev/null
+## Maintainer Guide
+
+This document documents best practises and guidelines for *collectd*
+maintainers.
+
+### Ideology
+
+As maintainer of an open-source project, you are one of the most knowledgable
+people of the project's structure, best practices, goals, etc. You are most
+helping the project by *facilitating change*, in other words "help contributors
+make changes to the codebase."
+
+The most common form of helping users is doing *code reviews* and (eventually)
+using your commit rights to merge the pull request.
+
+### Code reviews
+
+* Be friendly, especially with new contributors. Write "Hi" and thank them for their contribution before diving into review comments.
+* Criticize code, not people. Ideally, tell the contributor a better way to do what they need.
+* Clearly mark optional suggestions as such. Best practise, start your comment with *At your option: …*
+* Wait for a successful run of our [continuous integration system](https://ci.collectd.org/) before merging.
+
+### Repository access
+
+You have write access to the *collectd/collectd* repository. Please use it
+responsibly.
+
+#### Own work
+
+Open *pull requests* for your own changes, too:
+
+* For simple changes it's okay to self-approve and merge after a
+ successful build on the CI systems.
+* Trivial changes, cherry-picks from *master* and roll-up merges are
+ excempt and may be pushed to the version branches and *master* directly.
+* "Simple" and "trivial" are not further defined; use your best judgement.
+ We'll revisit this if and when it becomes necessary.
--- /dev/null
+!.gitignore
--- /dev/null
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_compare_version.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+#
+# DESCRIPTION
+#
+# This macro compares two version strings. Due to the various number of
+# minor-version numbers that can exist, and the fact that string
+# comparisons are not compatible with numeric comparisons, this is not
+# necessarily trivial to do in a autoconf script. This macro makes doing
+# these comparisons easy.
+#
+# The six basic comparisons are available, as well as checking equality
+# limited to a certain number of minor-version levels.
+#
+# The operator OP determines what type of comparison to do, and can be one
+# of:
+#
+# eq - equal (test A == B)
+# ne - not equal (test A != B)
+# le - less than or equal (test A <= B)
+# ge - greater than or equal (test A >= B)
+# lt - less than (test A < B)
+# gt - greater than (test A > B)
+#
+# Additionally, the eq and ne operator can have a number after it to limit
+# the test to that number of minor versions.
+#
+# eq0 - equal up to the length of the shorter version
+# ne0 - not equal up to the length of the shorter version
+# eqN - equal up to N sub-version levels
+# neN - not equal up to N sub-version levels
+#
+# When the condition is true, shell commands ACTION-IF-TRUE are run,
+# otherwise shell commands ACTION-IF-FALSE are run. The environment
+# variable 'ax_compare_version' is always set to either 'true' or 'false'
+# as well.
+#
+# Examples:
+#
+# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
+# AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
+#
+# would both be true.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
+# AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
+#
+# would both be false.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
+#
+# would be true because it is only comparing two minor versions.
+#
+# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
+#
+# would be true because it is only comparing the lesser number of minor
+# versions of the two values.
+#
+# Note: The characters that separate the version numbers do not matter. An
+# empty string is the same as version 0. OP is evaluated by autoconf, not
+# configure, so must be a string, not a variable.
+#
+# The author would like to acknowledge Guido Draheim whose advice about
+# the m4_case and m4_ifvaln functions make this macro only include the
+# portions necessary to perform the specific comparison specified by the
+# OP argument in the final configure script.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 12
+
+dnl #########################################################################
+AC_DEFUN([AX_COMPARE_VERSION], [
+ AC_REQUIRE([AC_PROG_AWK])
+
+ # Used to indicate true or false condition
+ ax_compare_version=false
+
+ # Convert the two version strings to be compared into a format that
+ # allows a simple string comparison. The end result is that a version
+ # string of the form 1.12.5-r617 will be converted to the form
+ # 0001001200050617. In other words, each number is zero padded to four
+ # digits, and non digits are removed.
+ AS_VAR_PUSHDEF([A],[ax_compare_version_A])
+ A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/[[^0-9]]//g'`
+
+ AS_VAR_PUSHDEF([B],[ax_compare_version_B])
+ B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+ -e 's/[[^0-9]]//g'`
+
+ dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
+ dnl # then the first line is used to determine if the condition is true.
+ dnl # The sed right after the echo is to remove any indented white space.
+ m4_case(m4_tolower($2),
+ [lt],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+ ],
+ [gt],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+ ],
+ [le],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+ ],
+ [ge],[
+ ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+ ],[
+ dnl Split the operator from the subversion count if present.
+ m4_bmatch(m4_substr($2,2),
+ [0],[
+ # A count of zero means use the length of the shorter version.
+ # Determine the number of characters in A and B.
+ ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
+ ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
+
+ # Set A to no more than B's length and B to no more than A's length.
+ A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
+ B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
+ ],
+ [[0-9]+],[
+ # A count greater than zero means use only that many subversions
+ A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+ B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+ ],
+ [.+],[
+ AC_WARNING(
+ [illegal OP numeric parameter: $2])
+ ],[])
+
+ # Pad zeros at end of numbers to make same length.
+ ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
+ B="$B`echo $A | sed 's/./0/g'`"
+ A="$ax_compare_version_tmp_A"
+
+ # Check for equality or inequality as necessary.
+ m4_case(m4_tolower(m4_substr($2,0,2)),
+ [eq],[
+ test "x$A" = "x$B" && ax_compare_version=true
+ ],
+ [ne],[
+ test "x$A" != "x$B" && ax_compare_version=true
+ ],[
+ AC_WARNING([illegal OP parameter: $2])
+ ])
+ ])
+
+ AS_VAR_POPDEF([A])dnl
+ AS_VAR_POPDEF([B])dnl
+
+ dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
+ if test "$ax_compare_version" = "true" ; then
+ m4_ifvaln([$4],[$4],[:])dnl
+ m4_ifvaln([$5],[else $5])dnl
+ fi
+]) dnl AX_COMPARE_VERSION
--- /dev/null
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_COMPILER_VENDOR
+#
+# DESCRIPTION
+#
+# Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun,
+# hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft,
+# watcom, etc. The vendor is returned in the cache variable
+# $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
+# Copyright (c) 2008 Matteo Frigo
+#
+# 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, either version 3 of the License, or (at your
+# option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 15
+
+AC_DEFUN([AX_COMPILER_VENDOR],
+[AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
+ dnl Please add if possible support to ax_compiler_version.m4
+ [# note: don't check for gcc first since some other compilers define __GNUC__
+ vendors="intel: __ICC,__ECC,__INTEL_COMPILER
+ ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__
+ pathscale: __PATHCC__,__PATHSCALE__
+ clang: __clang__
+ cray: _CRAYC
+ fujitsu: __FUJITSU
+ gnu: __GNUC__
+ sun: __SUNPRO_C,__SUNPRO_CC
+ hp: __HP_cc,__HP_aCC
+ dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER
+ borland: __BORLANDC__,__CODEGEARC__,__TURBOC__
+ comeau: __COMO__
+ kai: __KCC
+ lcc: __LCC__
+ sgi: __sgi,sgi
+ microsoft: _MSC_VER
+ metrowerks: __MWERKS__
+ watcom: __WATCOMC__
+ portland: __PGI
+ tcc: __TINYC__
+ unknown: UNKNOWN"
+ for ventest in $vendors; do
+ case $ventest in
+ *:) vendor=$ventest; continue ;;
+ *) vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" ;;
+ esac
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
+ #if !($vencpp)
+ thisisanerror;
+ #endif
+ ])], [break])
+ done
+ ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1`
+ ])
+])
+++ /dev/null
-EXTRA_DIST = collectd.proto types.proto prometheus.proto
string type_instance = 5;
}
+message MetadataValue {
+ oneof value {
+ string string_value = 1;
+ int64 int64_value = 2;
+ uint64 uint64_value = 3;
+ double double_value = 4;
+ bool bool_value = 5;
+ };
+}
+
message Value {
oneof value {
uint64 counter = 1;
Identifier identifier = 4;
repeated string ds_names = 5;
-}
+ map<string, MetadataValue> meta_data = 6;
+}
\ No newline at end of file
+++ /dev/null
-SUBDIRS = libcollectdclient
-if BUILD_WITH_OWN_LIBOCONFIG
-SUBDIRS += liboconfig
-endif
-SUBDIRS += daemon
-
-PLUGIN_LDFLAGS = -module -avoid-version -export-symbols-regex '\<module_register\>'
-
-AM_CPPFLAGS = -I$(srcdir)/daemon
-AM_CPPFLAGS += -DPREFIX='"${prefix}"'
-AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"'
-AM_CPPFLAGS += -DLOCALSTATEDIR='"${localstatedir}"'
-AM_CPPFLAGS += -DPKGLOCALSTATEDIR='"${localstatedir}/lib/${PACKAGE_NAME}"'
-if BUILD_FEATURE_DAEMON
-AM_CPPFLAGS += -DPIDFILE='"${localstatedir}/run/${PACKAGE_NAME}.pid"'
-endif
-AM_CPPFLAGS += -DPLUGINDIR='"${pkglibdir}"'
-AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"'
-
-LOG_COMPILER = env VALGRIND="@VALGRIND@" $(abs_top_srcdir)/testwrapper.sh
-
-V_PROTOC = $(v_protoc_@AM_V@)
-v_protoc_ = $(v_protoc_@AM_DEFAULT_V@)
-v_protoc_0 = @echo " PROTOC " $@;
-
-noinst_LTLIBRARIES =
-check_PROGRAMS =
-TESTS =
-
-noinst_LTLIBRARIES += libformat_graphite.la
-libformat_graphite_la_SOURCES = utils_format_graphite.c utils_format_graphite.h
-libformat_graphite_la_CPPFLAGS = $(AM_CPPFLAGS)
-libformat_graphite_la_LDFLAGS = $(AM_LDFLAGS)
-check_PROGRAMS += test_format_graphite
-TESTS += test_format_graphite
-test_format_graphite_SOURCES = utils_format_graphite_test.c testing.h
-test_format_graphite_LDADD = libformat_graphite.la daemon/libmetadata.la daemon/libplugin_mock.la -lm
-
-noinst_LTLIBRARIES += libformat_json.la
-libformat_json_la_SOURCES = utils_format_json.c utils_format_json.h
-libformat_json_la_CPPFLAGS = $(AM_CPPFLAGS)
-libformat_json_la_LDFLAGS = $(AM_LDFLAGS)
-libformat_json_la_LIBADD =
-if BUILD_WITH_LIBYAJL
-libformat_json_la_CPPFLAGS += $(BUILD_WITH_LIBYAJL_CPPFLAGS)
-libformat_json_la_LDFLAGS += $(BUILD_WITH_LIBYAJL_LDFLAGS)
-libformat_json_la_LIBADD += $(BUILD_WITH_LIBYAJL_LIBS)
-check_PROGRAMS += test_format_json
-TESTS += test_format_json
-test_format_json_SOURCES = utils_format_json_test.c testing.h
-test_format_json_LDADD = libformat_json.la daemon/libmetadata.la daemon/libplugin_mock.la -lm
-endif
-
-noinst_LTLIBRARIES += liblatency.la
-liblatency_la_SOURCES = utils_latency.c utils_latency.h utils_latency_config.c utils_latency_config.h
-liblatency_la_LIBADD = daemon/libcommon.la -lm
-check_PROGRAMS += test_utils_latency
-TESTS += test_utils_latency
-test_utils_latency_SOURCES = utils_latency_test.c testing.h
-test_utils_latency_LDADD = liblatency.la daemon/libplugin_mock.la -lm
-
-noinst_LTLIBRARIES += libcmds.la
-libcmds_la_SOURCES = utils_cmds.c utils_cmds.h \
- utils_cmd_flush.c utils_cmd_flush.h \
- utils_cmd_getthreshold.c utils_cmd_getthreshold.h \
- utils_cmd_getval.c utils_cmd_getval.h \
- utils_cmd_listval.c utils_cmd_listval.h \
- utils_cmd_putnotif.c utils_cmd_putnotif.h \
- utils_cmd_putval.c utils_cmd_putval.h \
- utils_parse_option.c utils_parse_option.h
-libcmds_la_LIBADD = daemon/libcommon.la daemon/libmetadata.la -lm
-check_PROGRAMS += test_utils_cmds
-TESTS += test_utils_cmds
-test_utils_cmds_SOURCES = utils_cmds_test.c testing.h
-test_utils_cmds_LDADD = libcmds.la \
- daemon/libplugin_mock.la
-
-noinst_LTLIBRARIES += liblookup.la
-liblookup_la_SOURCES = utils_vl_lookup.c utils_vl_lookup.h
-liblookup_la_LIBADD = daemon/libavltree.la
-check_PROGRAMS += test_utils_vl_lookup
-TESTS += test_utils_vl_lookup
-test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h
-test_utils_vl_lookup_LDADD = liblookup.la daemon/libplugin_mock.la
-if BUILD_WITH_LIBKSTAT
-test_utils_vl_lookup_LDADD += -lkstat
-endif
-
-noinst_LTLIBRARIES += libmount.la
-libmount_la_SOURCES = utils_mount.c utils_mount.h
-check_PROGRAMS += test_utils_mount
-TESTS += test_utils_mount
-test_utils_mount_SOURCES = utils_mount_test.c testing.h
-test_utils_mount_LDADD = libmount.la daemon/libplugin_mock.la
-if BUILD_WITH_LIBKSTAT
-test_utils_mount_LDADD += -lkstat
-endif
-
-sbin_PROGRAMS = collectdmon
-bin_PROGRAMS = collectd-nagios collectdctl collectd-tg
-
-collectdmon_SOURCES = collectdmon.c
-
-collectd_nagios_SOURCES = collectd-nagios.c
-collectd_nagios_CPPFLAGS = $(AM_CPPFLAGS) \
- -I$(top_srcdir)/src/libcollectdclient/collectd \
- -I$(top_builddir)/src/libcollectdclient/collectd
-collectd_nagios_LDADD = libcollectdclient/libcollectdclient.la
-if BUILD_WITH_LIBSOCKET
-collectd_nagios_LDADD += -lsocket
-endif
-if BUILD_AIX
-collectd_nagios_LDADD += -lm
-endif
-
-
-collectdctl_SOURCES = collectdctl.c
-collectdctl_CPPFLAGS = $(AM_CPPFLAGS) \
- -I$(top_srcdir)/src/libcollectdclient/collectd \
- -I$(top_builddir)/src/libcollectdclient/collectd
-collectdctl_LDADD = libcollectdclient/libcollectdclient.la
-if BUILD_WITH_LIBSOCKET
-collectdctl_LDADD += -lsocket
-endif
-if BUILD_AIX
-collectdctl_LDADD += -lm
-endif
-
-
-collectd_tg_SOURCES = collectd-tg.c
-collectd_tg_CPPFLAGS = $(AM_CPPFLAGS) \
- -I$(top_srcdir)/src/libcollectdclient/collectd \
- -I$(top_builddir)/src/libcollectdclient/collectd
-collectd_tg_LDADD = \
- $(PTHREAD_LIBS) \
- daemon/libheap.la \
- libcollectdclient/libcollectdclient.la
-if BUILD_WITH_LIBSOCKET
-collectd_tg_LDADD += -lsocket
-endif
-if BUILD_WITH_LIBRT
-collectd_tg_LDADD += -lrt
-endif
-if BUILD_AIX
-collectd_tg_LDADD += -lm
-endif
-
-
-pkglib_LTLIBRARIES =
-
-BUILT_SOURCES =
-CLEANFILES =
-
-if HAVE_PROTOC3
-if HAVE_GRPC_CPP
-BUILT_SOURCES += collectd.grpc.pb.cc collectd.pb.cc types.pb.cc
-CLEANFILES += collectd.grpc.pb.cc collectd.pb.cc types.pb.cc \
- collectd.grpc.pb.h collectd.pb.h types.pb.h
-
-collectd.grpc.pb.cc: $(top_srcdir)/proto/collectd.proto $(top_srcdir)/proto/types.proto
- $(V_PROTOC)@PROTOC@ -I$(top_srcdir)/proto \
- --grpc_out=$(builddir) --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN) $<
-
-collectd.pb.cc: $(top_srcdir)/proto/collectd.proto $(top_srcdir)/proto/types.proto
- $(V_PROTOC)@PROTOC@ -I$(top_srcdir)/proto --cpp_out=$(builddir) $<
-
-types.pb.cc: $(top_srcdir)/proto/types.proto
- $(V_PROTOC)@PROTOC@ -I$(top_srcdir)/proto --cpp_out=$(builddir) $<
-endif
-endif
-
-if BUILD_PLUGIN_AGGREGATION
-pkglib_LTLIBRARIES += aggregation.la
-aggregation_la_SOURCES = aggregation.c \
- utils_vl_lookup.c utils_vl_lookup.h
-aggregation_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-aggregation_la_LIBADD = -lm
-endif
-
-if BUILD_PLUGIN_AMQP
-pkglib_LTLIBRARIES += amqp.la
-amqp_la_SOURCES = amqp.c
-amqp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
-amqp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRABBITMQ_CPPFLAGS)
-amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS) \
- libcmds.la libformat_graphite.la libformat_json.la
-endif
-
-if BUILD_PLUGIN_APACHE
-pkglib_LTLIBRARIES += apache.la
-apache_la_SOURCES = apache.c
-apache_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-apache_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
-apache_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS)
-endif
-
-
-if BUILD_PLUGIN_APCUPS
-pkglib_LTLIBRARIES += apcups.la
-apcups_la_SOURCES = apcups.c
-apcups_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-apcups_la_LIBADD =
-if BUILD_WITH_LIBSOCKET
-apcups_la_LIBADD += -lsocket
-endif
-endif
-
-if BUILD_PLUGIN_APPLE_SENSORS
-pkglib_LTLIBRARIES += apple_sensors.la
-apple_sensors_la_SOURCES = apple_sensors.c
-apple_sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) -framework IOKit
-endif
-
-if BUILD_PLUGIN_AQUAERO
-pkglib_LTLIBRARIES += aquaero.la
-aquaero_la_SOURCES = aquaero.c
-aquaero_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBAQUAERO5_CFLAGS)
-aquaero_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBAQUAERO5_LDFLAGS)
-aquaero_la_LIBADD = -laquaero5
-endif
-
-if BUILD_PLUGIN_ASCENT
-pkglib_LTLIBRARIES += ascent.la
-ascent_la_SOURCES = ascent.c
-ascent_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-ascent_la_CFLAGS = $(AM_CFLAGS) \
- $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
-ascent_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
-endif
-
-if BUILD_PLUGIN_BAROMETER
-pkglib_LTLIBRARIES += barometer.la
-barometer_la_SOURCES = barometer.c
-barometer_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-barometer_la_LIBADD = -lm
-endif
-
-if BUILD_PLUGIN_BATTERY
-pkglib_LTLIBRARIES += battery.la
-battery_la_SOURCES = battery.c battery_statefs.c
-battery_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-if BUILD_WITH_LIBIOKIT
-battery_la_LDFLAGS += -framework IOKit
-endif
-endif
-
-if BUILD_PLUGIN_BIND
-pkglib_LTLIBRARIES += bind.la
-bind_la_SOURCES = bind.c
-bind_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-bind_la_CFLAGS = $(AM_CFLAGS) \
- $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
-bind_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
-endif
-
-if BUILD_PLUGIN_CEPH
-pkglib_LTLIBRARIES += ceph.la
-ceph_la_SOURCES = ceph.c
-ceph_la_CFLAGS = $(AM_CFLAGS)
-ceph_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
-ceph_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
-ceph_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS)
-endif
-
-if BUILD_PLUGIN_CGROUPS
-pkglib_LTLIBRARIES += cgroups.la
-cgroups_la_SOURCES = cgroups.c
-cgroups_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-cgroups_la_LIBADD = libmount.la
-endif
-
-if BUILD_PLUGIN_CHRONY
-pkglib_LTLIBRARIES += chrony.la
-chrony_la_SOURCES = chrony.c
-chrony_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-chrony_la_LIBADD = -lm
-endif
-
-if BUILD_PLUGIN_CONNTRACK
-pkglib_LTLIBRARIES += conntrack.la
-conntrack_la_SOURCES = conntrack.c
-conntrack_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_CONTEXTSWITCH
-pkglib_LTLIBRARIES += contextswitch.la
-contextswitch_la_SOURCES = contextswitch.c
-contextswitch_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-contextswitch_la_LIBADD =
-if BUILD_WITH_PERFSTAT
-contextswitch_la_LIBADD += -lperfstat
-endif
-endif
-
-if BUILD_PLUGIN_CPU
-pkglib_LTLIBRARIES += cpu.la
-cpu_la_SOURCES = cpu.c
-cpu_la_CFLAGS = $(AM_CFLAGS)
-cpu_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-cpu_la_LIBADD =
-if BUILD_WITH_LIBKSTAT
-cpu_la_LIBADD += -lkstat
-endif
-if BUILD_WITH_LIBDEVINFO
-cpu_la_LIBADD += -ldevinfo
-endif
-if BUILD_WITH_LIBSTATGRAB
-cpu_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
-cpu_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
-endif
-if BUILD_WITH_PERFSTAT
-cpu_la_LIBADD += -lperfstat
-endif
-endif
-
-if BUILD_PLUGIN_CPUFREQ
-pkglib_LTLIBRARIES += cpufreq.la
-cpufreq_la_SOURCES = cpufreq.c
-cpufreq_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_CPUSLEEP
-pkglib_LTLIBRARIES += cpusleep.la
-cpusleep_la_SOURCES = cpusleep.c
-cpusleep_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_CSV
-pkglib_LTLIBRARIES += csv.la
-csv_la_SOURCES = csv.c
-csv_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_CURL
-pkglib_LTLIBRARIES += curl.la
-curl_la_SOURCES = curl.c \
- utils_curl_stats.c utils_curl_stats.h \
- utils_match.c utils_match.h
-curl_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-curl_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
-curl_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) liblatency.la
-endif
-
-if BUILD_PLUGIN_CURL_JSON
-pkglib_LTLIBRARIES += curl_json.la
-curl_json_la_SOURCES = curl_json.c \
- utils_curl_stats.c utils_curl_stats.h
-curl_json_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
-curl_json_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
-curl_json_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
-curl_json_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBYAJL_LIBS)
-endif
-
-if BUILD_PLUGIN_CURL_XML
-pkglib_LTLIBRARIES += curl_xml.la
-curl_xml_la_SOURCES = curl_xml.c \
- utils_curl_stats.c utils_curl_stats.h
-curl_xml_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-curl_xml_la_CFLAGS = $(AM_CFLAGS) \
- $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
-curl_xml_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
-endif
-
-if BUILD_PLUGIN_DBI
-pkglib_LTLIBRARIES += dbi.la
-dbi_la_SOURCES = dbi.c \
- utils_db_query.c utils_db_query.h
-dbi_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBDBI_CPPFLAGS)
-dbi_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBDBI_LDFLAGS)
-dbi_la_LIBADD = $(BUILD_WITH_LIBDBI_LIBS)
-endif
-
-if BUILD_PLUGIN_DF
-pkglib_LTLIBRARIES += df.la
-df_la_SOURCES = df.c
-df_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-df_la_LIBADD = libmount.la
-endif
-
-if BUILD_PLUGIN_DISK
-pkglib_LTLIBRARIES += disk.la
-disk_la_SOURCES = disk.c
-disk_la_CFLAGS = $(AM_CFLAGS)
-disk_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-disk_la_LIBADD =
-if BUILD_WITH_LIBKSTAT
-disk_la_LIBADD += -lkstat
-endif
-if BUILD_WITH_LIBDEVINFO
-disk_la_LIBADD += -ldevinfo
-endif
-if BUILD_WITH_LIBIOKIT
-disk_la_LDFLAGS += -framework IOKit
-endif
-if BUILD_WITH_LIBSTATGRAB
-disk_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
-disk_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
-endif
-if BUILD_WITH_LIBUDEV
-disk_la_CFLAGS += $(BUILD_WITH_LIBUDEV_CFLAGS)
-disk_la_LDFLAGS += $(BUILD_WITH_LIBUDEV_LDFLAGS)
-disk_la_LIBADD += $(BUILD_WITH_LIBUDEV_LIBS)
-endif
-if BUILD_FREEBSD
-disk_la_LIBADD += -ldevstat -lgeom
-endif
-if BUILD_WITH_PERFSTAT
-disk_la_LIBADD += -lperfstat
-endif
-endif
-
-if BUILD_PLUGIN_DNS
-pkglib_LTLIBRARIES += dns.la
-dns_la_SOURCES = dns.c utils_dns.c utils_dns.h
-dns_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-dns_la_LIBADD = -lpcap
-endif
-
-if BUILD_PLUGIN_DPDKSTAT
-pkglib_LTLIBRARIES += dpdkstat.la
-dpdkstat_la_SOURCES = dpdkstat.c
-dpdkstat_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDPDK_CPPFLAGS)
-dpdkstat_la_CFLAGS = $(AM_CFLAGS) $(LIBDPDK_CFLAGS)
-dpdkstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS)
-dpdkstat_la_LIBADD = $(LIBDPDK_LIBS)
-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 \
- msr-index.h
-turbostat_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_UNIXSOCK
-pkglib_LTLIBRARIES += unixsock.la
-unixsock_la_SOURCES = unixsock.c
-unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-unixsock_la_LIBADD = libcmds.la
-endif
-
-if BUILD_PLUGIN_UPTIME
-pkglib_LTLIBRARIES += uptime.la
-uptime_la_SOURCES = uptime.c
-uptime_la_CFLAGS = $(AM_CFLAGS)
-uptime_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-uptime_la_LIBADD =
-if BUILD_WITH_LIBKSTAT
-uptime_la_LIBADD += -lkstat
-endif
-if BUILD_WITH_PERFSTAT
-uptime_la_LIBADD += -lperfstat
-endif
-endif
-
-if BUILD_PLUGIN_USERS
-pkglib_LTLIBRARIES += users.la
-users_la_SOURCES = users.c
-users_la_CFLAGS = $(AM_CFLAGS)
-users_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-users_la_LIBADD =
-if BUILD_WITH_LIBSTATGRAB
-users_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS)
-users_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS)
-endif
-endif
-
-if BUILD_PLUGIN_UUID
-pkglib_LTLIBRARIES += uuid.la
-uuid_la_SOURCES = uuid.c
-uuid_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBHAL_CFLAGS)
-uuid_la_LIBADD = $(BUILD_WITH_LIBHAL_LIBS)
-uuid_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_VARNISH
-pkglib_LTLIBRARIES += varnish.la
-varnish_la_SOURCES = varnish.c
-varnish_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-varnish_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBVARNISH_CFLAGS)
-varnish_la_LIBADD = $(BUILD_WITH_LIBVARNISH_LIBS)
-endif
-
-if BUILD_PLUGIN_VIRT
-pkglib_LTLIBRARIES += virt.la
-virt_la_SOURCES = virt.c
-virt_la_CFLAGS = $(AM_CFLAGS) \
- $(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
-virt_la_LIBADD = $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
-virt_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_VMEM
-pkglib_LTLIBRARIES += vmem.la
-vmem_la_SOURCES = vmem.c
-vmem_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_VSERVER
-pkglib_LTLIBRARIES += vserver.la
-vserver_la_SOURCES = vserver.c
-vserver_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_WIRELESS
-pkglib_LTLIBRARIES += wireless.la
-wireless_la_SOURCES = wireless.c
-wireless_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_WRITE_GRAPHITE
-pkglib_LTLIBRARIES += write_graphite.la
-write_graphite_la_SOURCES = write_graphite.c
-write_graphite_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-write_graphite_la_LIBADD = libformat_graphite.la
-endif
-
-if BUILD_PLUGIN_WRITE_HTTP
-pkglib_LTLIBRARIES += write_http.la
-write_http_la_SOURCES = write_http.c \
- utils_format_kairosdb.c utils_format_kairosdb.h
-write_http_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-write_http_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
-write_http_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) libformat_json.la
-endif
-
-if BUILD_PLUGIN_WRITE_KAFKA
-pkglib_LTLIBRARIES += write_kafka.la
-write_kafka_la_SOURCES = write_kafka.c \
- utils_crc32.c utils_crc32.h
-write_kafka_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRDKAFKA_CPPFLAGS)
-write_kafka_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRDKAFKA_LDFLAGS)
-write_kafka_la_LIBADD = $(BUILD_WITH_LIBRDKAFKA_LIBS) \
- libcmds.la libformat_graphite.la libformat_json.la
-endif
-
-if BUILD_PLUGIN_WRITE_LOG
-pkglib_LTLIBRARIES += write_log.la
-write_log_la_SOURCES = write_log.c
-write_log_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-write_log_la_LIBADD = libformat_graphite.la libformat_json.la
-endif
-
-if BUILD_PLUGIN_WRITE_MONGODB
-pkglib_LTLIBRARIES += write_mongodb.la
-write_mongodb_la_SOURCES = write_mongodb.c
-write_mongodb_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMONGOC_CPPFLAGS)
-write_mongodb_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMONGOC_LDFLAGS)
-write_mongodb_la_LIBADD = -lmongoc
-endif
-
-if BUILD_PLUGIN_WRITE_PROMETHEUS
-pkglib_LTLIBRARIES += write_prometheus.la
-write_prometheus_la_SOURCES = write_prometheus.c
-nodist_write_prometheus_la_SOURCES = prometheus.pb-c.c prometheus.pb-c.h
-write_prometheus_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS) $(BUILD_WITH_LIBMICROHTTPD_CPPFLAGS)
-write_prometheus_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_LDFLAGS) $(BUILD_WITH_LIBMICROHTTPD_LDFLAGS)
-write_prometheus_la_LIBADD = $(BUILD_WITH_LIBPROTOBUF_C_LIBS) $(BUILD_WITH_LIBMICROHTTPD_LIBS)
-endif
-
-if BUILD_PLUGIN_WRITE_REDIS
-pkglib_LTLIBRARIES += write_redis.la
-write_redis_la_SOURCES = write_redis.c
-write_redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBHIREDIS_LDFLAGS)
-write_redis_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBHIREDIS_CPPFLAGS)
-write_redis_la_LIBADD = -lhiredis
-endif
-
-if BUILD_PLUGIN_WRITE_RIEMANN
-pkglib_LTLIBRARIES += write_riemann.la
-write_riemann_la_SOURCES = write_riemann.c write_riemann_threshold.c write_riemann_threshold.h
-write_riemann_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBRIEMANN_CLIENT_LIBS)
-write_riemann_la_CFLAGS = $(AM_CFLAGS) $(LIBRIEMANN_CLIENT_CFLAGS)
-endif
-
-if BUILD_PLUGIN_WRITE_SENSU
-pkglib_LTLIBRARIES += write_sensu.la
-write_sensu_la_SOURCES = write_sensu.c
-write_sensu_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_WRITE_TSDB
-pkglib_LTLIBRARIES += write_tsdb.la
-write_tsdb_la_SOURCES = write_tsdb.c
-write_tsdb_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-if BUILD_PLUGIN_XENCPU
-pkglib_LTLIBRARIES += xencpu.la
-xencpu_la_SOURCES = xencpu.c
-xencpu_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBXENCTL_CPPFLAGS)
-xencpu_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBXENCTL_LDFLAGS)
-xencpu_la_LIBADD = -lxenctrl
-endif
-
-if BUILD_PLUGIN_XMMS
-pkglib_LTLIBRARIES += xmms.la
-xmms_la_SOURCES = xmms.c
-xmms_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBXMMS_CFLAGS)
-xmms_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-xmms_la_LIBADD = $(BUILD_WITH_LIBXMMS_LIBS)
-endif
-
-if BUILD_PLUGIN_ZFS_ARC
-pkglib_LTLIBRARIES += zfs_arc.la
-zfs_arc_la_SOURCES = zfs_arc.c
-zfs_arc_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-if BUILD_FREEBSD
-zfs_arc_la_LIBADD = -lm
-endif
-if BUILD_SOLARIS
-zfs_arc_la_LIBADD = -lkstat
-endif
-endif
-
-if BUILD_PLUGIN_ZOOKEEPER
-pkglib_LTLIBRARIES += zookeeper.la
-zookeeper_la_SOURCES = zookeeper.c
-zookeeper_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-BUILT_SOURCES += $(dist_man_MANS)
-
-if BUILD_PLUGIN_ZONE
-pkglib_LTLIBRARIES += zone.la
-zone_la_SOURCES = zone.c
-zone_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-endif
-
-dist_man_MANS = collectd.1 \
- collectd.conf.5 \
- collectd-email.5 \
- collectd-exec.5 \
- collectdctl.1 \
- collectd-java.5 \
- collectd-lua.5 \
- collectdmon.1 \
- collectd-nagios.1 \
- collectd-perl.5 \
- collectd-python.5 \
- collectd-snmp.5 \
- collectd-tg.1 \
- collectd-threshold.5 \
- collectd-unixsock.5 \
- types.db.5
-
-EXTRA_DIST = collectd.conf.pod \
- collectd-email.pod \
- collectd-exec.pod \
- collectdctl.pod \
- collectd-java.pod \
- collectd-lua.pod \
- collectdmon.pod \
- collectd-nagios.pod \
- collectd-perl.pod \
- collectd-python.pod \
- collectd.pod \
- collectd-snmp.pod \
- collectd-tg.pod \
- collectd-threshold.pod \
- collectd-unixsock.pod \
- postgresql_default.conf \
- types.db \
- types.db.pod \
- valgrind.FreeBSD.suppress
-
-AM_V_POD2MAN_C = $(am__v_POD2MAN_C_@AM_V@)
-am__v_POD2MAN_C_ = $(am__v_POD2MAN_C_@AM_DEFAULT_V@)
-am__v_POD2MAN_C_0 = @echo " POD2MAN " $@;
-am__v_POD2MAN_C_1 =
-
-.pod.1:
- $(AM_V_POD2MAN_C)pod2man --release=$(VERSION) --center=$(PACKAGE) $< \
- >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true
- @if grep '\<POD ERRORS\>' $@ >/dev/null 2>&1; \
- then \
- echo "$@ has some POD errors!"; false; \
- fi
-
-.pod.5:
- $(AM_V_POD2MAN_C)pod2man --section=5 --release=$(VERSION) --center=$(PACKAGE) $< \
- >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true
- @if grep '\<POD ERRORS\>' $@ >/dev/null 2>&1; \
- then \
- echo "$@ has some POD errors!"; false; \
- fi
-
-AM_V_PROTOC_C = $(am__v_PROTOC_C_@AM_V@)
-am__v_PROTOC_C_ = $(am__v_PROTOC_C_@AM_DEFAULT_V@)
-am__v_PROTOC_C_0 = @echo " PROTOC-C" $@;
-am__v_PROTOC_C_1 =
-
-# Protocol buffer for the "pinba" plugin.
-EXTRA_DIST += pinba.proto
-if BUILD_PLUGIN_PINBA
-CLEANFILES += pinba.pb-c.c pinba.pb-c.h
-BUILT_SOURCES += pinba.pb-c.c pinba.pb-c.h
-
-pinba.pb-c.c pinba.pb-c.h: pinba.proto
- $(AM_V_PROTOC_C)$(PROTOC_C) -I$(srcdir) --c_out . $(srcdir)/pinba.proto
-endif
-
-# Protocol buffer for the "write_prometheus" plugin.
-if BUILD_PLUGIN_WRITE_PROMETHEUS
-CLEANFILES += prometheus.pb-c.c prometheus.pb-c.h
-BUILT_SOURCES += prometheus.pb-c.c prometheus.pb-c.h
-
-prometheus.pb-c.c prometheus.pb-c.h: $(top_srcdir)/proto/prometheus.proto
- $(AM_V_PROTOC_C)$(PROTOC_C) -I$(top_srcdir)/proto --c_out=$(builddir) $(top_srcdir)/proto/prometheus.proto
-endif
-
-install-exec-hook:
- $(mkinstalldirs) $(DESTDIR)$(sysconfdir)
- if test -e $(DESTDIR)$(sysconfdir)/collectd.conf; \
- then \
- $(INSTALL) -m 0640 collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf.pkg-orig; \
- else \
- $(INSTALL) -m 0640 collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf; \
- fi; \
- $(mkinstalldirs) $(DESTDIR)$(pkgdatadir)
- $(INSTALL) -m 0644 $(srcdir)/types.db $(DESTDIR)$(pkgdatadir)/types.db;
- $(INSTALL) -m 0644 $(srcdir)/postgresql_default.conf \
- $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
-
-uninstall-hook:
- rm -f $(DESTDIR)$(pkgdatadir)/types.db;
- rm -f $(DESTDIR)$(sysconfdir)/collectd.conf
- rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
-
-if BUILD_PLUGIN_CEPH
-test_plugin_ceph_SOURCES = ceph_test.c
-test_plugin_ceph_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
-test_plugin_ceph_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
-test_plugin_ceph_LDADD = daemon/libplugin_mock.la $(BUILD_WITH_LIBYAJL_LIBS)
-check_PROGRAMS += test_plugin_ceph
-TESTS += test_plugin_ceph
-endif
size_t len;
if (str == NULL)
- return (0);
+ return 0;
len = strlen(str);
if (len < 3)
- return (0);
+ return 0;
if ((str[0] == '/') && (str[len - 1] == '/'))
- return (1);
+ return 1;
else
- return (0);
+ return 0;
} /* }}} _Bool agg_is_regex */
static void agg_destroy(aggregation_t *agg) /* {{{ */
sstrncpy(inst->ident.plugin_instance, AGG_FUNC_PLACEHOLDER,
sizeof(inst->ident.plugin_instance));
else if (strcmp("", tmp_plugin) != 0)
- ssnprintf(inst->ident.plugin_instance,
- sizeof(inst->ident.plugin_instance), "%s-%s", tmp_plugin,
- AGG_FUNC_PLACEHOLDER);
+ snprintf(inst->ident.plugin_instance, sizeof(inst->ident.plugin_instance),
+ "%s-%s", tmp_plugin, AGG_FUNC_PLACEHOLDER);
else if (strcmp("", tmp_plugin_instance) != 0)
- ssnprintf(inst->ident.plugin_instance,
- sizeof(inst->ident.plugin_instance), "%s-%s",
- tmp_plugin_instance, AGG_FUNC_PLACEHOLDER);
+ snprintf(inst->ident.plugin_instance, sizeof(inst->ident.plugin_instance),
+ "%s-%s", tmp_plugin_instance, AGG_FUNC_PLACEHOLDER);
else
- ssnprintf(inst->ident.plugin_instance,
- sizeof(inst->ident.plugin_instance), "%s-%s-%s", tmp_plugin,
- tmp_plugin_instance, AGG_FUNC_PLACEHOLDER);
+ snprintf(inst->ident.plugin_instance, sizeof(inst->ident.plugin_instance),
+ "%s-%s-%s", tmp_plugin, tmp_plugin_instance,
+ AGG_FUNC_PLACEHOLDER);
}
/* Type */
#undef COPY_FIELD
- return (0);
+ return 0;
} /* }}} int agg_instance_create_name */
/* Create a new aggregation instance. */
inst = calloc(1, sizeof(*inst));
if (inst == NULL) {
ERROR("aggregation plugin: calloc() failed.");
- return (NULL);
+ return NULL;
}
pthread_mutex_init(&inst->lock, /* attr = */ NULL);
agg_instance_destroy(inst); \
free(inst); \
ERROR("aggregation plugin: calloc() failed."); \
- return (NULL); \
+ return NULL; \
} \
} \
} while (0)
agg_instance_list_head = inst;
pthread_mutex_unlock(&agg_instance_list_lock);
- return (inst);
+ return inst;
} /* }}} agg_instance_t *agg_instance_create */
/* Update the num, sum, min, max, ... fields of the aggregation instance, if
"data source. This is currently not supported by this plugin. "
"Sorry.",
ds->type);
- return (EINVAL);
+ return EINVAL;
}
rate = uc_get_rate(ds, vl);
FORMAT_VL(ident, sizeof(ident), vl);
ERROR("aggregation plugin: Unable to read the current rate of \"%s\".",
ident);
- return (ENOENT);
+ return ENOENT;
}
if (isnan(rate[0])) {
sfree(rate);
- return (0);
+ return 0;
}
pthread_mutex_lock(&inst->lock);
pthread_mutex_unlock(&inst->lock);
sfree(rate);
- return (0);
+ return 0;
} /* }}} int agg_instance_update */
static int agg_instance_read_func(agg_instance_t *inst, /* {{{ */
* COUNTER or a DERIVE, it will return EAGAIN. Catch this and handle
* gracefully. */
if (status == EAGAIN)
- return (0);
+ return 0;
WARNING("aggregation plugin: rate_to_value failed with status %i.", status);
- return (-1);
+ return -1;
}
vl->values = &v;
vl->values = NULL;
vl->values_len = 0;
- return (0);
+ return 0;
} /* }}} int agg_instance_read_func */
static int agg_instance_read(agg_instance_t *inst, cdtime_t t) /* {{{ */
vl.meta = meta_data_create();
if (vl.meta == NULL) {
ERROR("aggregation plugin: meta_data_create failed.");
- return (-1);
+ return -1;
}
meta_data_add_boolean(vl.meta, "aggregation:created", 1);
meta_data_destroy(vl.meta);
vl.meta = NULL;
- return (0);
+ return 0;
} /* }}} int agg_instance_read */
/* lookup_class_callback_t for utils_vl_lookup */
data_set_t const *ds,
value_list_t const *vl,
void *user_class) {
- return (agg_instance_create(ds, vl, (aggregation_t *)user_class));
+ return agg_instance_create(ds, vl, (aggregation_t *)user_class);
} /* }}} void *agg_class_callback */
/* lookup_obj_callback_t for utils_vl_lookup */
value_list_t const *vl,
__attribute__((unused)) void *user_class,
void *user_obj) {
- return (agg_instance_update((agg_instance_t *)user_obj, ds, vl));
+ return agg_instance_update((agg_instance_t *)user_obj, ds, vl);
} /* }}} int agg_lookup_obj_callback */
/* lookup_free_class_callback_t for utils_vl_lookup */
value);
} /* for (ci->values) */
- return (0);
+ return 0;
} /* }}} int agg_config_handle_group_by */
static int agg_config_aggregation(oconfig_item_t *ci) /* {{{ */
aggregation_t *agg = calloc(1, sizeof(*agg));
if (agg == NULL) {
ERROR("aggregation plugin: calloc failed.");
- return (-1);
+ return -1;
}
sstrncpy(agg->ident.host, "/.*/", sizeof(agg->ident.host));
if (!is_valid) { /* {{{ */
sfree(agg);
- return (-1);
+ return -1;
} /* }}} */
int status = lookup_add(lookup, &agg->ident, agg->group_by, agg);
if (status != 0) {
ERROR("aggregation plugin: lookup_add failed with status %i.", status);
sfree(agg);
- return (-1);
+ return -1;
}
DEBUG("aggregation plugin: Successfully added aggregation: "
"Type \"%s\", TypeInstance \"%s\")",
agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance,
agg->ident.type, agg->ident.type_instance);
- return (0);
+ return 0;
} /* }}} int agg_config_aggregation */
static int agg_config(oconfig_item_t *ci) /* {{{ */
if (lookup == NULL) {
pthread_mutex_unlock(&agg_instance_list_lock);
ERROR("aggregation plugin: lookup_create failed.");
- return (-1);
+ return -1;
}
}
pthread_mutex_unlock(&agg_instance_list_lock);
- return (0);
+ return 0;
} /* }}} int agg_config */
static int agg_read(void) /* {{{ */
* Therefore we need to handle this case separately. */
if (agg_instance_list_head == NULL) {
pthread_mutex_unlock(&agg_instance_list_lock);
- return (0);
+ return 0;
}
for (agg_instance_t *this = agg_instance_list_head; this != NULL;
pthread_mutex_unlock(&agg_instance_list_lock);
- return ((success > 0) ? 0 : -1);
+ return (success > 0) ? 0 : -1;
} /* }}} int agg_read */
static int agg_write(data_set_t const *ds, value_list_t const *vl, /* {{{ */
(void)meta_data_get_boolean(vl->meta, "aggregation:created",
&created_by_aggregation);
if (created_by_aggregation)
- return (0);
+ return 0;
if (lookup == NULL)
status = ENOENT;
status = 0;
}
- return (status);
+ return status;
} /* }}} int agg_write */
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 : */
char *ret;
if ((in == NULL) || (in->bytes == NULL))
- return (NULL);
+ return NULL;
ret = malloc(in->len + 1);
if (ret == NULL)
- return (NULL);
+ return NULL;
memcpy(ret, in->bytes, in->len);
ret[in->len] = 0;
- return (ret);
+ return ret;
} /* }}} char *camqp_bytes_cstring */
static _Bool camqp_is_error(camqp_config_t *conf) /* {{{ */
r = amqp_get_rpc_reply(conf->connection);
if (r.reply_type == AMQP_RESPONSE_NORMAL)
- return (0);
+ return 0;
- return (1);
+ return 1;
} /* }}} _Bool camqp_is_error */
static char *camqp_strerror(camqp_config_t *conf, /* {{{ */
case AMQP_RESPONSE_LIBRARY_EXCEPTION:
#if HAVE_AMQP_RPC_REPLY_T_LIBRARY_ERRNO
if (r.library_errno)
- return (sstrerror(r.library_errno, buffer, buffer_size));
+ return sstrerror(r.library_errno, buffer, buffer_size);
#else
if (r.library_error)
- return (sstrerror(r.library_error, buffer, buffer_size));
+ return sstrerror(r.library_error, buffer, buffer_size);
#endif
else
sstrncpy(buffer, "End of stream", buffer_size);
if (r.reply.id == AMQP_CONNECTION_CLOSE_METHOD) {
amqp_connection_close_t *m = r.reply.decoded;
char *tmp = camqp_bytes_cstring(&m->reply_text);
- ssnprintf(buffer, buffer_size, "Server connection error %d: %s",
- m->reply_code, tmp);
+ snprintf(buffer, buffer_size, "Server connection error %d: %s",
+ m->reply_code, tmp);
sfree(tmp);
} else if (r.reply.id == AMQP_CHANNEL_CLOSE_METHOD) {
amqp_channel_close_t *m = r.reply.decoded;
char *tmp = camqp_bytes_cstring(&m->reply_text);
- ssnprintf(buffer, buffer_size, "Server channel error %d: %s",
- m->reply_code, tmp);
+ snprintf(buffer, buffer_size, "Server channel error %d: %s",
+ m->reply_code, tmp);
sfree(tmp);
} else {
- ssnprintf(buffer, buffer_size, "Server error method %#" PRIx32,
- r.reply.id);
+ snprintf(buffer, buffer_size, "Server error method %#" PRIx32,
+ r.reply.id);
}
break;
default:
- ssnprintf(buffer, buffer_size, "Unknown reply type %i", (int)r.reply_type);
+ snprintf(buffer, buffer_size, "Unknown reply type %i", (int)r.reply_type);
}
- return (buffer);
+ return buffer;
} /* }}} char *camqp_strerror */
#if HAVE_AMQP_RPC_REPLY_T_LIBRARY_ERRNO
amqp_exchange_declare_ok_t *ed_ret;
if (conf->exchange_type == NULL)
- return (0);
+ return 0;
ed_ret = amqp_exchange_declare(
conf->connection,
ERROR("amqp plugin: amqp_exchange_declare failed: %s",
camqp_strerror(conf, errbuf, sizeof(errbuf)));
camqp_close_connection(conf);
- return (-1);
+ return -1;
}
INFO("amqp plugin: Successfully created exchange \"%s\" "
"with type \"%s\".",
conf->exchange, conf->exchange_type);
- return (0);
+ return 0;
} /* }}} int camqp_create_exchange */
#else
static int camqp_create_exchange(camqp_config_t *conf) /* {{{ */
struct amqp_table_entry_t_ argument_table_entries[1];
if (conf->exchange_type == NULL)
- return (0);
+ return 0;
/* Valid arguments: "auto_delete", "internal" */
argument_table.num_entries = STATIC_ARRAY_SIZE(argument_table_entries);
ERROR("amqp plugin: amqp_exchange_declare failed: %s",
camqp_strerror(conf, errbuf, sizeof(errbuf)));
camqp_close_connection(conf);
- return (-1);
+ return -1;
}
INFO("amqp plugin: Successfully created exchange \"%s\" "
"with type \"%s\".",
conf->exchange, conf->exchange_type);
- return (0);
+ return 0;
} /* }}} int camqp_create_exchange */
#endif
if (qd_ret == NULL) {
ERROR("amqp plugin: amqp_queue_declare failed.");
camqp_close_connection(conf);
- return (-1);
+ return -1;
}
if (conf->queue == NULL) {
if (conf->queue == NULL) {
ERROR("amqp plugin: camqp_bytes_cstring failed.");
camqp_close_connection(conf);
- return (-1);
+ return -1;
}
INFO("amqp plugin: Created queue \"%s\".", conf->queue);
ERROR("amqp plugin: amqp_queue_bind failed: %s",
camqp_strerror(conf, errbuf, sizeof(errbuf)));
camqp_close_connection(conf);
- return (-1);
+ return -1;
}
DEBUG("amqp plugin: Successfully bound queue \"%s\" to exchange \"%s\".",
ERROR("amqp plugin: amqp_basic_consume failed: %s",
camqp_strerror(conf, errbuf, sizeof(errbuf)));
camqp_close_connection(conf);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int camqp_setup_queue */
static int camqp_connect(camqp_config_t *conf) /* {{{ */
#endif
if (conf->connection != NULL)
- return (0);
+ return 0;
time_t now = time(NULL);
if (now < (last_connect_time + conf->connection_retry_delay)) {
DEBUG("amqp plugin: skipping connection retry, "
"ConnectionRetryDelay: %d",
conf->connection_retry_delay);
- return (1);
+ return 1;
} else {
DEBUG("amqp plugin: retrying connection");
last_connect_time = now;
conf->connection = amqp_new_connection();
if (conf->connection == NULL) {
ERROR("amqp plugin: amqp_new_connection failed.");
- return (ENOMEM);
+ return ENOMEM;
}
#ifdef HAVE_AMQP_TCP_SOCKET
ERROR("amqp plugin: amqp_tcp_socket_new failed.");
amqp_destroy_connection(conf->connection);
conf->connection = NULL;
- return (ENOMEM);
+ return ENOMEM;
}
status = amqp_socket_open(socket, CONF(conf, host), conf->port);
sstrerror(status, errbuf, sizeof(errbuf)));
amqp_destroy_connection(conf->connection);
conf->connection = NULL;
- return (status);
+ return status;
}
#else /* HAVE_AMQP_TCP_SOCKET */
#define CLOSE_SOCKET() close(sockfd)
sstrerror(status, errbuf, sizeof(errbuf)));
amqp_destroy_connection(conf->connection);
conf->connection = NULL;
- return (status);
+ return status;
}
amqp_set_sockfd(conf->connection, sockfd);
#endif
amqp_destroy_connection(conf->connection);
CLOSE_SOCKET();
conf->connection = NULL;
- return (1);
+ return 1;
}
amqp_channel_open(conf->connection, /* channel = */ 1);
amqp_destroy_connection(conf->connection);
CLOSE_SOCKET();
conf->connection = NULL;
- return (1);
+ return 1;
}
INFO("amqp plugin: Successfully opened connection to vhost \"%s\" "
status = camqp_create_exchange(conf);
if (status != 0)
- return (status);
+ return status;
if (!conf->publish)
- return (camqp_setup_queue(conf));
- return (0);
+ return camqp_setup_queue(conf);
+ return 0;
} /* }}} int camqp_connect */
static int camqp_shutdown(void) /* {{{ */
DEBUG("amqp plugin: All subscriber threads exited.");
- return (0);
+ return 0;
} /* }}} int camqp_shutdown */
/*
ERROR("amqp plugin: amqp_simple_wait_frame failed: %s",
sstrerror(status, errbuf, sizeof(errbuf)));
camqp_close_connection(conf);
- return (status);
+ return status;
}
if (frame.frame_type != AMQP_FRAME_BODY) {
NOTICE("amqp plugin: Unexpected frame type: %#" PRIx8, frame.frame_type);
- return (-1);
+ return -1;
}
if ((body_size - received) < frame.payload.body_fragment.len) {
WARNING("amqp plugin: Body is larger than indicated by header.");
- return (-1);
+ return -1;
}
memcpy(body_ptr, frame.payload.body_fragment.bytes,
status = cmd_handle_putval(stderr, body);
if (status != 0)
ERROR("amqp plugin: cmd_handle_putval failed with status %i.", status);
- return (status);
+ return status;
} else if (strcasecmp("application/json", content_type) == 0) {
ERROR("amqp plugin: camqp_read_body: Parsing JSON data has not "
"been implemented yet. FIXME!");
- return (0);
+ return 0;
} else {
ERROR("amqp plugin: camqp_read_body: Unknown content type \"%s\".",
content_type);
- return (EINVAL);
+ return EINVAL;
}
/* not reached */
- return (0);
+ return 0;
} /* }}} int camqp_read_body */
static int camqp_read_header(camqp_config_t *conf) /* {{{ */
ERROR("amqp plugin: amqp_simple_wait_frame failed: %s",
sstrerror(status, errbuf, sizeof(errbuf)));
camqp_close_connection(conf);
- return (status);
+ return status;
}
if (frame.frame_type != AMQP_FRAME_HEADER) {
NOTICE("amqp plugin: Unexpected frame type: %#" PRIx8, frame.frame_type);
- return (-1);
+ return -1;
}
properties = frame.payload.properties.decoded;
content_type = camqp_bytes_cstring(&properties->content_type);
if (content_type == NULL) {
ERROR("amqp plugin: Unable to determine content type.");
- return (-1);
+ return -1;
}
status = camqp_read_body(conf, (size_t)frame.payload.properties.body_size,
content_type);
sfree(content_type);
- return (status);
+ return status;
} /* }}} int camqp_read_header */
static void *camqp_subscribe_thread(void *user_data) /* {{{ */
camqp_config_free(conf);
pthread_exit(NULL);
- return (NULL);
+ return NULL;
} /* }}} void *camqp_subscribe_thread */
static int camqp_subscribe_init(camqp_config_t *conf) /* {{{ */
if (tmp == NULL) {
ERROR("amqp plugin: realloc failed.");
sfree(subscriber_threads);
- return (ENOMEM);
+ return ENOMEM;
}
subscriber_threads = tmp;
tmp = subscriber_threads + subscriber_threads_num;
char errbuf[1024];
ERROR("amqp plugin: pthread_create failed: %s",
sstrerror(status, errbuf, sizeof(errbuf)));
- return (status);
+ return status;
}
subscriber_threads_num++;
- return (0);
+ return 0;
} /* }}} int camqp_subscribe_init */
/*
status = camqp_connect(conf);
if (status != 0)
- return (status);
+ return status;
amqp_basic_properties_t props = {._flags = AMQP_BASIC_CONTENT_TYPE_FLAG |
AMQP_BASIC_DELIVERY_MODE_FLAG |
camqp_close_connection(conf);
}
- return (status);
+ return status;
} /* }}} int camqp_write_locked */
static int camqp_write(const data_set_t *ds, const value_list_t *vl, /* {{{ */
int status;
if ((ds == NULL) || (vl == NULL) || (conf == NULL))
- return (EINVAL);
+ return EINVAL;
if (conf->routing_key != NULL) {
sstrncpy(routing_key, conf->routing_key, sizeof(routing_key));
} else {
- ssnprintf(routing_key, sizeof(routing_key), "collectd/%s/%s/%s/%s/%s",
- vl->host, vl->plugin, vl->plugin_instance, vl->type,
- vl->type_instance);
+ snprintf(routing_key, sizeof(routing_key), "collectd/%s/%s/%s/%s/%s",
+ vl->host, vl->plugin, vl->plugin_instance, vl->type,
+ vl->type_instance);
/* Switch slashes (the only character forbidden by collectd) and dots
* (the separation character used by AMQP). */
status = cmd_create_putval(buffer, sizeof(buffer), ds, vl);
if (status != 0) {
ERROR("amqp plugin: cmd_create_putval failed with status %i.", status);
- return (status);
+ return status;
}
} else if (conf->format == CAMQP_FORMAT_JSON) {
size_t bfree = sizeof(buffer);
conf->postfix, conf->escape_char, conf->graphite_flags);
if (status != 0) {
ERROR("amqp plugin: format_graphite failed with status %i.", status);
- return (status);
+ return status;
}
} else {
ERROR("amqp plugin: Invalid format (%i).", conf->format);
- return (-1);
+ return -1;
}
pthread_mutex_lock(&conf->lock);
status = camqp_write_locked(conf, buffer, routing_key);
pthread_mutex_unlock(&conf->lock);
- return (status);
+ return status;
} /* }}} int camqp_write */
/*
string = NULL;
status = cf_util_get_string(ci, &string);
if (status != 0)
- return (status);
+ return status;
assert(string != NULL);
if (strcasecmp("Command", string) == 0)
free(string);
- return (0);
+ return 0;
} /* }}} int config_set_string */
static int camqp_config_connection(oconfig_item_t *ci, /* {{{ */
conf = calloc(1, sizeof(*conf));
if (conf == NULL) {
ERROR("amqp plugin: calloc failed.");
- return (ENOMEM);
+ return ENOMEM;
}
/* Initialize "conf" {{{ */
status = cf_util_get_string(ci, &conf->name);
if (status != 0) {
sfree(conf);
- return (status);
+ return status;
}
for (int i = 0; i < ci->children_num; i++) {
if (status != 0) {
camqp_config_free(conf);
- return (status);
+ return status;
}
if (conf->exchange != NULL) {
if (publish) {
char cbname[128];
- ssnprintf(cbname, sizeof(cbname), "amqp/%s", conf->name);
+ snprintf(cbname, sizeof(cbname), "amqp/%s", conf->name);
status = plugin_register_write(
cbname, camqp_write, &(user_data_t){
});
if (status != 0) {
camqp_config_free(conf);
- return (status);
+ return status;
}
} else {
status = camqp_subscribe_init(conf);
if (status != 0) {
camqp_config_free(conf);
- return (status);
+ return status;
}
}
- return (0);
+ return 0;
} /* }}} int camqp_config_connection */
static int camqp_config(oconfig_item_t *ci) /* {{{ */
child->key);
} /* for (ci->children_num) */
- return (0);
+ return 0;
} /* }}} int camqp_config */
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 : */
if (st == NULL) {
ERROR("apache plugin: apache_curl_callback: "
"user_data pointer is NULL.");
- return (0);
+ return 0;
}
if (len == 0)
- return (len);
+ return len;
if ((st->apache_buffer_fill + len) >= st->apache_buffer_size) {
char *temp;
temp = realloc(st->apache_buffer, st->apache_buffer_fill + len + 1);
if (temp == NULL) {
ERROR("apache plugin: realloc failed.");
- return (0);
+ return 0;
}
st->apache_buffer = temp;
st->apache_buffer_size = st->apache_buffer_fill + len + 1;
st->apache_buffer_fill += len;
st->apache_buffer[st->apache_buffer_fill] = 0;
- return (len);
+ return len;
} /* int apache_curl_callback */
static size_t apache_header_callback(void *buf, size_t size, size_t nmemb,
if (st == NULL) {
ERROR("apache plugin: apache_header_callback: "
"user_data pointer is NULL.");
- return (0);
+ return 0;
}
if (len == 0)
- return (len);
+ return len;
/* look for the Server header */
if (strncasecmp(buf, "Server: ", strlen("Server: ")) != 0)
- return (len);
+ return len;
if (strstr(buf, "Apache") != NULL)
st->server_type = APACHE;
NOTICE("apache plugin: Unknown server software: %s", hdr);
}
- return (len);
+ return len;
} /* apache_header_callback */
/* Configuration handling functiions
st = calloc(1, sizeof(*st));
if (st == NULL) {
ERROR("apache plugin: calloc failed.");
- return (-1);
+ return -1;
}
st->timeout = -1;
status = cf_util_get_string(ci, &st->name);
if (status != 0) {
sfree(st);
- return (status);
+ return status;
}
assert(st->name != NULL);
status = -1;
}
- if (status == 0) {
- char callback_name[3 * DATA_MAX_NAME_LEN];
-
- ssnprintf(callback_name, sizeof(callback_name), "apache/%s/%s",
- (st->host != NULL) ? st->host : hostname_g,
- (st->name != NULL) ? st->name : "default");
-
- status = plugin_register_complex_read(
- /* group = */ NULL,
- /* name = */ callback_name,
- /* callback = */ apache_read_host,
- /* interval = */ 0, &(user_data_t){
- .data = st, .free_func = apache_free,
- });
- }
-
if (status != 0) {
apache_free(st);
- return (-1);
+ return -1;
}
- return (0);
+ char callback_name[3 * DATA_MAX_NAME_LEN];
+
+ snprintf(callback_name, sizeof(callback_name), "apache/%s/%s",
+ (st->host != NULL) ? st->host : hostname_g,
+ (st->name != NULL) ? st->name : "default");
+
+ return plugin_register_complex_read(
+ /* group = */ NULL,
+ /* name = */ callback_name,
+ /* callback = */ apache_read_host,
+ /* interval = */ 0,
+ &(user_data_t){
+ .data = st, .free_func = apache_free,
+ });
} /* int config_add */
static int config(oconfig_item_t *ci) {
child->key);
} /* for (ci->children) */
- return (status);
+ return status;
} /* int config */
/* initialize curl for each host */
if ((st->curl = curl_easy_init()) == NULL) {
ERROR("apache plugin: init_host: `curl_easy_init' failed.");
- return (-1);
+ return -1;
}
curl_easy_setopt(st->curl, CURLOPT_NOSIGNAL, 1L);
static char credentials[1024];
int status;
- status = ssnprintf(credentials, sizeof(credentials), "%s:%s", st->user,
- (st->pass == NULL) ? "" : st->pass);
+ status = snprintf(credentials, sizeof(credentials), "%s:%s", st->user,
+ (st->pass == NULL) ? "" : st->pass);
if ((status < 0) || ((size_t)status >= sizeof(credentials))) {
ERROR("apache plugin: init_host: Returning an error "
"because the credentials have been "
"truncated.");
curl_easy_cleanup(st->curl);
st->curl = NULL;
- return (-1);
+ return -1;
}
curl_easy_setopt(st->curl, CURLOPT_USERPWD, credentials);
(long)CDTIME_T_TO_MS(plugin_get_interval()));
#endif
- return (0);
+ return 0;
} /* }}} int init_host */
static void submit_value(const char *type, const char *type_instance,
if (st->curl == NULL) {
status = init_host(st);
if (status != 0)
- return (-1);
+ return -1;
}
assert(st->curl != NULL);
if (curl_easy_perform(st->curl) != CURLE_OK) {
ERROR("apache: curl_easy_perform failed: %s", st->apache_curl_error);
- return (-1);
+ return -1;
}
/* fallback - server_type to apache if not set at this time */
st->apache_buffer_fill = 0;
- return (0);
+ return 0;
} /* }}} int apache_read_host */
static int apache_init(void) /* {{{ */
/* Call this while collectd is still single-threaded to avoid
* initialization issues in libgcrypt. */
curl_global_init(CURL_GLOBAL_SSL);
- return (0);
+ return 0;
} /* }}} int apache_init */
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 : */
uint16_t packet_size = 0;
if ((fd == NULL) || (*fd < 0))
- return (EINVAL);
+ return EINVAL;
(void)swrite(*fd, (void *)&packet_size, sizeof(packet_size));
close(*fd);
*fd = -1;
- return (0);
+ return 0;
} /* int net_shutdown */
/* Close the network connection */
static int apcups_shutdown(void) {
if (global_sockfd < 0)
- return (0);
+ return 0;
net_shutdown(&global_sockfd);
- return (0);
+ return 0;
} /* int apcups_shutdown */
/*
INFO("apcups plugin: getaddrinfo failed: %s",
(status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
: gai_strerror(status));
- return (-1);
+ return -1;
}
/* Create socket */
if (sd < 0) {
DEBUG("apcups plugin: Unable to open a socket");
freeaddrinfo(ai_return);
- return (-1);
+ return -1;
}
status = connect(sd, ai_list->ai_addr, ai_list->ai_addrlen);
INFO("apcups plugin: connect failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
close(sd);
- return (-1);
+ return -1;
}
DEBUG("apcups plugin: Done opening a socket %i", sd);
- return (sd);
+ return sd;
} /* int net_open */
/*
if (sread(*sockfd, (void *)&packet_size, sizeof(packet_size)) != 0) {
close(*sockfd);
*sockfd = -1;
- return (-1);
+ return -1;
}
packet_size = ntohs(packet_size);
packet_size, buflen);
close(*sockfd);
*sockfd = -1;
- return (-2);
+ return -2;
}
if (packet_size == 0)
- return (0);
+ return 0;
/* now read the actual data */
if (sread(*sockfd, (void *)buf, packet_size) != 0) {
close(*sockfd);
*sockfd = -1;
- return (-1);
+ return -1;
}
- return ((int)packet_size);
+ return (int)packet_size;
} /* static int net_recv (int *sockfd, char *buf, int buflen) */
/*
if (swrite(*sockfd, (void *)&packet_size, sizeof(packet_size)) != 0) {
close(*sockfd);
*sockfd = -1;
- return (-1);
+ return -1;
}
/* send data packet */
if (swrite(*sockfd, (void *)buff, len) != 0) {
close(*sockfd);
*sockfd = -1;
- return (-2);
+ return -2;
}
- return (0);
+ return 0;
}
/* Get and print status from apcupsd NIS server */
char recvline[1024];
char *tokptr;
char *toksaveptr;
- _Bool retry = 1;
+ int try = 0;
int status;
#if APCMAIN
#define PRINT_VALUE(name, val) /**/
#endif
- while (retry) {
+ while (1) {
if (global_sockfd < 0) {
global_sockfd = net_open(node, service);
if (global_sockfd < 0) {
ERROR("apcups plugin: Connecting to the "
"apcupsd failed.");
- return (-1);
+ return -1;
}
}
status = net_send(&global_sockfd, "status", strlen("status"));
if (status != 0) {
- /* net_send is closing the socket on error. */
+ /* net_send closes the socket on error. */
assert(global_sockfd < 0);
- if (retry) {
- retry = 0;
+ if (try == 0) {
+ try++;
count_retries++;
continue;
}
ERROR("apcups plugin: Writing to the socket failed.");
- return (-1);
+ return -1;
}
break;
- } /* while (retry) */
+ } /* while (1) */
/* When collectd's collection interval is larger than apcupsd's
* timeout, we would have to retry / re-connect each iteration. Try to
char errbuf[1024];
ERROR("apcups plugin: Reading from socket failed: %s",
sstrerror(status, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static int apcups_config(oconfig_item_t *ci) {
}
}
- return (0);
+ return 0;
} /* int apcups_config */
static void apc_submit_generic(const char *type, const char *type_inst,
.linefreq = NAN,
};
- int status =
- apc_query_server(conf_node == NULL ? APCUPS_DEFAULT_NODE : conf_node,
- conf_service, &apcups_detail);
+ int status = apc_query_server(conf_node, conf_service, &apcups_detail);
+
if (status != 0) {
DEBUG("apcups plugin: apc_query_server (\"%s\", \"%s\") = %d",
- conf_node == NULL ? APCUPS_DEFAULT_NODE : conf_node, conf_service,
- status);
- return (status);
+ conf_node, conf_service, status);
+ return status;
}
apc_submit(&apcups_detail);
- return (0);
+ return 0;
} /* apcups_read */
+static int apcups_init(void) {
+ if (conf_node == NULL)
+ conf_node = APCUPS_DEFAULT_NODE;
+
+ if (conf_service == NULL)
+ conf_service = APCUPS_DEFAULT_SERVICE;
+
+ return 0;
+} /* apcups_init */
+
void module_register(void) {
plugin_register_complex_config("apcups", apcups_config);
+ plugin_register_init("apcups", apcups_init);
plugin_register_read("apcups", apcups_read);
plugin_register_shutdown("apcups", apcups_shutdown);
} /* void module_register */
#include "common.h"
#include "plugin.h"
-#if HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-
#if HAVE_MACH_MACH_TYPES_H
#include <mach/mach_types.h>
#endif
if (status != kIOReturnSuccess) {
ERROR("IOMasterPort failed: %s", mach_error_string(status));
io_master_port = MACH_PORT_NULL;
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static void as_submit(const char *type, const char *type_instance, double val) {
int value_int;
double value_double;
if (!io_master_port || (io_master_port == MACH_PORT_NULL))
- return (-1);
+ return -1;
status = IOServiceGetMatchingServices(
io_master_port, IOServiceNameMatching("IOHWSensor"), &iterator);
if (status != kIOReturnSuccess) {
ERROR("IOServiceGetMatchingServices failed: %s", mach_error_string(status));
- return (-1);
+ return -1;
}
while ((io_obj = IOIteratorNext(iterator))) {
IOObjectRelease(iterator);
- return (0);
+ return 0;
} /* int as_read */
void module_register(void) {
}
}
- return (0);
+ return 0;
}
static int aquaero_shutdown(void) {
libaquaero5_exit();
- return (0);
+ return 0;
} /* int aquaero_shutdown */
static void aquaero_submit(const char *type, const char *type_instance,
ERROR("aquaero plugin: Failed to poll device \"%s\": %s (%s)",
conf_device ? conf_device : "default", err_msg,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
if (libaquaero5_getsettings(conf_device, &aq_sett, &err_msg) < 0) {
"for device \"%s\": %s (%s)",
conf_device ? conf_device : "default", err_msg,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
/* CPU Temperature sensor */
/* Liquid level */
aquaero_submit_array("percent", "waterlevel", aq_data.level, AQ5_NUM_LEVEL);
- return (0);
+ return 0;
}
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 : */
sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
plugin_dispatch_values(&vl);
- return (0);
+ return 0;
} /* }}} int ascent_submit_gauge */
static size_t ascent_curl_callback(void *buf, size_t size,
size_t len = size * nmemb;
if (len == 0)
- return (len);
+ return len;
if ((ascent_buffer_fill + len) >= ascent_buffer_size) {
char *temp;
temp = realloc(ascent_buffer, ascent_buffer_fill + len + 1);
if (temp == NULL) {
ERROR("ascent plugin: realloc failed.");
- return (0);
+ return 0;
}
ascent_buffer = temp;
ascent_buffer_size = ascent_buffer_fill + len + 1;
ascent_buffer_fill += len;
ascent_buffer[ascent_buffer_fill] = 0;
- return (len);
+ return len;
} /* }}} size_t ascent_curl_callback */
static int ascent_submit_players(player_stats_t *ps) /* {{{ */
value = ((double)ps->latency_sum) / (1000.0 * ((double)ps->latency_num));
ascent_submit_gauge(NULL, "latency", "average", value);
- return (0);
+ return 0;
} /* }}} int ascent_submit_players */
static int ascent_account_player(player_stats_t *ps, /* {{{ */
ps->latency_num++;
}
- return (0);
+ return 0;
} /* }}} int ascent_account_player */
static int ascent_xml_submit_gauge(xmlDoc *doc, xmlNode *node, /* {{{ */
if (str_ptr == NULL) {
ERROR(
"ascent plugin: ascent_xml_submit_gauge: xmlNodeListGetString failed.");
- return (-1);
+ return -1;
}
if (strcasecmp("N/A", str_ptr) == 0)
if (str_ptr == end_ptr) {
xmlFree(str_ptr);
ERROR("ascent plugin: ascent_xml_submit_gauge: strtod failed.");
- return (-1);
+ return -1;
}
}
xmlFree(str_ptr);
- return (ascent_submit_gauge(plugin_instance, type, type_instance, value));
+ return ascent_submit_gauge(plugin_instance, type, type_instance, value);
} /* }}} int ascent_xml_submit_gauge */
static int ascent_xml_read_int(xmlDoc *doc, xmlNode *node, /* {{{ */
str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
if (str_ptr == NULL) {
ERROR("ascent plugin: ascent_xml_read_int: xmlNodeListGetString failed.");
- return (-1);
+ return -1;
}
if (strcasecmp("N/A", str_ptr) == 0)
if (str_ptr == end_ptr) {
xmlFree(str_ptr);
ERROR("ascent plugin: ascent_xml_read_int: strtol failed.");
- return (-1);
+ return -1;
}
}
xmlFree(str_ptr);
*ret_value = value;
- return (0);
+ return 0;
} /* }}} int ascent_xml_read_int */
static int ascent_xml_sessions_plr(xmlDoc *doc, xmlNode *node, /* {{{ */
}
} /* for (child) */
- return (0);
+ return 0;
} /* }}} int ascent_xml_sessions_plr */
static int ascent_xml_sessions(xmlDoc *doc, xmlNode *node) /* {{{ */
ascent_submit_players(&ps);
- return (0);
+ return 0;
} /* }}} int ascent_xml_sessions */
static int ascent_xml_status(xmlDoc *doc, xmlNode *node) /* {{{ */
}
} /* for (child) */
- return (0);
+ return 0;
} /* }}} int ascent_xml_status */
static int ascent_xml(const char *data) /* {{{ */
#endif
if (doc == NULL) {
ERROR("ascent plugin: xmlParseMemory failed.");
- return (-1);
+ return -1;
}
cur = xmlDocGetRootElement(doc);
if (cur == NULL) {
ERROR("ascent plugin: XML document is empty.");
xmlFreeDoc(doc);
- return (-1);
+ return -1;
}
if (xmlStrcmp((const xmlChar *)"serverpage", cur->name) != 0) {
ERROR("ascent plugin: XML root element is not \"serverpage\".");
xmlFreeDoc(doc);
- return (-1);
+ return -1;
}
for (xmlNode *child = cur->xmlChildrenNode; child != NULL;
} /* for (child) */
xmlFreeDoc(doc);
- return (0);
+ return 0;
} /* }}} int ascent_xml */
static int config_set(char **var, const char *value) /* {{{ */
}
if ((*var = strdup(value)) == NULL)
- return (1);
+ return 1;
else
- return (0);
+ return 0;
} /* }}} int config_set */
static int ascent_config(const char *key, const char *value) /* {{{ */
{
if (strcasecmp(key, "URL") == 0)
- return (config_set(&url, value));
+ return config_set(&url, value);
else if (strcasecmp(key, "User") == 0)
- return (config_set(&user, value));
+ return config_set(&user, value);
else if (strcasecmp(key, "Password") == 0)
- return (config_set(&pass, value));
+ return config_set(&pass, value);
else if (strcasecmp(key, "VerifyPeer") == 0)
- return (config_set(&verify_peer, value));
+ return config_set(&verify_peer, value);
else if (strcasecmp(key, "VerifyHost") == 0)
- return (config_set(&verify_host, value));
+ return config_set(&verify_host, value);
else if (strcasecmp(key, "CACert") == 0)
- return (config_set(&cacert, value));
+ return config_set(&cacert, value);
else if (strcasecmp(key, "Timeout") == 0)
- return (config_set(&timeout, value));
+ return config_set(&timeout, value);
else
- return (-1);
+ return -1;
} /* }}} int ascent_config */
static int ascent_init(void) /* {{{ */
if (url == NULL) {
WARNING("ascent plugin: ascent_init: No URL configured, "
"returning an error.");
- return (-1);
+ return -1;
}
if (curl != NULL) {
if ((curl = curl_easy_init()) == NULL) {
ERROR("ascent plugin: ascent_init: curl_easy_init failed.");
- return (-1);
+ return -1;
}
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
static char credentials[1024];
int status;
- status = ssnprintf(credentials, sizeof(credentials), "%s:%s", user,
- (pass == NULL) ? "" : pass);
+ status = snprintf(credentials, sizeof(credentials), "%s:%s", user,
+ (pass == NULL) ? "" : pass);
if ((status < 0) || ((size_t)status >= sizeof(credentials))) {
ERROR("ascent plugin: ascent_init: Returning an error because the "
"credentials have been truncated.");
- return (-1);
+ return -1;
}
curl_easy_setopt(curl, CURLOPT_USERPWD, credentials);
(long)CDTIME_T_TO_MS(plugin_get_interval()));
#endif
- return (0);
+ return 0;
} /* }}} int ascent_init */
static int ascent_read(void) /* {{{ */
if (curl == NULL) {
ERROR("ascent plugin: I don't have a CURL object.");
- return (-1);
+ return -1;
}
if (url == NULL) {
ERROR("ascent plugin: No URL has been configured.");
- return (-1);
+ return -1;
}
ascent_buffer_fill = 0;
if (curl_easy_perform(curl) != CURLE_OK) {
ERROR("ascent plugin: curl_easy_perform failed: %s", ascent_curl_error);
- return (-1);
+ return -1;
}
status = ascent_xml(ascent_buffer);
if (status != 0)
- return (-1);
+ return -1;
else
- return (0);
+ return 0;
} /* }}} int ascent_read */
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 : */
kCFStringEncodingASCII);
if (key_obj == NULL) {
DEBUG("CFStringCreateWithCString (%s) failed.\n", key_string);
- return (NAN);
+ return NAN;
}
if ((val_obj = CFDictionaryGetValue(dict, key_obj)) == NULL) {
DEBUG("CFDictionaryGetValue (%s) failed.", key_string);
CFRelease(key_obj);
- return (NAN);
+ return NAN;
}
CFRelease(key_obj);
}
} else {
DEBUG("CFGetTypeID (val_obj) = %i", (int)CFGetTypeID(val_obj));
- return (NAN);
+ return NAN;
}
- return (val_double);
+ return val_double;
} /* }}} double dict_get_double */
#if HAVE_IOKIT_PS_IOPOWERSOURCES_H
if (!isnan(voltage))
battery_submit("0", "voltage", voltage);
- return (0);
+ return 0;
} /* }}} int battery_read */
/* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */
char filename[PATH_MAX];
int status;
- ssnprintf(filename, sizeof(filename), "%s/%s/%s", dir, power_supply,
- basename);
+ snprintf(filename, sizeof(filename), "%s/%s/%s", dir, power_supply, basename);
status = (int)read_file_contents(filename, buffer, buffer_size - 1);
if (status < 0)
status =
sysfs_file_to_buffer(dir, power_supply, basename, buffer, sizeof(buffer));
if (status != 0)
- return (status);
+ return status;
- return (strtogauge(buffer, ret_value));
+ return strtogauge(buffer, ret_value);
} /* }}} sysfs_file_to_gauge */
static int read_sysfs_capacity(char const *dir, /* {{{ */
status =
sysfs_file_to_gauge(dir, power_supply, "energy_now", &capacity_charged);
if (status != 0)
- return (status);
+ return status;
status =
sysfs_file_to_gauge(dir, power_supply, "energy_full", &capacity_full);
if (status != 0)
- return (status);
+ return status;
status = sysfs_file_to_gauge(dir, power_supply, "energy_full_design",
&capacity_design);
if (status != 0)
- return (status);
+ return status;
submit_capacity(plugin_instance, capacity_charged * SYSFS_FACTOR,
capacity_full * SYSFS_FACTOR, capacity_design * SYSFS_FACTOR);
- return (0);
+ return 0;
} /* }}} int read_sysfs_capacity */
static int read_sysfs_callback(char const *dir, /* {{{ */
status =
sysfs_file_to_buffer(dir, power_supply, "type", buffer, sizeof(buffer));
if (status != 0)
- return (0);
+ return 0;
if (strcasecmp("Battery", buffer) != 0)
- return (0);
+ return 0;
(void)sysfs_file_to_buffer(dir, power_supply, "status", buffer,
sizeof(buffer));
if (sysfs_file_to_gauge(dir, power_supply, "voltage_now", &v) == 0)
battery_submit(plugin_instance, "voltage", v * SYSFS_FACTOR);
- return (0);
+ return 0;
} /* }}} int read_sysfs_callback */
static int read_sysfs(void) /* {{{ */
int battery_counter = 0;
if (access(SYSFS_PATH, R_OK) != 0)
- return (ENOENT);
+ return ENOENT;
status = walk_directory(SYSFS_PATH, read_sysfs_callback,
/* user_data = */ &battery_counter,
/* include hidden */ 0);
- return (status);
+ return status;
} /* }}} int read_sysfs */
static int read_acpi_full_capacity(char const *dir, /* {{{ */
FILE *fh;
- ssnprintf(filename, sizeof(filename), "%s/%s/info", dir, power_supply);
+ snprintf(filename, sizeof(filename), "%s/%s/info", dir, power_supply);
fh = fopen(filename, "r");
if (fh == NULL)
- return (errno);
+ return errno;
/* last full capacity: 40090 mWh */
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
}
fclose(fh);
- return (0);
+ return 0;
} /* }}} int read_acpi_full_capacity */
static int read_acpi_callback(char const *dir, /* {{{ */
FILE *fh;
- ssnprintf(filename, sizeof(filename), "%s/%s/state", dir, power_supply);
+ snprintf(filename, sizeof(filename), "%s/%s/state", dir, power_supply);
fh = fopen(filename, "r");
if (fh == NULL) {
if ((errno == EAGAIN) || (errno == EINTR) || (errno == ENOENT))
- return (0);
+ return 0;
else
- return (errno);
+ return errno;
}
/*
int battery_counter = 0;
if (access(PROC_ACPI_PATH, R_OK) != 0)
- return (ENOENT);
+ return ENOENT;
status = walk_directory(PROC_ACPI_PATH, read_acpi_callback,
/* user_data = */ &battery_counter,
/* include hidden */ 0);
- return (status);
+ return status;
} /* }}} int read_acpi */
static int read_pmu(void) /* {{{ */
gauge_t voltage = NAN;
gauge_t charge = NAN;
- ssnprintf(filename, sizeof(filename), PROC_PMU_PATH_FORMAT, i);
+ snprintf(filename, sizeof(filename), PROC_PMU_PATH_FORMAT, i);
if (access(filename, R_OK) != 0)
break;
- ssnprintf(plugin_instance, sizeof(plugin_instance), "%i", i);
+ snprintf(plugin_instance, sizeof(plugin_instance), "%i", i);
fh = fopen(filename, "r");
if (fh == NULL) {
else if ((errno == EAGAIN) || (errno == EINTR))
continue;
else
- return (errno);
+ return errno;
}
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
}
if (i == 0)
- return (ENOENT);
- return (0);
+ return ENOENT;
+ return 0;
} /* }}} int read_pmu */
static int battery_read(void) /* {{{ */
DEBUG("battery plugin: Trying sysfs ...");
status = read_sysfs();
if (status == 0)
- return (0);
+ return 0;
DEBUG("battery plugin: Trying acpi ...");
status = read_acpi();
if (status == 0)
- return (0);
+ return 0;
DEBUG("battery plugin: Trying pmu ...");
status = read_pmu();
if (status == 0)
- return (0);
+ return 0;
ERROR("battery plugin: All available input methods failed.");
- return (-1);
+ return -1;
} /* }}} int battery_read */
#endif /* KERNEL_LINUX */
child->key);
}
- return (0);
+ return 0;
} /* }}} int battery_config */
void module_register(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
if (success == 0) {
ERROR("battery plugin: statefs backend: none of the statistics are "
"available");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
size_t len = size * nmemb;
if (len == 0)
- return (len);
+ return len;
if ((bind_buffer_fill + len) >= bind_buffer_size) {
char *temp;
temp = realloc(bind_buffer, bind_buffer_fill + len + 1);
if (temp == NULL) {
ERROR("bind plugin: realloc failed.");
- return (0);
+ return 0;
}
bind_buffer = temp;
bind_buffer_size = bind_buffer_fill + len + 1;
bind_buffer_fill += len;
bind_buffer[bind_buffer_fill] = 0;
- return (len);
+ return len;
} /* }}} size_t bind_curl_callback */
/*
translation_table_ptr_t *table = (translation_table_ptr_t *)user_data;
if (table == NULL)
- return (-1);
+ return -1;
for (size_t i = 0; i < table->table_length; i++) {
if (strcmp(table->table[i].xml_name, name) != 0)
break;
}
- return (0);
+ return 0;
} /* }}} int bind_xml_table_callback */
/*
list_info_ptr_t *list_info = (list_info_ptr_t *)user_data;
if (list_info == NULL)
- return (-1);
+ return -1;
submit(current_time, list_info->plugin_instance, list_info->type,
/* type instance = */ name, value);
- return (0);
+ return 0;
} /* }}} int bind_xml_list_callback */
static int bind_xml_read_derive(xmlDoc *doc, xmlNode *node, /* {{{ */
str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
if (str_ptr == NULL) {
ERROR("bind plugin: bind_xml_read_derive: xmlNodeListGetString failed.");
- return (-1);
+ return -1;
}
status = parse_value(str_ptr, &value, DS_TYPE_DERIVE);
ERROR("bind plugin: Parsing string \"%s\" to derive value failed.",
str_ptr);
xmlFree(str_ptr);
- return (-1);
+ return -1;
}
xmlFree(str_ptr);
*ret_value = value.derive;
- return (0);
+ return 0;
} /* }}} int bind_xml_read_derive */
static int bind_xml_read_gauge(xmlDoc *doc, xmlNode *node, /* {{{ */
str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
if (str_ptr == NULL) {
ERROR("bind plugin: bind_xml_read_gauge: xmlNodeListGetString failed.");
- return (-1);
+ return -1;
}
errno = 0;
ERROR("bind plugin: bind_xml_read_gauge: strtod failed with overflow.");
else
ERROR("bind plugin: bind_xml_read_gauge: strtod failed.");
- return (-1);
+ return -1;
}
*ret_value = (gauge_t)value;
- return (0);
+ return 0;
} /* }}} int bind_xml_read_gauge */
static int bind_xml_read_timestamp(const char *xpath_expression, /* {{{ */
if (xpathObj == NULL) {
ERROR("bind plugin: Unable to evaluate XPath expression `%s'.",
xpath_expression);
- return (-1);
+ return -1;
}
if ((xpathObj->nodesetval == NULL) || (xpathObj->nodesetval->nodeNr < 1)) {
xmlXPathFreeObject(xpathObj);
- return (-1);
+ return -1;
}
if (xpathObj->nodesetval->nodeNr != 1) {
ERROR("bind plugin: bind_xml_read_timestamp: "
"node->xmlChildrenNode == NULL");
xmlXPathFreeObject(xpathObj);
- return (-1);
+ return -1;
}
str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
if (str_ptr == NULL) {
ERROR("bind plugin: bind_xml_read_timestamp: xmlNodeListGetString failed.");
xmlXPathFreeObject(xpathObj);
- return (-1);
+ return -1;
}
tmp = strptime(str_ptr, "%Y-%m-%dT%T", &tm);
if (tmp == NULL) {
ERROR("bind plugin: bind_xml_read_timestamp: strptime failed.");
xmlXPathFreeObject(xpathObj);
- return (-1);
+ return -1;
}
#if HAVE_TIMEGM
char errbuf[1024];
ERROR("bind plugin: timegm() failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
*ret_value = t;
#else
char errbuf[1024];
ERROR("bind plugin: mktime() failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
/* mktime assumes that tm is local time. Luckily, it also sets timezone to
* the offset used for the conversion, and we undo the conversion to convert
#endif
xmlXPathFreeObject(xpathObj);
- return (0);
+ return 0;
} /* }}} int bind_xml_read_timestamp */
/*
if (xpathObj == NULL) {
ERROR("bind plugin: Unable to evaluate XPath expression `%s'.",
xpath_expression);
- return (-1);
+ return -1;
}
num_entries = 0;
xmlXPathFreeObject(xpathObj);
- return (0);
+ return 0;
} /* }}} int bind_parse_generic_name_value */
/*
if (xpathObj == NULL) {
ERROR("bind plugin: Unable to evaluate XPath expression `%s'.",
xpath_expression);
- return (-1);
+ return -1;
}
num_entries = 0;
xmlXPathFreeObject(xpathObj);
- return (0);
+ return 0;
} /* }}} int bind_parse_generic_value_list */
/*
if (xpathObj == NULL) {
ERROR("bind plugin: Unable to evaluate XPath expression `%s'.",
xpath_expression);
- return (-1);
+ return -1;
}
num_entries = 0;
xmlXPathFreeObject(xpathObj);
- return (0);
+ return 0;
} /* }}} int bind_parse_generic_name_attr_value_list */
static int bind_xml_stats_handle_zone(int version, xmlDoc *doc, /* {{{ */
path_obj = xmlXPathEvalExpression(BAD_CAST "name", path_ctx);
if (path_obj == NULL) {
ERROR("bind plugin: xmlXPathEvalExpression failed.");
- return (-1);
+ return -1;
}
for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr);
if (zone_name == NULL) {
ERROR("bind plugin: Could not determine zone name.");
- return (-1);
+ return -1;
}
for (j = 0; j < view->zones_num; j++) {
zone_name = NULL;
if (j >= view->zones_num)
- return (0);
+ return 0;
zone_name = view->zones[j];
nsstats_translation_table_length,
plugin_instance};
- ssnprintf(plugin_instance, sizeof(plugin_instance), "%s-zone-%s",
- view->name, zone_name);
+ snprintf(plugin_instance, sizeof(plugin_instance), "%s-zone-%s", view->name,
+ zone_name);
if (version == 3) {
list_info_ptr_t list_info = {plugin_instance,
}
} /* }}} */
- return (0);
+ return 0;
} /* }}} int bind_xml_stats_handle_zone */
static int bind_xml_stats_search_zones(int version, xmlDoc *doc, /* {{{ */
zone_path_context = xmlXPathNewContext(doc);
if (zone_path_context == NULL) {
ERROR("bind plugin: xmlXPathNewContext failed.");
- return (-1);
+ return -1;
}
zone_nodes = xmlXPathEvalExpression(BAD_CAST "zones/zone", path_ctx);
if (zone_nodes == NULL) {
ERROR("bind plugin: Cannot find any <view> tags.");
xmlXPathFreeContext(zone_path_context);
- return (-1);
+ return -1;
}
for (int i = 0; i < zone_nodes->nodesetval->nodeNr; i++) {
xmlXPathFreeObject(zone_nodes);
xmlXPathFreeContext(zone_path_context);
- return (0);
+ return 0;
} /* }}} int bind_xml_stats_search_zones */
static int bind_xml_stats_handle_view(int version, xmlDoc *doc, /* {{{ */
if (view_name == NULL) {
ERROR("bind plugin: Could not determine view name.");
- return (-1);
+ return -1;
}
for (j = 0; j < views_num; j++) {
path_obj = xmlXPathEvalExpression(BAD_CAST "name", path_ctx);
if (path_obj == NULL) {
ERROR("bind plugin: xmlXPathEvalExpression failed.");
- return (-1);
+ return -1;
}
for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr);
if (view_name == NULL) {
ERROR("bind plugin: Could not determine view name.");
xmlXPathFreeObject(path_obj);
- return (-1);
+ return -1;
}
for (j = 0; j < views_num; j++) {
}
if (j >= views_num)
- return (0);
+ return 0;
view = views + j;
list_info_ptr_t list_info = {plugin_instance,
/* type = */ "dns_qtype"};
- ssnprintf(plugin_instance, sizeof(plugin_instance), "%s-qtypes",
- view->name);
+ snprintf(plugin_instance, sizeof(plugin_instance), "%s-qtypes", view->name);
if (version == 3) {
bind_parse_generic_name_attr_value_list(
/* xpath = */ "counters[@type='resqtype']",
resstats_translation_table_length,
plugin_instance};
- ssnprintf(plugin_instance, sizeof(plugin_instance), "%s-resolver_stats",
- view->name);
+ snprintf(plugin_instance, sizeof(plugin_instance), "%s-resolver_stats",
+ view->name);
if (version == 3) {
bind_parse_generic_name_attr_value_list(
"counters[@type='resstats']",
list_info_ptr_t list_info = {plugin_instance,
/* type = */ "dns_qtype_cached"};
- ssnprintf(plugin_instance, sizeof(plugin_instance), "%s-cache_rr_sets",
- view->name);
+ snprintf(plugin_instance, sizeof(plugin_instance), "%s-cache_rr_sets",
+ view->name);
bind_parse_generic_name_value(/* xpath = */ "cache/rrset",
/* callback = */ bind_xml_list_callback,
bind_xml_stats_search_zones(version, doc, path_ctx, node, view,
current_time);
- return (0);
+ return 0;
} /* }}} int bind_xml_stats_handle_view */
static int bind_xml_stats_search_views(int version, xmlDoc *doc, /* {{{ */
view_path_context = xmlXPathNewContext(doc);
if (view_path_context == NULL) {
ERROR("bind plugin: xmlXPathNewContext failed.");
- return (-1);
+ return -1;
}
view_nodes = xmlXPathEvalExpression(BAD_CAST "views/view", xpathCtx);
if (view_nodes == NULL) {
ERROR("bind plugin: Cannot find any <view> tags.");
xmlXPathFreeContext(view_path_context);
- return (-1);
+ return -1;
}
for (int i = 0; i < view_nodes->nodesetval->nodeNr; i++) {
xmlXPathFreeObject(view_nodes);
xmlXPathFreeContext(view_path_context);
- return (0);
+ return 0;
} /* }}} int bind_xml_stats_search_views */
static void bind_xml_stats_v3(xmlDoc *doc, /* {{{ */
¤t_time);
if (status != 0) {
ERROR("bind plugin: Reading `server/current-time' failed.");
- return (-1);
+ return -1;
}
DEBUG("bind plugin: Current server time is %i.", (int)current_time);
doc = xmlParseMemory(data, strlen(data));
if (doc == NULL) {
ERROR("bind plugin: xmlParseMemory failed.");
- return (-1);
+ return -1;
}
xpathCtx = xmlXPathNewContext(doc);
if (xpathCtx == NULL) {
ERROR("bind plugin: xmlXPathNewContext failed.");
xmlFreeDoc(doc);
- return (-1);
+ return -1;
}
//
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
- return (ret);
+ return ret;
}
//
ERROR("bind plugin: Cannot find the <statistics> tag.");
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
- return (-1);
+ return -1;
} else if (xpathObj->nodesetval == NULL) {
ERROR("bind plugin: xmlXPathEvalExpression failed.");
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
- return (-1);
+ return -1;
}
for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++) {
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
- return (ret);
+ return ret;
} /* }}} int bind_xml */
static int bind_config_set_bool(const char *name, int *var, /* {{{ */
WARNING("bind plugin: The `%s' option needs "
"exactly one boolean argument.",
name);
- return (-1);
+ return -1;
}
if (ci->values[0].value.boolean)
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("bind plugin: The `Zone' option needs "
"exactly one string argument.");
- return (-1);
+ return -1;
}
tmp = realloc(view->zones, sizeof(char *) * (view->zones_num + 1));
if (tmp == NULL) {
ERROR("bind plugin: realloc failed.");
- return (-1);
+ return -1;
}
view->zones = tmp;
view->zones[view->zones_num] = strdup(ci->values[0].value.string);
if (view->zones[view->zones_num] == NULL) {
ERROR("bind plugin: strdup failed.");
- return (-1);
+ return -1;
}
view->zones_num++;
- return (0);
+ return 0;
} /* }}} int bind_config_add_view_zone */
static int bind_config_add_view(oconfig_item_t *ci) /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("bind plugin: `View' blocks need exactly one string argument.");
- return (-1);
+ return -1;
}
tmp = realloc(views, sizeof(*views) * (views_num + 1));
if (tmp == NULL) {
ERROR("bind plugin: realloc failed.");
- return (-1);
+ return -1;
}
views = tmp;
tmp = views + views_num;
if (tmp->name == NULL) {
ERROR("bind plugin: strdup failed.");
sfree(views);
- return (-1);
+ return -1;
}
for (int i = 0; i < ci->children_num; i++) {
} /* for (i = 0; i < ci->children_num; i++) */
views_num++;
- return (0);
+ return 0;
} /* }}} int bind_config_add_view */
static int bind_config(oconfig_item_t *ci) /* {{{ */
(child->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("bind plugin: The `Url' option needs "
"exactly one string argument.");
- return (-1);
+ return -1;
}
sfree(url);
}
}
- return (0);
+ return 0;
} /* }}} int bind_config */
static int bind_init(void) /* {{{ */
{
if (curl != NULL)
- return (0);
+ return 0;
curl = curl_easy_init();
if (curl == NULL) {
ERROR("bind plugin: bind_init: curl_easy_init failed.");
- return (-1);
+ return -1;
}
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
plugin_get_interval()));
#endif
- return (0);
+ return 0;
} /* }}} int bind_init */
static int bind_read(void) /* {{{ */
if (curl == NULL) {
ERROR("bind plugin: I don't have a CURL object.");
- return (-1);
+ return -1;
}
bind_buffer_fill = 0;
if (curl_easy_perform(curl) != CURLE_OK) {
ERROR("bind plugin: curl_easy_perform failed: %s", bind_curl_error);
- return (-1);
+ return -1;
}
status = bind_xml(bind_buffer);
if (status != 0)
- return (-1);
+ return -1;
else
- return (0);
+ return 0;
} /* }}} int bind_read */
static int bind_shutdown(void) /* {{{ */
curl = NULL;
}
- return (0);
+ return 0;
} /* }}} int bind_shutdown */
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 : */
uint64_t avgcount;
/** current index of counters - used to get type of counter */
int index;
- /** do we already have an avgcount for latency pair */
- int avgcount_exists;
/**
* similar to index, but current index of latency type counters -
* used to get last poll data of counter
yajl_struct *state = (yajl_struct *)ctx;
char buffer[number_len + 1];
char key[2 * DATA_MAX_NAME_LEN] = {0};
- _Bool latency_type = 0;
int status;
memcpy(buffer, number_val, number_len);
BUFFER_ADD(key, state->stack[i]);
}
- /* Special case for latency metrics. */
- if ((strcmp("avgcount", state->key) == 0) ||
- (strcmp("sum", state->key) == 0)) {
- latency_type = 1;
-
- /* depth >= 2 => (stack[-1] != NULL && stack[-2] != NULL) */
- assert((state->depth < 2) || ((state->stack[state->depth - 1] != NULL) &&
- (state->stack[state->depth - 2] != NULL)));
-
- /* Super-special case for filestore.journal_wr_bytes.avgcount: For
- * some reason, Ceph schema encodes this as a count/sum pair while all
- * other "Bytes" data (excluding used/capacity bytes for OSD space) uses
- * a single "Derive" type. To spare further confusion, keep this KPI as
- * the same type of other "Bytes". Instead of keeping an "average" or
- * "rate", use the "sum" in the pair and assign that to the derive
- * value. */
- if (convert_special_metrics && (state->depth >= 2) &&
- (strcmp("filestore", state->stack[state->depth - 2]) == 0) &&
- (strcmp("journal_wr_bytes", state->stack[state->depth - 1]) == 0) &&
- (strcmp("avgcount", state->key) == 0)) {
- DEBUG("ceph plugin: Skipping avgcount for filestore.JournalWrBytes");
- return CEPH_CB_CONTINUE;
- }
- } else /* not a latency type */
- {
- BUFFER_ADD(key, ".");
- BUFFER_ADD(key, state->key);
+ /* Super-special case for filestore.journal_wr_bytes.avgcount: For
+ * some reason, Ceph schema encodes this as a count/sum pair while all
+ * other "Bytes" data (excluding used/capacity bytes for OSD space) uses
+ * a single "Derive" type. To spare further confusion, keep this KPI as
+ * the same type of other "Bytes". Instead of keeping an "average" or
+ * "rate", use the "sum" in the pair and assign that to the derive
+ * value. */
+ if (convert_special_metrics && (state->depth >= 2) &&
+ (strcmp("filestore", state->stack[state->depth - 2]) == 0) &&
+ (strcmp("journal_wr_bytes", state->stack[state->depth - 1]) == 0) &&
+ (strcmp("avgcount", state->key) == 0)) {
+ DEBUG("ceph plugin: Skipping avgcount for filestore.JournalWrBytes");
+ return CEPH_CB_CONTINUE;
}
- status = state->handler(state->handler_arg, buffer, key);
- if ((status == RETRY_AVGCOUNT) && latency_type) {
- /* Add previously skipped part of the key, either "avgcount" or "sum",
- * and try again. */
- BUFFER_ADD(key, ".");
- BUFFER_ADD(key, state->key);
+ BUFFER_ADD(key, ".");
+ BUFFER_ADD(key, state->key);
- status = state->handler(state->handler_arg, buffer, key);
- }
+ status = state->handler(state->handler_arg, buffer, key);
if (status != 0) {
ERROR("ceph plugin: JSON handler failed with status %d.", status);
}
/* compact_ds_name removed the special characters ":", "_", "-" and "+" from the
- * intput string. Characters following these special characters are capitalized.
+ * input string. Characters following these special characters are capitalized.
* Trailing "+" and "-" characters are replaces with the strings "Plus" and
* "Minus". */
static int compact_ds_name(char *buffer, size_t buffer_size, char const *src) {
return 0;
}
+static void cut_suffix(char *buffer, size_t buffer_size, char const *str,
+ char const *suffix) {
+
+ size_t str_len = strlen(str);
+ size_t suffix_len = strlen(suffix);
+
+ size_t offset = str_len - suffix_len + 1;
+
+ if (offset > buffer_size) {
+ offset = buffer_size;
+ }
+
+ sstrncpy(buffer, str, offset);
+}
+
/* count_parts returns the number of elements a "foo.bar.baz" style key has. */
static size_t count_parts(char const *key) {
size_t parts_num = 0;
*/
static int parse_keys(char *buffer, size_t buffer_size, const char *key_str) {
char tmp[2 * buffer_size];
+ size_t tmp_size = sizeof(tmp);
+ const char *cut_suffixes[] = {".type", ".avgcount", ".sum", ".avgtime"};
if (buffer == NULL || buffer_size == 0 || key_str == NULL ||
strlen(key_str) == 0)
return EINVAL;
- if ((count_parts(key_str) > 2) && has_suffix(key_str, ".type")) {
- /* strip ".type" suffix iff the key has more than two parts. */
- size_t sz = strlen(key_str) - strlen(".type") + 1;
+ sstrncpy(tmp, key_str, tmp_size);
- if (sz > sizeof(tmp))
- sz = sizeof(tmp);
- sstrncpy(tmp, key_str, sz);
- } else {
- sstrncpy(tmp, key_str, sizeof(tmp));
+ /* Strip suffix if it is ".type" or one of latency metric suffix. */
+ if (count_parts(key_str) > 2) {
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE(cut_suffixes); i++) {
+ if (has_suffix(key_str, cut_suffixes[i])) {
+ cut_suffix(tmp, tmp_size, key_str, cut_suffixes[i]);
+ break;
+ }
+ }
}
return compact_ds_name(buffer, buffer_size, tmp);
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("ceph plugin: `Daemon' blocks need exactly one string "
"argument.");
- return (-1);
+ return -1;
}
ret = cc_handle_str(ci, cd.name, DATA_MAX_NAME_LEN);
switch (type) {
case DSET_LATENCY:
- if (vtmp->avgcount_exists == -1) {
+ if (has_suffix(key, ".avgcount")) {
sscanf(val, "%" PRIu64, &vtmp->avgcount);
- vtmp->avgcount_exists = 0;
// return after saving avgcount - don't dispatch value
// until latency calculation
return 0;
- } else {
- double sum, result;
- sscanf(val, "%lf", &sum);
-
+ } else if (has_suffix(key, ".sum")) {
if (vtmp->avgcount == 0) {
vtmp->avgcount = 1;
}
-
- /** User wants latency values as long run avg */
+ // user wants latency values as long run avg
+ // skip this step
if (long_run_latency_avg) {
- result = (sum / vtmp->avgcount);
- } else {
- result = get_last_avg(vtmp->d, ds_name, vtmp->latency_index, sum,
- vtmp->avgcount);
- if (result == -ENOMEM) {
- return -ENOMEM;
- }
+ return 0;
}
+ double sum, result;
+ sscanf(val, "%lf", &sum);
+ result = get_last_avg(vtmp->d, ds_name, vtmp->latency_index, sum,
+ vtmp->avgcount);
+ if (result == -ENOMEM) {
+ return -ENOMEM;
+ }
+ uv.gauge = result;
+ vtmp->latency_index = (vtmp->latency_index + 1);
+ } else if (has_suffix(key, ".avgtime")) {
+ /* The "avgtime" metric reports ("sum" / "avgcount"), i.e. the average
+ * time per request since the start of the Ceph daemon. Report this only
+ * when the user has configured "long running average". Otherwise, use the
+ * rate of "sum" and "avgcount" to calculate the current latency.
+ */
+
+ if (!long_run_latency_avg) {
+ return 0;
+ }
+ double result;
+ sscanf(val, "%lf", &result);
uv.gauge = result;
- vtmp->avgcount_exists = -1;
vtmp->latency_index = (vtmp->latency_index + 1);
+ } else {
+ WARNING("ceph plugin: ignoring unknown latency metric: %s", key);
+ return 0;
}
break;
case DSET_BYTES:
sizeof(vtmp->vlist.plugin_instance));
vtmp->d = io->d;
- vtmp->avgcount_exists = -1;
vtmp->latency_index = 0;
vtmp->index = 0;
yajl->handler_arg = vtmp;
plugin_register_read("ceph", ceph_read);
plugin_register_shutdown("ceph", ceph_shutdown);
}
-/* vim: set sw=4 sts=4 et : */
{"WBThrottle.ios_wb.type", "2"},
{"WBThrottle.inodes_dirtied.type", "2"},
{"WBThrottle.inodes_wb.type", "10"},
- {"filestore.journal_wr_bytes", "3117"},
+ {"filestore.journal_wr_bytes.sum", "3117"},
{"filestore.example_latency.avgcount", "42"},
{"filestore.example_latency.sum", "4711"},
};
END_TEST;
}
-
-/* vim: set sw=2 sts=2 et : */
FILE *fh;
if (ignorelist_match(il_cgroup, cgroup_name))
- return (0);
+ return 0;
- ssnprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, cgroup_name);
+ snprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, cgroup_name);
status = lstat(abs_path, &statbuf);
if (status != 0) {
ERROR("cgroups plugin: stat (\"%s\") failed.", abs_path);
- return (-1);
+ return -1;
}
/* We are only interested in directories, so skip everything else. */
if (!S_ISDIR(statbuf.st_mode))
- return (0);
+ return 0;
- ssnprintf(abs_path, sizeof(abs_path), "%s/%s/cpuacct.stat", dirname,
- cgroup_name);
+ snprintf(abs_path, sizeof(abs_path), "%s/%s/cpuacct.stat", dirname,
+ cgroup_name);
fh = fopen(abs_path, "r");
if (fh == NULL) {
char errbuf[1024];
ERROR("cgroups plugin: fopen (\"%s\") failed: %s", abs_path,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
while (fgets(buf, sizeof(buf), fh) != NULL) {
}
fclose(fh);
- return (0);
+ return 0;
} /* int read_cpuacct_procs */
/*
struct stat statbuf;
int status;
- ssnprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, filename);
+ snprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, filename);
status = lstat(abs_path, &statbuf);
if (status != 0) {
ERROR("cgroups plugin: stat (%s) failed.", abs_path);
- return (-1);
+ return -1;
}
if (S_ISDIR(statbuf.st_mode)) {
status = walk_directory(abs_path, read_cpuacct_procs,
/* user_data = */ NULL,
/* include_hidden = */ 0);
- return (status);
+ return status;
}
- return (0);
+ return 0;
}
static int cgroups_init(void) {
if (il_cgroup == NULL)
il_cgroup = ignorelist_create(1);
- return (0);
+ return 0;
}
static int cgroups_config(const char *key, const char *value) {
if (strcasecmp(key, "CGroup") == 0) {
if (ignorelist_add(il_cgroup, value))
- return (1);
- return (0);
+ return 1;
+ return 0;
} else if (strcasecmp(key, "IgnoreSelected") == 0) {
if (IS_TRUE(value))
ignorelist_set_invert(il_cgroup, 0);
else
ignorelist_set_invert(il_cgroup, 1);
- return (0);
+ return 0;
}
- return (-1);
+ return -1;
}
static int cgroups_read(void) {
if (cu_mount_getlist(&mnt_list) == NULL) {
ERROR("cgroups plugin: cu_mount_getlist failed.");
- return (-1);
+ return -1;
}
for (cu_mount_t *mnt_ptr = mnt_list; mnt_ptr != NULL;
if (!cgroup_found) {
WARNING("cgroups plugin: Unable to find cgroup "
"mount-point with the \"cpuacct\" option.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int cgroup_read */
void module_register(void) {
#define IPADDR_INET4 1
#define IPADDR_INET6 2
#define IPV6_STR_MAX_SIZE (8 * 4 + 7 + 1)
+#define MODE_REFCLOCK 2
typedef enum { PKT_TYPE_CMD_REQUEST = 1, PKT_TYPE_CMD_REPLY = 2 } ePacketType;
uint8_t ip6[16];
} addr;
uint16_t f_family;
+ uint16_t padding;
} tChrony_IPAddr;
typedef struct ATTRIB_PACKED {
tChrony_IPAddr addr;
- uint16_t
- dummy; /* FIXME: Strange dummy space. Needed on gcc 4.8.3/clang 3.4.1 on
- x86_64 */
int16_t f_poll; /* 2^f_poll = Time between polls (s) */
uint16_t f_stratum; /* Remote clock stratum */
uint16_t f_state; /* 0 = RPY_SD_ST_SYNC, 1 = RPY_SD_ST_UNREACH, 2 =
typedef struct ATTRIB_PACKED {
uint32_t f_ref_id;
tChrony_IPAddr addr;
- uint16_t
- dummy; /* FIXME: Strange dummy space. Needed on gcc 4.8.3/clang 3.4.1 on
- x86_64 */
uint32_t f_n_samples; /* Number of measurements done */
uint32_t f_n_runs; /* How many measurements to come */
uint32_t f_span_seconds; /* For how long we're measuring */
typedef struct ATTRIB_PACKED {
uint32_t f_ref_id;
tChrony_IPAddr addr;
- uint16_t
- dummy; /* FIXME: Strange dummy space. Needed on gcc 4.8.3/clang 3.4.1 on
- x86_64 */
uint16_t f_stratum;
uint16_t f_leap_status;
tTimeval f_ref_time;
return p_buf;
}
+static void nreftostr(uint32_t nrefid, char *p_buf, size_t p_buf_size) {
+ size_t j = 0;
+
+ for (int i = 0; i < 4; i++) {
+ int c = ntohl(nrefid) << i * 8 >> 24;
+ if (!isalnum(c) || j + 1 >= p_buf_size)
+ continue;
+ p_buf[j++] = c;
+ }
+ if (j < p_buf_size)
+ p_buf[j] = '\0';
+}
+
static int chrony_set_timeout(void) {
/* Set the socket's timeout to g_chrony_timeout; a value of 0 signals
* infinite timeout */
uint32_t uval;
uval = ntohl(p_float.value);
- exp = (uval >> FLOAT_COEF_BITS) - FLOAT_COEF_BITS;
+ exp = (uval >> FLOAT_COEF_BITS);
if (exp >= 1 << (FLOAT_EXP_BITS - 1))
exp -= 1 << FLOAT_EXP_BITS;
+ exp -= FLOAT_COEF_BITS;
/* coef = (x << FLOAT_EXP_BITS) >> FLOAT_EXP_BITS; */
coef = uval % (1U << FLOAT_COEF_BITS);
return CHRONY_RC_OK;
}
-static int chrony_request_source_data(int p_src_idx, int *p_is_reachable) {
+static int chrony_request_source_data(int p_src_idx, char *src_addr,
+ size_t addr_size, int *p_is_reachable) {
/* Perform Source data request for source #p_src_idx */
int rc;
size_t chrony_resp_size;
tChrony_Request chrony_req;
tChrony_Response chrony_resp;
- char src_addr[IPV6_STR_MAX_SIZE] = {0};
-
chrony_init_req(&chrony_req);
chrony_req.body.source_data.f_index = htonl(p_src_idx);
rc = chrony_query(REQ_SOURCE_DATA, &chrony_req, &chrony_resp,
return rc;
}
- niptoha(&chrony_resp.body.source_data.addr, src_addr, sizeof(src_addr));
+ if (ntohs(chrony_resp.body.source_data.f_mode) == MODE_REFCLOCK)
+ nreftostr(chrony_resp.body.source_data.addr.addr.ip4, src_addr, addr_size);
+ else
+ niptoha(&chrony_resp.body.source_data.addr, src_addr, addr_size);
+
DEBUG(PLUGIN_NAME ": Source[%d] data: .addr = %s, .poll = %u, .stratum = %u, "
".state = %u, .mode = %u, .flags = %u, .reach = %u, "
".latest_meas_ago = %u, .orig_latest_meas = %f, "
chrony_push_data_valid("clock_reachability", src_addr, is_reachable,
ntohs(chrony_resp.body.source_data.f_reachability));
chrony_push_data_valid("clock_last_meas", src_addr, is_reachable,
- ntohs(chrony_resp.body.source_data.f_since_sample));
+ ntohl(chrony_resp.body.source_data.f_since_sample));
+ chrony_push_data_valid(
+ "time_offset", src_addr, is_reachable,
+ ntohf(chrony_resp.body.source_data.f_origin_latest_meas));
return CHRONY_RC_OK;
}
-static int chrony_request_source_stats(int p_src_idx,
+static int chrony_request_source_stats(int p_src_idx, const char *src_addr,
const int *p_is_reachable) {
/* Perform Source stats request for source #p_src_idx */
int rc;
size_t chrony_resp_size;
tChrony_Request chrony_req;
tChrony_Response chrony_resp;
- double skew_ppm, frequency_error, time_offset;
-
- char src_addr[IPV6_STR_MAX_SIZE] = {0};
+ double skew_ppm, frequency_error;
if (*p_is_reachable == 0) {
skew_ppm = 0;
frequency_error = 0;
- time_offset = 0;
} else {
chrony_init_req(&chrony_req);
chrony_req.body.source_stats.f_index = htonl(p_src_idx);
skew_ppm = ntohf(chrony_resp.body.source_stats.f_skew_ppm);
frequency_error = ntohf(chrony_resp.body.source_stats.f_rtc_gain_rate_ppm);
- time_offset = ntohf(chrony_resp.body.source_stats.f_est_offset);
- niptoha(&chrony_resp.body.source_stats.addr, src_addr, sizeof(src_addr));
DEBUG(PLUGIN_NAME
": Source[%d] stat: .addr = %s, .ref_id= %u, .n_samples = %u, "
".n_runs = %u, .span_seconds = %u, .rtc_seconds_fast = %f, "
ntohl(chrony_resp.body.source_stats.f_n_runs),
ntohl(chrony_resp.body.source_stats.f_span_seconds),
ntohf(chrony_resp.body.source_stats.f_rtc_seconds_fast),
- frequency_error, skew_ppm, time_offset,
+ frequency_error, skew_ppm,
+ ntohf(chrony_resp.body.source_stats.f_est_offset),
ntohf(chrony_resp.body.source_stats.f_est_offset_err));
} /* if (*is_reachable) */
chrony_push_data_valid("clock_skew_ppm", src_addr, *p_is_reachable, skew_ppm);
chrony_push_data_valid("frequency_error", src_addr, *p_is_reachable,
frequency_error); /* unit: ppm */
- chrony_push_data_valid("time_offset", src_addr, *p_is_reachable,
- time_offset); /* unit: s */
return CHRONY_RC_OK;
}
return rc;
for (unsigned int now_src = 0; now_src < n_sources; ++now_src) {
+ char src_addr[IPV6_STR_MAX_SIZE] = {0};
int is_reachable;
- rc = chrony_request_source_data(now_src, &is_reachable);
+ rc = chrony_request_source_data(now_src, src_addr, sizeof(src_addr),
+ &is_reachable);
if (rc != CHRONY_RC_OK)
return rc;
- rc = chrony_request_source_stats(now_src, &is_reachable);
+ rc = chrony_request_source_stats(now_src, src_addr, &is_reachable);
if (rc != CHRONY_RC_OK)
return rc;
}
#endif
#endif /* NAN_ZERO_ZERO */
-#include "libcollectdclient/collectd/client.h"
+#include "collectd/client.h"
#define RET_OKAY 0
#define RET_WARNING 1
ret = (char *)malloc(strsize);
if (ret != NULL)
memcpy(ret, str, strsize);
- return (ret);
+ return ret;
} /* }}} char *cn_strdup */
static int filter_ds(size_t *values_num, double **values,
char **new_names;
if (match_ds_g == NULL)
- return (RET_OKAY);
+ return RET_OKAY;
new_values = (gauge_t *)calloc(match_ds_num_g, sizeof(*new_values));
if (new_values == NULL) {
fprintf(stderr, "calloc failed: %s\n", strerror(errno));
- return (RET_UNKNOWN);
+ return RET_UNKNOWN;
}
new_names = (char **)calloc(match_ds_num_g, sizeof(*new_names));
if (new_names == NULL) {
fprintf(stderr, "calloc failed: %s\n", strerror(errno));
free(new_values);
- return (RET_UNKNOWN);
+ return RET_UNKNOWN;
}
for (size_t i = 0; i < match_ds_num_g; i++) {
for (j = 0; j < i; j++)
free(new_names[j]);
free(new_names);
- return (RET_UNKNOWN);
+ return RET_UNKNOWN;
}
for (j = 0; j < *values_num; j++)
for (j = 0; j <= i; j++)
free(new_names[j]);
free(new_names);
- return (RET_CRITICAL);
+ return RET_CRITICAL;
}
new_values[i] = (*values)[j];
*values = new_values;
*values_names = new_names;
*values_num = match_ds_num_g;
- return (RET_OKAY);
+ return RET_OKAY;
} /* int filter_ds */
static void parse_range(char *string, range_t *range) {
if (!isnan(range->max) && (range->max < value))
ret = 1;
- return (((ret - range->invert) == 0) ? 0 : 1);
+ return ((ret - range->invert) == 0) ? 0 : 1;
} /* int match_range */
__attribute__((noreturn)) static void usage(const char *name) {
printf("UNKNOWN: %s\n", lcc_strerror(connection));
if (ret_ident != NULL)
free(ret_ident);
- return (RET_UNKNOWN);
+ return RET_UNKNOWN;
}
status = lcc_sort_identifiers(connection, ret_ident, ret_ident_num);
printf("UNKNOWN: %s\n", lcc_strerror(connection));
if (ret_ident != NULL)
free(ret_ident);
- return (RET_UNKNOWN);
+ return RET_UNKNOWN;
}
for (size_t i = 0; i < ret_ident_num; ++i) {
free(ret_ident);
free(hostname);
- return (RET_OKAY);
+ return RET_OKAY;
} /* int do_listval */
static int do_check_con_none(size_t values_num, double *values,
if ((num_critical == 0) && (num_warning == 0) && (num_okay == 0)) {
printf("WARNING: No defined values found\n");
- return (RET_WARNING);
+ return RET_WARNING;
} else if ((num_critical == 0) && (num_warning == 0)) {
status_str = "OKAY";
status_code = RET_OKAY;
}
printf("\n");
- return (status_code);
+ return status_code;
} /* int do_check_con_none */
static int do_check_con_average(size_t values_num, double *values,
continue;
printf("CRITICAL: Data source \"%s\" is NaN\n", values_names[i]);
- return (RET_CRITICAL);
+ return RET_CRITICAL;
}
total += values[i];
if (total_num == 0) {
printf("WARNING: No defined values found\n");
- return (RET_WARNING);
+ return RET_WARNING;
}
average = total / total_num;
printf(" %s=%f;;;;", values_names[i], values[i]);
printf("\n");
- return (status_code);
+ return status_code;
} /* int do_check_con_average */
static int do_check_con_sum(size_t values_num, double *values,
continue;
printf("CRITICAL: Data source \"%s\" is NaN\n", values_names[i]);
- return (RET_CRITICAL);
+ return RET_CRITICAL;
}
total += values[i];
if (total_num == 0) {
printf("WARNING: No defined values found\n");
- return (RET_WARNING);
+ return RET_WARNING;
}
if (match_range(&range_critical_g, total) != 0) {
printf(" %s=%f;;;;", values_names[i], values[i]);
printf("\n");
- return (status_code);
+ return status_code;
} /* int do_check_con_sum */
static int do_check_con_percentage(size_t values_num, double *values,
if ((values_num < 1) || (isnan(values[0]))) {
printf("WARNING: The first value is not defined\n");
- return (RET_WARNING);
+ return RET_WARNING;
}
for (size_t i = 0; i < values_num; i++) {
continue;
printf("CRITICAL: Data source \"%s\" is NaN\n", values_names[i]);
- return (RET_CRITICAL);
+ return RET_CRITICAL;
}
sum += values[i];
if (sum == 0.0) {
printf("WARNING: Values sum up to zero\n");
- return (RET_WARNING);
+ return RET_WARNING;
}
percentage = 100.0 * values[0] / sum;
printf("%s: %lf percent |", status_str, percentage);
for (size_t i = 0; i < values_num; i++)
printf(" %s=%lf;;;;", values_names[i], values[i]);
- return (status_code);
+ return status_code;
} /* int do_check_con_percentage */
static int do_check(lcc_connection_t *connection) {
printf("ERROR: Creating an identifier failed: %s.\n",
lcc_strerror(connection));
LCC_DESTROY(connection);
- return (RET_CRITICAL);
+ return RET_CRITICAL;
}
status = lcc_getval(connection, &ident, &values_num, &values, &values_names);
printf("ERROR: Retrieving values from the daemon failed: %s.\n",
lcc_strerror(connection));
LCC_DESTROY(connection);
- return (RET_CRITICAL);
+ return RET_CRITICAL;
}
LCC_DESTROY(connection);
status = filter_ds(&values_num, &values, &values_names);
if (status != RET_OKAY)
- return (status);
+ return status;
status = RET_UNKNOWN;
if (consolitation_g == CON_NONE)
free(values_names[i]);
free(values_names);
- return (status);
+ return status;
} /* int do_check */
int main(int argc, char **argv) {
tmp = realloc(match_ds_g, (match_ds_num_g + 1) * sizeof(char *));
if (tmp == NULL) {
fprintf(stderr, "realloc failed: %s\n", strerror(errno));
- return (RET_UNKNOWN);
+ return RET_UNKNOWN;
}
match_ds_g = tmp;
match_ds_g[match_ds_num_g] = cn_strdup(optarg);
if (match_ds_g[match_ds_num_g] == NULL) {
fprintf(stderr, "cn_strdup failed: %s\n", strerror(errno));
- return (RET_UNKNOWN);
+ return RET_UNKNOWN;
}
match_ds_num_g++;
break;
status = lcc_connect(address, &connection);
if (status != 0) {
printf("ERROR: Connecting to daemon at %s failed.\n", socket_file_g);
- return (RET_CRITICAL);
+ return RET_CRITICAL;
}
if (0 == strcasecmp(value_string_g, "LIST"))
- return (do_listval(connection));
+ return do_listval(connection);
- return (do_check(connection));
+ return do_check(connection);
} /* int main */
If a Python script throws an exception it will be logged by collectd with the
name of the exception and the message. If you set this option to true it will
also log the full stacktrace just like the default output of an interactive
-Python interpreter. This should probably be set to false most of the time but
-is very useful for development and debugging of new modules.
+Python interpreter. This does not apply to the CollectError exception, which
+will never log a stacktrace.
+This should probably be set to false most of the time but is very useful for
+development and debugging of new modules.
=item B<Interactive> I<bool>
The following complex types are used to pass values between the Python plugin
and collectd:
+=head2 CollectdError
+
+This is an exception. If any Python script raises this exception it will
+still be treated like an error by collectd but it will be logged as a
+warning instead of an error and it will never generate a stacktrace.
+
+ class CollectdError(Exception)
+
+Basic exception for collectd Python scripts.
+Throwing this exception will not cause a stacktrace to be logged, even if
+LogTraces is enabled in the config.
+
=head2 Signed
The Signed class is just a long. It has all its methods and behaves exactly
=over 4
-=item B<dispatch>([type][, message][, plugin_instance][, type_instance][, plugin][, host][, time][, severity]) -> None. Dispatch a notification.
+=item B<dispatch>([type][, message][, plugin_instance][, type_instance][, plugin][, host][, time][, severity][, meta]) -> None. Dispatch a notification.
Dispatch this instance to the collectd process. The object has members for each
of the possible arguments for this method. For a detailed explanation of these
The severity of this notification. Assign or compare to I<NOTIF_FAILURE>,
I<NOTIF_WARNING> or I<NOTIF_OKAY>.
+=item meta
+
+These are the meta data for the Notification object.
+It has to be a dictionary of numbers, strings or bools. All keys must be
+strings. I<int> and I<long> objects will be dispatched as signed integers unless
+they are between 2**63 and 2**64-1, which will result in a unsigned integer.
+One of these storage classes can be forced by using the classes
+B<collectd.Signed> and B<collectd.Unsigned>. A meta object received by a
+notification callback will always contain B<Signed> or B<Unsigned> objects.
+
=back
=head1 FUNCTIONS
=item *
Not all aspects of the collectd API are accessible from Python. This includes
-but is not limited to filters and data sets.
+but is not limited to filters.
=back
Community "community_string"
Collect "std_traffic"
Interval 120
+ Timeout 10
+ Retries 1
</Host>
<Host "some.server.mydomain.org">
Address "192.168.0.42"
Collect "std_traffic" "hr_users"
</Host>
<Host "secure.router.mydomain.org">
- Address "192.168.0.7"
+ Address "192.168.0.7:165"
Version 3
SecurityLevel "authPriv"
Username "cosmo"
Collect "std_traffic"
</Host>
<Host "some.ups.mydomain.org">
- Address "192.168.0.3"
+ Address "tcp:192.168.0.3"
Version 1
Community "more_communities"
Collect "powerplus_voltge_input"
Interval 300
+ Timeout 5
+ Retries 5
</Host>
</Plugin>
=head1 CONFIGURATION
Since the aim of the C<snmp plugin> is to provide a generic interface to SNMP,
-it's configuration is not trivial and may take some time.
+its configuration is not trivial and may take some time.
Since the C<Net-SNMP> library is used you can use all the environment variables
that are interpreted by that package. See L<snmpcmd(1)> for more details.
=item B<Address> I<IP-Address>|I<Hostname>
-Set the address to connect to.
+Set the address to connect to. Address may include transport specifier and/or
+port number.
=item B<Version> B<1>|B<2>|B<3>
B<Step> of generated RRD files depends on this setting it's wise to select a
reasonable value once and never change it.
+=item B<Timeout> I<Seconds>
+
+How long to wait for a response. The C<Net-SNMP> library default is 1 second.
+
+=item B<Retries> I<Integer>
+
+The number of times that a query should be retried after the Timeout expires.
+The C<Net-SNMP> library default is 5.
+
=back
=head1 SEE ALSO
#include "utils_heap.h"
-#include "libcollectdclient/collectd/client.h"
-#include "libcollectdclient/collectd/network.h"
+#include "collectd/client.h"
+#include "collectd/network.h"
#define DEF_NUM_HOSTS 1000
#define DEF_NUM_PLUGINS 20
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
perror("clock_gettime");
- return ((double)ts.tv_sec) + (((double)ts.tv_nsec) / 1e9);
+ return (double)ts.tv_sec + (double)ts.tv_nsec / 1e9;
} /* }}} double dtime */
#else
/* Work around for Mac OS X which doesn't have clock_gettime(2). *sigh* */
if (gettimeofday(&tv, /* timezone = */ NULL) != 0)
perror("gettimeofday");
- return ((double)tv.tv_sec) + (((double)tv.tv_usec) / 1e6);
+ return (double)tv.tv_sec + ((double)tv.tv_usec) / 1e6;
} /* }}} double dtime */
#endif
const lcc_value_list_t *vl1 = v1;
if (vl0->time < vl1->time)
- return (-1);
+ return -1;
else if (vl0->time > vl1->time)
- return (1);
+ return 1;
else
- return (0);
+ return 0;
} /* }}} int compare_time */
static int get_boundet_random(int min, int max) /* {{{ */
int range;
if (min >= max)
- return (-1);
+ return -1;
if (min == (max - 1))
- return (min);
+ return min;
range = max - min;
- return (min + ((int)(((double)range) * ((double)random()) /
- (((double)RAND_MAX) + 1.0))));
+ return min + ((int)(((double)range) * ((double)random()) / (((double)RAND_MAX) + 1.0)));
} /* }}} int get_boundet_random */
static lcc_value_list_t *create_value_list(void) /* {{{ */
vl = calloc(1, sizeof(*vl));
if (vl == NULL) {
fprintf(stderr, "calloc failed.\n");
- return (NULL);
+ return NULL;
}
vl->values = calloc(/* nmemb = */ 1, sizeof(*vl->values));
if (vl->values == NULL) {
fprintf(stderr, "calloc failed.\n");
free(vl);
- return (NULL);
+ return NULL;
}
vl->values_types = calloc(/* nmemb = */ 1, sizeof(*vl->values_types));
fprintf(stderr, "calloc failed.\n");
free(vl->values);
free(vl);
- return (NULL);
+ return NULL;
}
vl->values_len = 1;
snprintf(vl->identifier.type_instance, sizeof(vl->identifier.type_instance),
"ti%li", random());
- return (vl);
+ return vl;
} /* }}} int create_value_list */
static void destroy_value_list(lcc_value_list_t *vl) /* {{{ */
vl->time += vl->interval;
- return (0);
+ return 0;
} /* }}} int send_value */
static int get_integer_opt(const char *str, int *ret_value) /* {{{ */
}
*ret_value = tmp;
- return (0);
+ return 0;
} /* }}} int get_integer_opt */
static int get_double_opt(const char *str, double *ret_value) /* {{{ */
}
*ret_value = tmp;
- return (0);
+ return 0;
} /* }}} int get_double_opt */
static int read_options(int argc, char **argv) /* {{{ */
} /* switch (opt) */
} /* while (getopt) */
- return (0);
+ return 0;
} /* }}} int read_options */
int main(int argc, char **argv) /* {{{ */
lcc_network_destroy(net);
exit(EXIT_SUCCESS);
} /* }}} int main */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
#@BUILD_PLUGIN_DF_TRUE@LoadPlugin df
#@BUILD_PLUGIN_DISK_TRUE@LoadPlugin disk
#@BUILD_PLUGIN_DNS_TRUE@LoadPlugin dns
+#@BUILD_PLUGIN_DPDKEVENTS_TRUE@LoadPlugin dpdkevents
#@BUILD_PLUGIN_DPDKSTAT_TRUE@LoadPlugin dpdkstat
#@BUILD_PLUGIN_DRBD_TRUE@LoadPlugin drbd
#@BUILD_PLUGIN_EMAIL_TRUE@LoadPlugin email
#@BUILD_PLUGIN_GRPC_TRUE@LoadPlugin grpc
#@BUILD_PLUGIN_HDDTEMP_TRUE@LoadPlugin hddtemp
#@BUILD_PLUGIN_HUGEPAGES_TRUE@LoadPlugin hugepages
+#@BUILD_PLUGIN_INTEL_PMU_TRUE@LoadPlugin intel_pmu
#@BUILD_PLUGIN_INTEL_RDT_TRUE@LoadPlugin intel_rdt
@BUILD_PLUGIN_INTERFACE_TRUE@@BUILD_PLUGIN_INTERFACE_TRUE@LoadPlugin interface
#@BUILD_PLUGIN_IPC_TRUE@LoadPlugin ipc
#@BUILD_PLUGIN_LVM_TRUE@LoadPlugin lvm
#@BUILD_PLUGIN_MADWIFI_TRUE@LoadPlugin madwifi
#@BUILD_PLUGIN_MBMON_TRUE@LoadPlugin mbmon
+#@BUILD_PLUGIN_MCELOG_TRUE@LoadPlugin mcelog
#@BUILD_PLUGIN_MD_TRUE@LoadPlugin md
#@BUILD_PLUGIN_MEMCACHEC_TRUE@LoadPlugin memcachec
#@BUILD_PLUGIN_MEMCACHED_TRUE@LoadPlugin memcached
#@BUILD_PLUGIN_OPENLDAP_TRUE@LoadPlugin openldap
#@BUILD_PLUGIN_OPENVPN_TRUE@LoadPlugin openvpn
#@BUILD_PLUGIN_ORACLE_TRUE@LoadPlugin oracle
+#@BUILD_PLUGIN_OVS_EVENTS_TRUE@LoadPlugin ovs_events
+#@BUILD_PLUGIN_OVS_STATS_TRUE@LoadPlugin ovs_stats
#@BUILD_PLUGIN_PERL_TRUE@LoadPlugin perl
#@BUILD_PLUGIN_PINBA_TRUE@LoadPlugin pinba
#@BUILD_PLUGIN_PING_TRUE@LoadPlugin ping
#@BUILD_PLUGIN_SIGROK_TRUE@LoadPlugin sigrok
#@BUILD_PLUGIN_SMART_TRUE@LoadPlugin smart
#@BUILD_PLUGIN_SNMP_TRUE@LoadPlugin snmp
+#@BUILD_PLUGIN_SNMP_AGENT_TRUE@LoadPlugin snmp_agent
#@BUILD_PLUGIN_STATSD_TRUE@LoadPlugin statsd
#@BUILD_PLUGIN_SWAP_TRUE@LoadPlugin swap
#@BUILD_PLUGIN_TABLE_TRUE@LoadPlugin table
# ReportByCpu true
# ReportByState true
# ValuesPercentage false
+# ReportNumCpu false
+# ReportGuestState false
+# SubtractGuestState true
#</Plugin>
#
#<Plugin csv>
#<Plugin curl_xml>
# <URL "http://localhost/stats.xml">
# Host "my_host"
+# #Plugin "stats"
# Instance "some_instance"
# User "collectd"
# Password "thaiNg0I"
# Type "magic_level"
# #InstancePrefix "prefix-"
# InstanceFrom "td[1]"
+# #PluginInstanceFrom "td[1]"
# ValuesFrom "td[2]/span[@class=\"level\"]"
# </XPath>
# </URL>
# </Result>
# </Query>
# <Database "customers_db">
+# #Plugin "mycompany"
# Driver "mysql"
# DriverOption "host" "localhost"
# DriverOption "username" "collectd"
# SelectNumericQueryTypes true
#</Plugin>
+#<Plugin "dpdkevents">
+# <EAL>
+# Coremask "0x1"
+# MemoryChannels "4"
+# FilePrefix "rte"
+# </EAL>
+# <Event "link_status">
+# SendEventsOnUpdate true
+# EnabledPortMask 0xffff
+# PortName "interface1"
+# PortName "interface2"
+# SendNotification false
+# </Event>
+# <Event "keep_alive">
+# SendEventsOnUpdate true
+# LCoreMask "0xf"
+# KeepAliveShmName "/dpdk_keepalive_shm_name"
+# SendNotification false
+# </Event>
+#</Plugin>
+
#<Plugin dpdkstat>
-# Interval 1
-# Coremask "0xf"
-# ProcessType "secondary"
-# FilePrefix "rte"
-# EnabledPortMask 0xffff
-# PortName "interface1"
-# PortName "interface2"
+# <EAL>
+# Coremask "0x2"
+# MemoryChannels "4"
+# FilePrefix "rte"
+# LogLevel "7"
+# RteDriverLibPath "/usr/lib/dpdk-pmd"
+# </EAL>
+# SharedMemObj "dpdk_collectd_stats_0"
+# EnabledPortMask 0xffff
+# PortName "interface1"
+# PortName "interface2"
#</Plugin>
#<Plugin email>
#<Plugin filecount>
# <Directory "/path/to/dir">
+# #Plugin "foo"
# Instance "foodir"
# Name "*.conf"
# MTime "-5m"
# Size "+10k"
# Recursive true
# IncludeHidden false
+# RegularOnly true
+# #FilesSizeType "bytes"
+# #FilesCountType "files"
+# #TypeInstance "instance"
# </Directory>
#</Plugin>
# ValuesPercentage false
#</Plugin>
+#<Plugin intel_pmu>
+# ReportHardwareCacheEvents true
+# ReportKernelPMUEvents true
+# ReportSoftwareEvents true
+# EventList "/var/cache/pmu/GenuineIntel-6-2D-core.json"
+# HardwareEvents "L2_RQSTS.CODE_RD_HIT,L2_RQSTS.CODE_RD_MISS" "L2_RQSTS.ALL_CODE_RD"
+#</Plugin>
+
#<Plugin "intel_rdt">
# Cores "0-2"
#</Plugin>
#</Plugin>
#<Plugin ipmi>
-# Sensor "some_sensor"
-# Sensor "another_one"
-# IgnoreSelected false
-# NotifySensorAdd false
-# NotifySensorRemove true
-# NotifySensorNotPresent false
+# <Instance "local">
+# Sensor "some_sensor"
+# Sensor "another_one"
+# IgnoreSelected false
+# NotifySensorAdd false
+# NotifySensorRemove true
+# NotifySensorNotPresent false
+# NotifyIPMIConnectionState false
+# SELEnabled false
+# SELClearEvent false
+# </Instance>
+# <Instance "remote">
+# Host "server.example.com"
+# Address "1.2.3.4"
+# Username "user"
+# Password "secret"
+# #AuthType "md5"
+# Sensor "some_sensor"
+# Sensor "another_one"
+# IgnoreSelected false
+# NotifySensorAdd false
+# NotifySensorRemove true
+# NotifySensorNotPresent false
+# NotifyIPMIConnectionState false
+# SELEnabled false
+# SELClearEvent false
+# </Instance>
#</Plugin>
#<Plugin iptables>
# Port "411"
#</Plugin>
+#<Plugin mcelog>
+# <Memory>
+# McelogClientSocket "/var/run/mcelog-client"
+# PersistentNotification false
+# </Memory>
+# McelogLogfile "/var/log/mcelog"
+#</Plugin>
+
#<Plugin md>
# Device "/dev/md0"
# IgnoreSelected false
# QoS 2
# Topic "collectd/#"
# CleanSession true
+# CACert "/etc/ssl/ca.crt"
+# CertificateFile "/etc/ssl/client.crt"
+# CertificateKeyFile "/etc/ssl/client.pem"
+# TLSProtocol "tlsv1.2"
+# CipherSuite "ciphers"
# </Subscribe>
#</Plugin>
# CacheFlush 1800
@LOAD_PLUGIN_NETWORK@</Plugin>
+#<Plugin nfs>
+# ReportV2 false
+# #ReportV3 false
+# #ReportV4 false
+#</Plugin>
+
#<Plugin nginx>
# URL "http://localhost/status?auto"
# User "www-user"
#<Plugin nut>
# UPS "upsname@hostname:port"
+# ForceSSL true
+# VerifyPeer true
+# CAPath "/path/to/folder"
+# #ConnectTimeout 5000
#</Plugin>
#<Plugin olsrd>
# </Result>
# </Query>
# <Database "product_information">
+# #Plugin "warehouse"
# ConnectID "db01"
# Username "oracle"
# Password "secret"
# </Database>
#</Plugin>
+#<Plugin ovs_events>
+# Port "6640"
+# Address "127.0.0.1"
+# Socket "/var/run/openvswitch/db.sock"
+# Interfaces "br0" "veth0"
+# SendNotification true
+# DispatchValues false
+#</Plugin>
+
+#<Plugin ovs_stats>
+# Port "6640"
+# Address "127.0.0.1"
+# Socket "/var/run/openvswitch/db.sock"
+# Bridges "br0" "br_ext"
+#</Plugin>
+
#<Plugin perl>
# IncludeDir "/my/include/path"
# BaseName "Collectd::Plugins"
# StoreRates true
# </Writer>
# <Database foo>
+# #Plugin "kingdom"
# Host "hostname"
# Port "5432"
# User "username"
#</Plugin>
#<Plugin processes>
+# CollectFileDescriptor true
+# CollectContextSwitch true
+# CollectMemoryMaps true
# Process "name"
+# ProcessMatch "name" "regex"
+# <Process "collectd">
+# CollectFileDescriptor false
+# CollectContextSwitch false
+# </Process>
+# <ProcessMatch "name" "regex">
+# CollectFileDescriptor false
+# CollectContextSwitch true
+# </Process>
#</Plugin>
#<Plugin protocols>
# Community "community_string"
# Collect "std_traffic"
# Interval 120
+# Timeout 10
+# Retries 1
# </Host>
# <Host "some.server.mydomain.org">
# Address "192.168.0.42"
# Community "more_communities"
# Collect "powerplus_voltge_input"
# Interval 300
+# Timeout 5
+# Retries 5
# </Host>
#</Plugin>
+#<Plugin snmp_agent>
+# <Data "memAvailReal">
+# Plugin "memory"
+# Type "memory"
+# TypeInstance "free"
+# OIDs "1.3.6.1.4.1.2021.4.6.0"
+# </Data>
+# <Table "ifTable">
+# IndexOID "IF-MIB::ifIndex"
+# SizeOID "IF-MIB::ifNumber"
+# <Data "ifDescr">
+# Instance true
+# Plugin "interface"
+# OIDs "IF-MIB::ifDescr"
+# </Data>
+# <Data "ifOctets">
+# Plugin "interface"
+# Type "if_octets"
+# TypeInstance ""
+# OIDs "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets"
+# </Data>
+# </Table>
+#</Plugin>
+
#<Plugin statsd>
# Host "::"
# Port "8125"
# ReportBytes true
# ValuesAbsolute true
# ValuesPercentage false
+# ReportIO true
#</Plugin>
#<Plugin table>
# <Table "/proc/slabinfo">
+# #Plugin "table"
# Instance "slabinfo"
# Separator " "
# <Result>
# Bucket 0.5 1.0 # -> bucket-latency-foo-0.5_1
# Bucket 1.0 2.0 # -> bucket-latency-foo-1_2
# Bucket 2.0 0 # -> bucket-latency-foo-2_inf
+# #BucketType "bucket"
# </DSType>
# Type "latency"
# Instance "foo"
# SystemManagementInterrupt true
# DigitalTemperatureSensor true
# PackageThermalManagement true
-# RunningAveragePowerLimit "7"
+# RunningAveragePowerLimit "7"
#</Plugin>
#<Plugin unixsock>
# CollectPurge false # Varnish 2 only
# CollectSession false
# CollectSHM true
-# CollectSMA false # Varnish 2 only
+# CollectSMA false # Varnish 2 & 4 only
# CollectSMS false
# CollectSM false # Varnish 2 only
# CollectStruct false
# CollectVCL false
# CollectVSM false # Varnish 4 only
# CollectWorkers false
+# CollectLock false # Varnish 4 only
+# CollectMempool false # Varnish 4 only
+# CollectManagement false # Varnish 4 only
+# CollectSMF false # Varnish 4 only
+# CollectVBE false # Varnish 4 only
+# CollectMSE false # Varnish-Plus 4 only
# </Instance>
#</Plugin>
# HostnameFormat name
# InterfaceFormat name
# PluginInstanceFormat name
+# Instances 1
+# ExtraStats "cpu_util disk disk_err domain_state fs_info job_stats_background pcpu perf vcpupin"
#</Plugin>
#<Plugin vmem>
# Header "X-Custom-Header: custom_value"
# SSLVersion "TLSv1"
# Format "Command"
+# Prefix "collectd" # metric prefix, only available for KAIROSDB format
+# Attribute "key" "value" # only available for KAIROSDB format
+# TTL 0 # data ttl, only available for KAIROSDB format
# Metrics true
# Notifications false
# StoreRates false
When set to B<true>, reports the number of available CPUs.
Defaults to B<false>.
+=item B<ReportGuestState> B<false>|B<true>
+
+When set to B<true>, reports the "guest" and "guest_nice" CPU states.
+Defaults to B<false>.
+
+=item B<SubtractGuestState> B<false>|B<true>
+
+This option is only considered when B<ReportGuestState> is set to B<true>.
+"guest" and "guest_nice" are included in respectively "user" and "nice".
+If set to B<true>, "guest" will be subtracted from "user" and "guest_nice"
+will be subtracted from "nice".
+Defaults to B<true>.
+
=back
=head2 Plugin C<cpufreq>
<Plugin curl>
<Page "stock_quotes">
+ Plugin "quotes"
URL "http://finance.google.com/finance?q=NYSE%3AAMD"
User "foo"
Password "bar"
=over 4
+=item B<Plugin> I<Plugin>
+
+Use I<Plugin> as the plugin name when submitting values.
+Defaults to C<curl>.
+
=item B<URL> I<URL>
URL of the web site to retrieve. Since a regular expression will be used to
Use I<Name> as the host name when submitting values. Defaults to the global
host name setting.
+=item B<Plugin> I<Plugin>
+
+Use I<Plugin> as the plugin name when submitting values.
+Defaults to C<curl_json>.
+
=item B<Instance> I<Instance>
Sets the plugin instance to I<Instance>.
<Plugin "curl_xml">
<URL "http://localhost/stats.xml">
Host "my_host"
+ #Plugin "curl_xml"
Instance "some_instance"
User "collectd"
Password "thaiNg0I"
Type "magic_level"
#InstancePrefix "prefix-"
InstanceFrom "td[1]"
+ #PluginInstanceFrom "td[1]"
ValuesFrom "td[2]/span[@class=\"level\"]"
</XPath>
</URL>
Use I<Name> as the host name when submitting values. Defaults to the global
host name setting.
+=item B<Plugin> I<Plugin>
+
+Use I<Plugin> as the plugin name when submitting values.
+Defaults to 'curl_xml'.
+
=item B<Instance> I<Instance>
-Use I<Instance> as the plugin instance when submitting values. Defaults to an
-empty string (no plugin instance).
+Use I<Instance> as the plugin instance when submitting values.
+May be overridden by B<PluginInstanceFrom> option inside B<XPath> blocks.
+Defaults to an empty string (no plugin instance).
=item B<Namespace> I<Prefix> I<URL>
XPath expression must return exactly one element. The element's value is then
used as I<type instance>, possibly prefixed with I<InstancePrefix> (see above).
-This value is required. As a special exception, if the "base XPath expression"
-(the argument to the B<XPath> block) returns exactly one argument, then this
-option may be omitted.
+=item B<PluginInstanceFrom> I<PluginInstanceFrom>
+
+Specifies a XPath expression to use for determining the I<plugin instance>. The
+XPath expression must return exactly one element. The element's value is then
+used as I<plugin instance>.
+
+=back
+
+If the "base XPath expression" (the argument to the B<XPath> block) returns
+exactly one argument, then I<InstanceFrom> and I<PluginInstanceFrom> may be omitted.
+Otherwise, at least one of I<InstanceFrom> or I<PluginInstanceFrom> is required.
+
+=over 4
=item B<ValuesFrom> I<ValuesFrom> [I<ValuesFrom> ...]
I<type> specified with B<Type> (see above). Each XPath expression must return
exactly one element. The element's value is then parsed as a number and used as
value for the appropriate value in the value list dispatched to the daemon.
+This option is required.
=back
</Result>
</Query>
<Database "product_information">
+ #Plugin "warehouse"
Driver "mysql"
Interval 120
DriverOption "host" "localhost"
=over 4
+=item B<Plugin> I<Plugin>
+
+Use I<Plugin> as the plugin name when submitting query results from
+this B<Database>. Defaults to C<dbi>.
+
=item B<Interval> I<Interval>
Sets the interval (in seconds) in which the values will be collected from this
=back
+=head2 Plugin C<dpdkevents>
+
+The I<dpdkevents plugin> collects events from DPDK such as link status of
+network ports and Keep Alive status of DPDK logical cores.
+In order to get Keep Alive events following requirements must be met:
+- DPDK >= 16.07
+- support for Keep Alive implemented in DPDK application. More details can
+be found here: http://dpdk.org/doc/guides/sample_app_ug/keep_alive.html
+
+B<Synopsis:>
+
+ <Plugin "dpdkevents">
+ <EAL>
+ Coremask "0x1"
+ MemoryChannels "4"
+ FilePrefix "rte"
+ </EAL>
+ <Event "link_status">
+ SendEventsOnUpdate true
+ EnabledPortMask 0xffff
+ PortName "interface1"
+ PortName "interface2"
+ SendNotification false
+ </Event>
+ <Event "keep_alive">
+ SendEventsOnUpdate true
+ LCoreMask "0xf"
+ KeepAliveShmName "/dpdk_keepalive_shm_name"
+ SendNotification false
+ </Event>
+ </Plugin>
+
+B<Options:>
+
+
+=head3 The EAL block
+
+=over 4
+
+=item B<Coremask> I<Mask>
+
+=item B<Memorychannels> I<Channels>
+
+Number of memory channels per processor socket.
+
+=item B<FilePrefix> I<File>
+
+The prefix text used for hugepage filenames. The filename will be set to
+/var/run/.<prefix>_config where prefix is what is passed in by the user.
+
+=back
+
+=head3 The Event block
+
+The B<Event> block defines configuration for specific event. It accepts a
+single argument which specifies the name of the event.
+
+=head4 Link Status event
+
+=over 4
+
+=item B<SendEventOnUpdate> I<true|false>
+
+If set to true link status value will be dispatched only when it is
+different from previously read value. This is an optional argument - default
+value is true.
+
+=item B<EnabledPortMask> I<Mask>
+
+A hexidecimal bit mask of the DPDK ports which should be enabled. A mask
+of 0x0 means that all ports will be disabled. A bitmask of all F's means
+that all ports will be enabled. This is an optional argument - by default
+all ports are enabled.
+
+=item B<PortName> I<Name>
+
+A string containing an optional name for the enabled DPDK ports. Each PortName
+option should contain only one port name; specify as many PortName options as
+desired. Default naming convention will be used if PortName is blank. If there
+are less PortName options than there are enabled ports, the default naming
+convention will be used for the additional ports.
+
+=item B<SendNotification> I<true|false>
+
+If set to true, link status notifications are sent, instead of link status
+being collected as a statistic. This is an optional argument - default
+value is false.
+
+=back
+
+=head4 Keep Alive event
+
+=over 4
+
+=item B<SendEventOnUpdate> I<true|false>
+
+If set to true keep alive value will be dispatched only when it is
+different from previously read value. This is an optional argument - default
+value is true.
+
+=item B<LCoreMask> I<Mask>
+
+An hexadecimal bit mask of the logical cores to monitor keep alive state.
+
+=item B<KeepAliveShmName> I<Name>
+
+Shared memory name identifier that is used by secondary process to monitor
+the keep alive cores state.
+
+=item B<SendNotification> I<true|false>
+
+If set to true, keep alive notifications are sent, instead of keep alive
+information being collected as a statistic. This is an optional
+argument - default value is false.
+
+=back
+
=head2 Plugin C<dpdkstat>
The I<dpdkstat plugin> collects information about DPDK interfaces using the
B<Synopsis:>
<Plugin "dpdkstat">
- Coremask "0x4"
- MemoryChannels "4"
- ProcessType "secondary"
- FilePrefix "rte"
- EnabledPortMask 0xffff
- PortName "interface1"
- PortName "interface2"
+ <EAL>
+ Coremask "0x4"
+ MemoryChannels "4"
+ FilePrefix "rte"
+ SocketMemory "1024"
+ LogLevel "7"
+ RteDriverLibPath "/usr/lib/dpdk-pmd"
+ </EAL>
+ SharedMemObj "dpdk_collectd_stats_0"
+ EnabledPortMask 0xffff
+ PortName "interface1"
+ PortName "interface2"
</Plugin>
B<Options:>
+=head3 The EAL block
+
=over 4
=item B<Coremask> I<Mask>
A string containing a number of memory channels per processor socket.
-=item B<ProcessType> I<type>
-
-A string containing the type of DPDK process instance.
-
=item B<FilePrefix> I<File>
The prefix text used for hugepage filenames. The filename will be set to
=item B<SocketMemory> I<MB>
A string containing amount of Memory to allocate from hugepages on specific
-sockets in MB
+sockets in MB. This is an optional value.
+
+=item B<LogLevel> I<LogLevel_number>
+
+A string containing log level number. This parameter is optional.
+If parameter is not present then default value "7" - (INFO) is used.
+Value "8" - (DEBUG) can be set to enable debug traces.
+
+=item B<RteDriverLibPath> I<Path>
+
+A string containing path to shared pmd driver lib or path to directory,
+where shared pmd driver libs are available. This parameter is optional.
+This parameter enable loading of shared pmd driver libs from defined path.
+E.g.: "/usr/lib/dpdk-pmd/librte_pmd_i40e.so"
+or "/usr/lib/dpdk-pmd"
+
+=back
+
+=over 3
+
+=item B<SharedMemObj> I<Mask>
+
+A string containing the name of the shared memory object that should be used to
+share stats from the DPDK secondary process to the collectd dpdkstat plugin.
+Defaults to dpdk_collectd_stats if no other value is configured.
=item B<EnabledPortMask> I<Mask>
=over 4
+=item B<Plugin> I<Plugin>
+
+Use I<Plugin> as the plugin name when submitting values.
+Defaults to B<filecount>.
+
=item B<Instance> I<Instance>
-Sets the plugin instance to I<Instance>. That instance name must be unique, but
-it's your responsibility, the plugin doesn't check for that. If not given, the
-instance is set to the directory name with all slashes replaced by underscores
-and all leading underscores removed.
+Sets the plugin instance to I<Instance>. If not given, the instance is set to
+the directory name with all slashes replaced by underscores and all leading
+underscores removed. Empty value is allowed.
=item B<Name> I<Pattern>
"Hidden" files and directories are those, whose name begins with a dot.
Defaults to I<false>, i.e. by default hidden files and directories are ignored.
+=item B<RegularOnly> I<true>|I<false>
+
+Controls whether or not to include only regular files in the count.
+Defaults to I<true>, i.e. by default non regular files are ignored.
+
+=item B<FilesSizeType> I<Type>
+
+Sets the type used to dispatch files combined size. Empty value ("") disables
+reporting. Defaults to B<bytes>.
+
+=item B<FilesCountType> I<Type>
+
+Sets the type used to dispatch number of files. Empty value ("") disables
+reporting. Defaults to B<files>.
+
+=item B<TypeInstance> I<Instance>
+
+Sets the I<type instance> used to dispatch values. Defaults to an empty string
+(no plugin instance).
+
=back
=head2 Plugin C<GenericJMX>
=back
+=head2 Plugin C<intel_pmu>
+
+The I<intel_pmu> plugin collects performance counters data on Intel CPUs using
+Linux perf interface. All events are reported on a per core basis.
+
+B<Synopsis:>
+
+ <Plugin intel_pmu>
+ ReportHardwareCacheEvents true
+ ReportKernelPMUEvents true
+ ReportSoftwareEvents true
+ EventList "/var/cache/pmu/GenuineIntel-6-2D-core.json"
+ HardwareEvents "L2_RQSTS.CODE_RD_HIT,L2_RQSTS.CODE_RD_MISS" "L2_RQSTS.ALL_CODE_RD"
+ </Plugin>
+
+B<Options:>
+
+=over 4
+
+=item B<ReportHardwareCacheEvents> B<false>|B<true>
+
+Enable or disable measuring of hardware CPU cache events:
+ - L1-dcache-loads
+ - L1-dcache-load-misses
+ - L1-dcache-stores
+ - L1-dcache-store-misses
+ - L1-dcache-prefetches
+ - L1-dcache-prefetch-misses
+ - L1-icache-loads
+ - L1-icache-load-misses
+ - L1-icache-prefetches
+ - L1-icache-prefetch-misses
+ - LLC-loads
+ - LLC-load-misses
+ - LLC-stores
+ - LLC-store-misses
+ - LLC-prefetches
+ - LLC-prefetch-misses
+ - dTLB-loads
+ - dTLB-load-misses
+ - dTLB-stores
+ - dTLB-store-misses
+ - dTLB-prefetches
+ - dTLB-prefetch-misses
+ - iTLB-loads
+ - iTLB-load-misses
+ - branch-loads
+ - branch-load-misses
+
+=item B<ReportKernelPMUEvents> B<false>|B<true>
+
+Enable or disable measuring of the following events:
+ - cpu-cycles
+ - instructions
+ - cache-references
+ - cache-misses
+ - branches
+ - branch-misses
+ - bus-cycles
+
+=item B<ReportSoftwareEvents> B<false>|B<true>
+
+Enable or disable measuring of software events provided by kernel:
+ - cpu-clock
+ - task-clock
+ - context-switches
+ - cpu-migrations
+ - page-faults
+ - minor-faults
+ - major-faults
+ - alignment-faults
+ - emulation-faults
+
+=item B<EventList> I<filename>
+
+JSON performance counter event list file name. To be able to monitor all Intel
+CPU specific events JSON event list file should be downloaded. Use the pmu-tools
+event_download.py script to download event list for current CPU.
+
+=item B<HardwareEvents> I<events>
+
+This field is a list of event names or groups of comma separated event names.
+This option requires B<EventList> option to be configured.
+
+=back
+
=head2 Plugin C<intel_rdt>
The I<intel_rdt> plugin collects information provided by monitoring features of
Monitor events are hardware dependant. Monitoring capabilities are detected on
plugin initialization and only supported events are monitored.
+B<Note:> I<intel_rdt> plugin is using model-specific registers (MSRs), which
+require an additional capability to be enabled if collectd is run as a service.
+Please refer to I<contrib/systemd.collectd.service> file for more details.
+
B<Synopsis:>
<Plugin "intel_rdt">
=item B<IgnoreSelected> I<true>|I<false>
-If no configuration if given, the B<interface>-plugin will collect data from
+If no configuration is given, the B<interface>-plugin will collect data from
all interfaces. This may not be practical, especially for loopback- and
similar interfaces. Thus, you can use the B<Interface>-option to pick the
interfaces you're interested in. Sometimes, however, it's easier/preferred
=head2 Plugin C<ipmi>
+The B<ipmi plugin> allows to monitor server platform status using the Intelligent
+Platform Management Interface (IPMI). Local and remote interfaces are supported.
+
+The plugin configuration consists of one or more B<Instance> blocks which
+specify one I<ipmi> connection each. Each block requires one unique string
+argument as the instance name. If instances are not configured, an instance with
+the default option values will be created.
+
+For backwards compatibility, any option other than B<Instance> block will trigger
+legacy config handling and it will be treated as an option within B<Instance>
+block. This support will go away in the next major version of Collectd.
+
+Within the B<Instance> blocks, the following options are allowed:
+
=over 4
+=item B<Address> I<Address>
+
+Hostname or IP to connect to. If not specified, plugin will try to connect to
+local management controller (BMC).
+
+=item B<Username> I<Username>
+
+=item B<Password> I<Password>
+
+The username and the password to use for the connection to remote BMC.
+
+=item B<AuthType> I<MD5>|I<rmcp+>
+
+Forces the authentication type to use for the connection to remote BMC.
+By default most secure type is seleted.
+
+=item B<Host> I<Hostname>
+
+Sets the B<host> field of dispatched values. Defaults to the global hostname
+setting.
+
=item B<Sensor> I<Sensor>
Selects sensors to collect or to ignore, depending on B<IgnoreSelected>.
If you have for example dual power supply and one of them is (un)plugged then
a notification is sent.
+=item B<NotifyIPMIConnectionState> I<true>|I<false>
+
+If a IPMI connection state changes after initialization time of a minute
+a notification is sent. Defaults to B<false>.
+
+=item B<SELEnabled> I<true>|I<false>
+
+If system event log (SEL) is enabled, plugin will listen for sensor threshold
+and discrete events. When event is received the notification is sent.
+Defaults to B<false>.
+
+=item B<SELClearEvent> I<true>|I<false>
+
+If SEL clear event is enabled, plugin will delete event from SEL list after
+it is received and successfully handled. In this case other tools that are
+subscribed for SEL events will receive an empty event.
+Defaults to B<false>.
+
=back
=head2 Plugin C<iptables>
=back
+=head2 Plugin C<mcelog>
+
+The C<mcelog plugin> uses mcelog to retrieve machine check exceptions.
+
+By default the plugin connects to B<"/var/run/mcelog-client"> to check if the
+mcelog server is running. When the server is running, the plugin will tail the
+specified logfile to retrieve machine check exception information and send a
+notification with the details from the logfile. The plugin will use the mcelog
+client protocol to retrieve memory related machine check exceptions. Note that
+for memory exceptions, notifications are only sent when there is a change in
+the number of corrected/uncorrected memory errors.
+
+=head3 The Memory block
+
+Note: these options cannot be used in conjunction with the logfile options, they are mutually
+exclusive.
+
+=over 3
+
+=item B<McelogClientSocket> I<Path>
+Connect to the mcelog client socket using the UNIX domain socket at I<Path>.
+Defaults to B<"/var/run/mcelog-client">.
+
+=item B<PersistentNotification> B<true>|B<false>
+Override default configuration to only send notifications when sent when there
+is a change in the number of corrected/uncorrected memory errors. When set to
+true notifications will be sent for every read cycle. Default is false. Does
+not affect the stats being dispatched.
+
+=back
+
+=over 4
+
+=item B<McelogLogfile> I<Path>
+
+The mcelog file to parse. Defaults to B<"/var/log/mcelog">. Note: this option
+cannot be used in conjunction with the memory block options, they are mutually
+exclusive.
+
+=back
+
=head2 Plugin C<md>
The C<md plugin> collects information from Linux Software-RAID devices (md).
<Page "plugin_instance">
Server "localhost"
Key "page_key"
+ Plugin "plugin_name"
<Match>
Regex "(\\d+) bytes sent"
DSType CounterAdd
When connected to the memcached server, asks for the page I<Key>.
+=item B<Plugin> I<Plugin>
+
+Use I<Plugin> as the plugin name when submitting values.
+Defaults to C<memcachec>.
+
=item E<lt>B<Match>E<gt>
Match blocks define which strings to look for and how matches substrings are
Path to the PEM-encoded CA certificate file. Setting this option enables TLS
communication with the MQTT broker, and as such, B<Port> should be the TLS-enabled
port of the MQTT broker.
-A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+This option enables the use of TLS.
=item B<CertificateFile> I<file>
Path to the PEM-encoded certificate file to use as client certificate when
connecting to the MQTT broker.
-A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+Only valid if B<CACert> and B<CertificateKeyFile> are also set.
=item B<CertificateKeyFile> I<file>
Path to the unencrypted PEM-encoded key file corresponding to B<CertificateFile>.
-A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+Only valid if B<CACert> and B<CertificateFile> are also set.
=item B<TLSProtocol> I<protocol>
C<tlsv1.2>) to use for the TLS connection to the broker. If not set a default
version is used which depends on the version of OpenSSL the Mosquitto library
was linked against.
+Only valid if B<CACert> is set.
=item B<CipherSuite> I<ciphersuite>
A string describing the ciphers available for use. See L<ciphers(1)> and the
C<openssl ciphers> utility for more information. If unset, the default ciphers
will be used.
-
+Only valid if B<CACert> is set.
=back
or SQL threads are not running. Defaults to B<false>.
=item B<WsrepStats> I<true|false>
-
+
Enable the collection of wsrep plugin statistics, used in Master-Master
replication setups like in MySQL Galera/Percona XtraDB Cluster.
User needs only privileges to execute 'SHOW GLOBAL STATUS'
-
+
=item B<ConnectTimeout> I<Seconds>
Sets the connect timeout for the MySQL client.
=back
+=head2 Plugin C<nfs>
+
+The I<nfs plugin> collects information about the usage of the Network File
+System (NFS). It counts the number of procedure calls for each procedure,
+grouped by version and whether the system runs as server or client.
+
+It is possibly to omit metrics for a specific NFS version by setting one or
+more of the following options to B<false> (all of them default to B<true>).
+
+=over 4
+
+=item B<ReportV2> B<true>|B<false>
+
+=item B<ReportV3> B<true>|B<false>
+
+=item B<ReportV4> B<true>|B<false>
+
+=back
+
=head2 Plugin C<nginx>
This plugin collects the number of connections and requests handled by the
Add a UPS to collect data from. The format is identical to the one accepted by
L<upsc(8)>.
+=item B<ForceSSL> B<true>|B<false>
+
+Stops connections from falling back to unsecured if an SSL connection
+cannot be established. Defaults to false if undeclared.
+
+=item B<VerifyPeer> I<true>|I<false>
+
+If set to true, requires a CAPath be provided. Will use the CAPath to find
+certificates to use as Trusted Certificates to validate a upsd server certificate.
+If validation of the upsd server certificate fails, the connection will not be
+established. If ForceSSL is undeclared or set to false, setting VerifyPeer to true
+will override and set ForceSSL to true.
+
+=item B<CAPath> I/path/to/certs/folder
+
+If VerifyPeer is set to true, this is required. Otherwise this is ignored.
+The folder pointed at must contain certificate(s) named according to their hash.
+Ex: XXXXXXXX.Y where X is the hash value of a cert and Y is 0. If name collisions
+occur because two different certs have the same hash value, Y can be incremented
+in order to avoid conflict. To create a symbolic link to a certificate the following
+command can be used from within the directory where the cert resides:
+
+C<ln -s some.crt ./$(openssl x509 -hash -noout -in some.crt).0>
+
+Alternatively, the package openssl-perl provides a command C<c_rehash> that will
+generate links like the one described above for ALL certs in a given folder.
+Example usage:
+C<c_rehash /path/to/certs/folder>
+
+=item B<ConnectTimeout> I<Milliseconds>
+
+The B<ConnectTimeout> option sets the connect timeout, in milliseconds.
+By default, the configured B<Interval> is used to set the timeout.
+
=back
=head2 Plugin C<olsrd>
traffic statistics about connected clients.
To set up OpenVPN to write to the status file periodically, use the
-B<--status> option of OpenVPN. Since OpenVPN can write two different formats,
-you need to set the required format, too. This is done by setting
-B<--status-version> to B<2>.
+B<--status> option of OpenVPN.
So, in a nutshell you need:
openvpn $OTHER_OPTIONS \
- --status "/var/run/openvpn-status" 10 \
- --status-version 2
+ --status "/var/run/openvpn-status" 10
Available options:
</Result>
</Query>
<Database "product_information">
+ #Plugin "warehouse"
ConnectID "db01"
Username "oracle"
Password "secret"
=over 4
+=item B<Plugin> I<Plugin>
+
+Use I<Plugin> as the plugin name when submitting query results from
+this B<Database>. Defaults to C<oracle>.
+
=item B<ConnectID> I<ID>
Defines the "database alias" or "service name" to connect to. Usually, these
=back
+=head2 Plugin C<ovs_events>
+
+The I<ovs_events> plugin monitors the link status of I<Open vSwitch> (OVS)
+connected interfaces, dispatches the values to collectd and sends the
+notification whenever the link state change occurs. This plugin uses OVS
+database to get a link state change notification.
+
+B<Synopsis:>
+
+ <Plugin "ovs_events">
+ Port 6640
+ Address "127.0.0.1"
+ Socket "/var/run/openvswitch/db.sock"
+ Interfaces "br0" "veth0"
+ SendNotification true
+ DispatchValues false
+ </Plugin>
+
+The plugin provides the following configuration options:
+
+=over 4
+
+=item B<Address> I<node>
+
+The address of the OVS DB server JSON-RPC interface used by the plugin. To
+enable the interface, OVS DB daemon should be running with C<--remote=ptcp:>
+option. See L<ovsdb-server(1)> for more details. The option may be either
+network hostname, IPv4 numbers-and-dots notation or IPv6 hexadecimal string
+format. Defaults to C<localhost>.
+
+=item B<Port> I<service>
+
+TCP-port to connect to. Either a service name or a port number may be given.
+Defaults to B<6640>.
+
+=item B<Socket> I<path>
+
+The UNIX domain socket path of OVS DB server JSON-RPC interface used by the
+plugin. To enable the interface, the OVS DB daemon should be running with
+C<--remote=punix:> option. See L<ovsdb-server(1)> for more details. If this
+option is set, B<Address> and B<Port> options are ignored.
+
+=item B<Interfaces> [I<ifname> ...]
+
+List of interface names to be monitored by this plugin. If this option is not
+specified or is empty then all OVS connected interfaces on all bridges are
+monitored.
+
+Default: empty (all interfaces on all bridges are monitored)
+
+=item B<SendNotification> I<true|false>
+
+If set to true, OVS link notifications (interface status and OVS DB connection
+terminate) are sent to collectd. Default value is true.
+
+=item B<DispatchValues> I<true|false>
+
+Dispatch the OVS DB interface link status value with configured plugin interval.
+Defaults to false. Please note, if B<SendNotification> and B<DispatchValues>
+options are false, no OVS information will be provided by the plugin.
+
+=back
+
+B<Note:> By default, the global interval setting is used within which to
+retrieve the OVS link status. To configure a plugin-specific interval, please
+use B<Interval> option of the OVS B<LoadPlugin> block settings. For milliseconds
+simple divide the time by 1000 for example if the desired interval is 50ms, set
+interval to 0.05.
+
+=head2 Plugin C<ovs_stats>
+
+The I<ovs_stats> plugin collects statistics of OVS connected interfaces.
+This plugin uses OVSDB management protocol (RFC7047) monitor mechanism to get
+statistics from OVSDB
+
+B<Synopsis:>
+
+ <Plugin "ovs_stats">
+ Port 6640
+ Address "127.0.0.1"
+ Socket "/var/run/openvswitch/db.sock"
+ Bridges "br0" "br_ext"
+ </Plugin>
+
+The plugin provides the following configuration options:
+
+=over 4
+
+=item B<Address> I<node>
+
+The address of the OVS DB server JSON-RPC interface used by the plugin. To
+enable the interface, OVS DB daemon should be running with C<--remote=ptcp:>
+option. See L<ovsdb-server(1)> for more details. The option may be either
+network hostname, IPv4 numbers-and-dots notation or IPv6 hexadecimal string
+format. Defaults to C<localhost>.
+
+=item B<Port> I<service>
+
+TCP-port to connect to. Either a service name or a port number may be given.
+Defaults to B<6640>.
+
+=item B<Socket> I<path>
+
+The UNIX domain socket path of OVS DB server JSON-RPC interface used by the
+plugin. To enable the interface, the OVS DB daemon should be running with
+C<--remote=punix:> option. See L<ovsdb-server(1)> for more details. If this
+option is set, B<Address> and B<Port> options are ignored.
+
+=item B<Bridges> [I<brname> ...]
+
+List of OVS bridge names to be monitored by this plugin. If this option is
+omitted or is empty then all OVS bridges will be monitored.
+
+Default: empty (monitor all bridges)
+
+=back
+
=head2 Plugin C<perl>
This plugin embeds a Perl-interpreter into collectd and provides an interface
</Writer>
<Database foo>
+ Plugin "kingdom"
Host "hostname"
Port "5432"
User "username"
amount of time will be lost, for example, if a single statement within the
transaction fails or if the database server crashes.
+=item B<Plugin> I<Plugin>
+
+Use I<Plugin> as the plugin name when submitting query results from
+this B<Database>. Defaults to C<postgresql>.
+
=item B<Instance> I<name>
Specify the plugin instance name that should be used instead of the database
=head2 Plugin C<processes>
+Collects information about processes of local system.
+
+By default, with no process matches configured, only general statistics is
+collected: the number of processes in each state and fork rate.
+
+Process matches can be configured by B<Process> and B<ProcessMatch> options.
+These may also be a block in which further options may be specified.
+
+The statistics collected for matched 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)
+ - number of memory mapped files (under Linux)
+ - io data (where available)
+ - context switches (under Linux)
+ - minor and major pagefaults.
+
+B<Synopsis:>
+
+ <Plugin processes>
+ CollectFileDescriptor true
+ CollectContextSwitch true
+ Process "name"
+ ProcessMatch "name" "regex"
+ <Process "collectd">
+ CollectFileDescriptor false
+ CollectContextSwitch false
+ </Process>
+ <ProcessMatch "name" "regex">
+ CollectFileDescriptor false
+ CollectContextSwitch true
+ </Process>
+ </Plugin>
+
=over 4
=item B<Process> I<Name>
-Select more detailed statistics of processes matching this name. The statistics
-collected for these selected processes are size of the resident segment size
-(RSS), user- and system-time used, number of processes and number of threads,
-io data (where available) and minor and major pagefaults.
+Select more detailed statistics of processes matching this name.
-Some platforms have a limit on the length of process names. I<Name> must stay
-below this limit.
+Some platforms have a limit on the length of process names.
+I<Name> must stay below this limit.
=item B<ProcessMatch> I<name> I<regex>
-Similar to the B<Process> option this allows one to select more detailed
-statistics of processes matching the specified I<regex> (see L<regex(7)> for
-details). The statistics of all matching processes are summed up and
-dispatched to the daemon using the specified I<name> as an identifier. This
-allows one to "group" several processes together. I<name> must not contain
-slashes.
+Select more detailed statistics of processes matching the specified I<regex>
+(see L<regex(7)> for details). The statistics of all matching processes are
+summed up and dispatched to the daemon using the specified I<name> as an
+identifier. This allows one to "group" several processes together.
+I<name> must not contain slashes.
=item B<CollectContextSwitch> I<Boolean>
-Collect context switch of the process.
+Collect the number of context switches for matched processes.
+Disabled by default.
+
+=item B<CollectFileDescriptor> I<Boolean>
+
+Collect number of file descriptors of matched processes.
+Disabled by default.
+
+=item B<CollectMemoryMaps> I<Boolean>
+
+Collect the number of memory mapped files of the process.
+The limit for this number is configured via F</proc/sys/vm/max_map_count> in
+the Linux kernel.
=back
+Options B<CollectContextSwitch> and B<CollectFileDescriptor> may be used inside
+B<Process> and B<ProcessMatch> blocks - then they affect corresponding match
+only. Otherwise they set the default value for subsequent matches.
+
=head2 Plugin C<protocols>
Collects a lot of information about various network protocols, such as I<IP>,
other plugins, its documentation has been moved to an own manpage,
L<collectd-snmp(5)>. Please see there for details.
+=head2 Plugin C<snmp_agent>
+
+The I<snmp_agent> plugin is an AgentX subagent that receives and handles queries
+from SNMP master agent and returns the data collected by read plugins.
+The I<snmp_agent> plugin handles requests only for OIDs specified in
+configuration file. To handle SNMP queries the plugin gets data from collectd
+and translates requested values from collectd's internal format to SNMP format.
+This plugin is a generic plugin and cannot work without configuration.
+For more details on AgentX subagent see
+<http://www.net-snmp.org/tutorial/tutorial-5/toolkit/demon/>
+
+B<Synopsis:>
+
+ <Plugin snmp_agent>
+ <Data "memAvailReal">
+ Plugin "memory"
+ #PluginInstance "some"
+ Type "memory"
+ TypeInstance "free"
+ OIDs "1.3.6.1.4.1.2021.4.6.0"
+ </Data>
+ <Table "ifTable">
+ IndexOID "IF-MIB::ifIndex"
+ SizeOID "IF-MIB::ifNumber"
+ <Data "ifDescr">
+ Instance true
+ Plugin "interface"
+ OIDs "IF-MIB::ifDescr"
+ </Data>
+ <Data "ifOctets">
+ Plugin "interface"
+ Type "if_octets"
+ TypeInstance ""
+ OIDs "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets"
+ </Data>
+ </Table>
+ </Plugin>
+
+There are two types of blocks that can be contained in the
+C<E<lt>PluginE<nbsp> snmp_agentE<gt>> block: B<Data> and B<Table>:
+
+=head3 The B<Data> block
+
+The B<Data> block defines a list OIDs that are to be handled. This block can
+define scalar or table OIDs. If B<Data> block is defined inside of B<Table>
+block it reperesents table OIDs.
+The following options can be set:
+
+=over 4
+
+=item B<Instance> I<true|false>
+
+When B<Instance> is set to B<true>, the value for requested OID is copied from
+plugin instance field of corresponding collectd value. If B<Data> block defines
+scalar data type B<Instance> has no effect and can be omitted.
+
+=item B<Plugin> I<String>
+
+Read plugin name whose collected data will be mapped to specified OIDs.
+
+=item B<PluginInstance> I<String>
+
+Read plugin instance whose collected data will be mapped to specified OIDs.
+The field is optional and by default there is no plugin instance check.
+Allowed only if B<Data> block defines scalar data type.
+
+=item B<Type> I<String>
+
+Collectd's type that is to be used for specified OID, e.E<nbsp>g. "if_octets"
+for example. The types are read from the B<TypesDB> (see L<collectd.conf(5)>).
+
+=item B<TypeInstance> I<String>
+
+Collectd's type-instance that is to be used for specified OID.
+
+=item B<OIDs> I<OID> [I<OID> ...]
+
+Configures the OIDs to be handled by I<snmp_agent> plugin. Values for these OIDs
+are taken from collectd data type specified by B<Plugin>, B<PluginInstance>,
+B<Type>, B<TypeInstance> fields of this B<Data> block. Number of the OIDs
+configured should correspond to number of values in specified B<Type>.
+For example two OIDs "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets" can be mapped to
+"rx" and "tx" values of "if_octets" type.
+
+=item B<Scale> I<Value>
+
+The values taken from collectd are multiplied by I<Value>. The field is optional
+and the default is B<1.0>.
+
+=item B<Shift> I<Value>
+
+I<Value> is added to values from collectd after they have been multiplied by
+B<Scale> value. The field is optional and the default value is B<0.0>.
+
+=back
+
+=head3 The B<Table> block
+
+The B<Table> block defines a collection of B<Data> blocks that belong to one
+snmp table. In addition to multiple B<Data> blocks the following options can be
+set:
+
+=over 4
+
+=item B<IndexOID> I<OID>
+
+OID that is handled by the plugin and is mapped to numerical index value that is
+generated by the plugin for each table record.
+
+=item B<SizeOID> I<OID>
+
+OID that is handled by the plugin. Returned value is the number of records in
+the table. The field is optional.
+
+=back
+
=head2 Plugin C<statsd>
The I<statsd plugin> listens to a UDP socket, reads "events" in the statsd
This is useful for deploying I<collectd> in a heterogeneous environment, where
swap sizes differ and you want to specify generic thresholds or similar.
+=item B<ReportIO> B<true>|B<false>
+
+Enables or disables reporting swap IO. Defaults to B<true>.
+
+This is useful for the cases when swap IO is not neccessary, is not available,
+or is not reliable.
+
=back
=head2 Plugin C<syslog>
<Plugin table>
<Table "/proc/slabinfo">
+ #Plugin "slab"
Instance "slabinfo"
Separator " "
<Result>
=over 4
+=item B<Plugin> I<Plugin>
+
+If specified, I<Plugin> is used as the plugin name when submitting values.
+Defaults to B<table>.
+
=item B<Instance> I<instance>
-If specified, I<instance> is used as the plugin instance. So, in the above
-example, the plugin name C<table-slabinfo> would be used. If omitted, the
+If specified, I<instance> is used as the plugin instance. If omitted, the
filename of the table is used instead, with all special characters replaced
with an underscore (C<_>).
<Plugin "tail">
<File "/var/log/exim4/mainlog">
+ Plugin "mail"
Instance "exim"
Interval 60
<Match>
<DSType "Distribution">
Percentile 99
Bucket 0 100
+ #BucketType "bucket"
</DSType>
Type "latency"
Instance "foo"
logfile to parse. Within each B<File> block, there are one or more B<Match>
blocks, which configure a regular expression to search for.
-The B<Instance> option in the B<File> block may be used to set the plugin
-instance. So in the above example the plugin name C<tail-foo> would be used.
-This plugin instance is for all B<Match> blocks that B<follow> it, until the
-next B<Instance> option. This way you can extract several plugin instances from
-one logfile, handy when parsing syslog and the like.
+The B<Plugin> and B<Instance> options in the B<File> block may be used to set
+the plugin name and instance respectively. So in the above example the plugin name
+C<mail-exim> would be used.
+
+These options are applied for all B<Match> blocks that B<follow> it, until the
+next B<Plugin> or B<Instance> option. This way you can extract several plugin
+instances from one logfile, handy when parsing syslog and the like.
The B<Interval> option allows you to define the length of time between reads. If
this is not set, the default Interval will be used.
<DSType "Distribution">
Percentile 99
Bucket 0 100
+ BucketType "bucket"
</DSType>
=over 4
Bucket 20 50
Bucket 50 0
-Metrics are reported with the I<type> C<bucket> and the I<type instance>
+Metrics are reported with the I<type> set by B<BucketType> option (C<bucket>
+by default) and the I<type instance>
C<E<lt>TypeE<gt>[-E<lt>InstanceE<gt>]-E<lt>lower_boundE<gt>_E<lt>upper_boundE<gt>>.
This option may be repeated to calculate more than one rate.
+=item B<BucketType> I<Type>
+
+Sets the type used to dispatch B<Bucket> metrics.
+Optional, by default C<bucket> will be used.
+
=back
=back
Index 1
</Metric>
<File "/var/log/snort/snort.stats">
- Instance "snort-eth0"
+ Plugin "snortstats"
+ Instance "eth0"
Interval 600
Collect "snort-dropped"
</File>
=over 4
+=item B<Plugin> I<Plugin>
+
+Use I<Plugin> as the plugin name when submitting values.
+Defaults to C<tail_csv>.
+
=item B<Instance> I<PluginInstance>
Sets the I<plugin instance> used when dispatching the values.
Boolean enabling the use of logical core numbering for per core statistics.
When enabled, C<cpuE<lt>nE<gt>> is used as plugin instance, where I<n> is a
-sequential number assigned by the kernel. Otherwise, C<coreE<lt>nE<gt>> is used
-where I<n> is the n-th core of the socket, causing name conflicts when there is
-more than one socket.
+dynamic number assigned by the kernel. Otherwise, C<coreE<lt>nE<gt>> is used
+if there is only one package and C<pkgE<lt>nE<gt>-coreE<lt>mE<gt>> if there is
+more than one, where I<n> is the n-th core of package I<m>.
=back
CollectVCL false
CollectVSM false
CollectWorkers false
+ CollectLock false
+ CollectMempool false
+ CollectManagement false
+ CollectSMF false
+ CollectVBE false
+ CollectMSE false
</Instance>
</Plugin>
=item B<CollectSMA> B<true>|B<false>
malloc or umem (umem_alloc(3MALLOC) based) storage statistics. The umem storage
-component is Solaris specific. Only available with Varnish 2.x. False by
-default.
+component is Solaris specific. Note: SMA, SMF and MSE share counters, enable
+only the one used by the Varnish instance. Only available with Varnish 2.x.
+False by default.
=item B<CollectSMS> B<true>|B<false>
=item B<CollectSM> B<true>|B<false>
-file (memory mapped file) storage statistics. Only available with Varnish 2.x.
+file (memory mapped file) storage statistics. Only available with Varnish 2.x.,
+in varnish 4.x. use CollectSMF.
False by default.
=item B<CollectStruct> B<true>|B<false>
Collect statistics about worker threads. False by default.
+=item B<CollectVBE> B<true>|B<false>
+
+Backend counters. Only available with Varnish 4.x. False by default.
+
+=item B<CollectSMF> B<true>|B<false>
+
+file (memory mapped file) storage statistics. Only available with Varnish 4.x.
+Note: SMA, SMF and MSE share counters, enable only the one used by the Varnish
+instance. Used to be called SM in Varnish 2.x. False by default.
+
+=item B<CollectManagement> B<true>|B<false>
+
+Management process counters. Only available with Varnish 4.x. False by default.
+
+=item B<CollectLock> B<true>|B<false>
+
+Lock counters. Only available with Varnish 4.x. False by default.
+
+=item B<CollectMempool> B<true>|B<false>
+
+Memory pool counters. Only available with Varnish 4.x. False by default.
+
+=item B<CollectMSE> B<true>|B<false>
+
+Varnish Massive Storage Engine 2.0 (MSE2) is an improved storage backend for
+Varnish, replacing the traditional malloc and file storages. Only available
+with Varnish-Plus 4.x. Note: SMA, SMF and MSE share counters, enable only the
+one used by the Varnish instance. False by default.
+
=back
=head2 Plugin C<virt>
-This plugin allows CPU, disk and network load to be collected for virtualized
-guests on the machine. This means that these metrics can be collected for guest
-systems without installing any software on them - I<collectd> only runs on the
-host system. The statistics are collected through libvirt
-(L<http://libvirt.org/>).
+This plugin allows CPU, disk, network load and other metrics to be collected for
+virtualized guests on the machine. The statistics are collected through libvirt
+API (L<http://libvirt.org/>). Majority of metrics can be gathered without
+installing any additional software on guests, especially I<collectd>, which runs
+only on the host system.
Only I<Connection> is required.
=item B<BlockDeviceFormat> B<target>|B<source>
If I<BlockDeviceFormat> is set to B<target>, the default, then the device name
-seen by the guest will be used for reporting metrics.
+seen by the guest will be used for reporting metrics.
This corresponds to the C<E<lt>targetE<gt>> node in the XML definition of the
domain.
For example B<name uuid> means to concatenate the guest name and UUID
(with a literal colon character between, thus I<"foo:1234-1234-1234-1234">).
+=item B<Instances> B<integer>
+
+How many read instances you want to use for this plugin. The default is one,
+and the sensible setting is a multiple of the B<ReadThreads> value.
+If you are not sure, just use the default setting.
+
+=item B<ExtraStats> B<string>
+
+Report additional extra statistics. The default is no extra statistics, preserving
+the previous behaviour of the plugin. If unsure, leave the default. If enabled,
+allows the plugin to reported more detailed statistics about the behaviour of
+Virtual Machines. The argument is a space-separated list of selectors.
+
+Currently supported selectors are:
+
+=over 4
+
+=item B<cpu_util>: report CPU utilization per domain in percentage.
+
+=item B<disk>: report extra statistics like number of flush operations and total
+service time for read, write and flush operations. Requires libvirt API version
+I<0.9.5> or later.
+
+=item B<disk_err>: report disk errors if any occured. Requires libvirt API version
+I<0.9.10> or later.
+
+=item B<domain_state>: report domain state and reason in human-readable format as
+a notification. If libvirt API version I<0.9.2> or later is available, domain
+reason will be included in notification.
+
+=item B<fs_info>: report file system information as a notification. Requires
+libvirt API version I<1.2.11> or later. Can be collected only if I<Guest Agent>
+is installed and configured inside VM. Make sure that installed I<Guest Agent>
+version supports retrieving file system information.
+
+=item B<job_stats_background>: report statistics about progress of a background
+job on a domain. Only one type of job statistics can be collected at the same time.
+Requires libvirt API version I<1.2.9> or later.
+
+=item B<job_stats_completed>: report statistics about a recently completed job on
+a domain. Only one type of job statistics can be collected at the same time.
+Requires libvirt API version I<1.2.9> or later.
+
+=item B<pcpu>: report the physical user/system cpu time consumed by the hypervisor, per-vm.
+Requires libvirt API version I<0.9.11> or later.
+
+=item B<perf>: report performance monitoring events. To collect performance
+metrics they must be enabled for domain and supported by the platform. Requires
+libvirt API version I<1.3.3> or later.
+B<Note>: I<perf> metrics can't be collected if I<intel_rdt> plugin is enabled.
+
+=item B<vcpupin>: report pinning of domain VCPUs to host physical CPUs.
+
+=back
+
=back
=head2 Plugin C<vmem>
Synopsis:
<Plugin write_tsdb>
+ ResolveInterval 60
+ ResolveJitter 60
<Node "example">
Host "tsd-1.my.domain"
Port "4242"
</Plugin>
The configuration consists of one or more E<lt>B<Node>E<nbsp>I<Name>E<gt>
-blocks. Inside the B<Node> blocks, the following options are recognized:
+blocks and global directives.
+
+Global directives are:
+
+=over 4
+
+=item B<ResolveInterval> I<seconds>
+
+=item B<ResolveJitter> I<seconds>
+
+When I<collectd> connects to a TSDB node, it will request the hostname from
+DNS. This can become a problem if the TSDB node is unavailable or badly
+configured because collectd will request DNS in order to reconnect for every
+metric, which can flood your DNS. So you can cache the last value for
+I<ResolveInterval> seconds.
+Defaults to the I<Interval> of the I<write_tsdb plugin>, e.g. 10E<nbsp>seconds.
+
+You can also define a jitter, a random interval to wait in addition to
+I<ResolveInterval>. This prevents all your collectd servers to resolve the
+hostname at the same time when the connection fails.
+Defaults to the I<Interval> of the I<write_tsdb plugin>, e.g. 10E<nbsp>seconds.
+
+B<Note:> If the DNS resolution has already been successful when the socket
+closes, the plugin will try to reconnect immediately with the cached
+information. DNS is queried only when the socket is closed for a longer than
+I<ResolveInterval> + I<ResolveJitter> seconds.
+
+=back
+
+Inside the B<Node> blocks, the following options are recognized:
=over 4
Defaults to B<Command>.
+=item B<Attribute> I<String> I<String>
+
+Only available for the KAIROSDB output format.
+
+Consider the two given strings to be the key and value of an additional tag for
+each metric being sent out.
+
+You can add multiple B<Attribute>.
+
+=item B<TTL> I<Int>
+
+Only available for the KAIROSDB output format.
+
+Sets the Cassandra ttl for the data points.
+
+Please refer to L<http://kairosdb.github.io/docs/build/html/restapi/AddDataPoints.html?highlight=ttl>
+
+=item B<Prefix> I<String>
+
+Only available for the KAIROSDB output format.
+
+Sets the metrics prefix I<string>. Defaults to I<collectd>.
+
=item B<Metrics> B<true>|B<false>
Controls whether I<metrics> are POSTed to this location. Defaults to B<true>.
Prefix "collectd/"
Database 1
MaxSetSize -1
+ MaxSetDuration -1
StoreRates true
</Node>
</Plugin>
The B<MaxSetSize> option limits the number of items that the I<Sorted Sets> can
hold. Negative values for I<Items> sets no limit, which is the default behavior.
+=item B<MaxSetDuration> I<Seconds>
+
+The B<MaxSetDuration> option limits the duration of items that the
+I<Sorted Sets> can hold. Negative values for I<Items> sets no duration, which
+is the default behavior.
+
=item B<StoreRates> B<true>|B<false>
If set to B<true> (the default), convert counter values to rates. If set to
=item B<-P> I<E<lt>pid-fileE<gt>>
-Specify an alternative pid file. This overwrites any settings in the config
+Specify an alternative pid file. This overwrites any settings in the config
file. This is thought for init-scripts that require the PID-file in a certain
directory to work correctly. For everyday-usage use the B<PIDFile>
config-option.
+=item B<-B>
+
+If set, collectd will I<not> try to create its base directory. If the base
+directory does not exist, it will exit rather than trying to create the
+directory.
+
=item B<-f>
Don't fork to the background. I<collectd> will also B<not> close standard file
#endif
#endif /* NAN_ZERO_ZERO */
-#include "libcollectdclient/collectd/client.h"
+#include "collectd/client.h"
#ifndef PREFIX
#define PREFIX "/opt/" PACKAGE_NAME
tmp = realloc(*array, (*array_len + 1) * elem_size);
if (tmp == NULL) {
fprintf(stderr, "ERROR: Failed to allocate memory.\n");
- return (-1);
+ return -1;
}
*array = tmp;
++(*array_len);
- return (0);
+ return 0;
} /* array_grow */
static int parse_identifier(lcc_connection_t *c, const char *value,
if (gethostname(hostname, sizeof(hostname)) != 0) {
fprintf(stderr, "ERROR: Failed to get local hostname: %s",
strerror(errno));
- return (-1);
+ return -1;
}
hostname[sizeof(hostname) - 1] = '\0';
if (status != 0) {
fprintf(stderr, "ERROR: Failed to parse identifier ``%s'': %s.\n",
ident_str, lcc_strerror(c));
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* parse_identifier */
static int getval(lcc_connection_t *c, int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "ERROR: getval: Missing identifier.\n");
- return (-1);
+ return -1;
}
status = parse_identifier(c, argv[1], &ident);
if (status != 0)
- return (status);
+ return status;
#define BAIL_OUT(s) \
do { \
free(ret_values_names); \
} \
ret_values_num = 0; \
- return (s); \
+ return s; \
} while (0)
status =
if (plugins != NULL) \
free(plugins); \
plugins_num = 0; \
- return (s); \
+ return s; \
} while (0)
for (int i = 1; i < argc; ++i) {
if (argc != 1) {
fprintf(stderr, "ERROR: listval: Does not accept any arguments.\n");
- return (-1);
+ return -1;
}
#define BAIL_OUT(s) \
if (ret_ident != NULL) \
free(ret_ident); \
ret_ident_num = 0; \
- return (s); \
+ return s; \
} while (0)
status = lcc_listval(c, &ret_ident, &ret_ident_num);
if (argc < 3) {
fprintf(stderr, "ERROR: putval: Missing identifier "
"and/or value list.\n");
- return (-1);
+ return -1;
}
vl.values = values;
status = parse_identifier(c, argv[1], &vl.identifier);
if (status != 0)
- return (status);
+ return status;
for (int i = 2; i < argc; ++i) {
char *tmp;
if (endptr == value) {
fprintf(stderr, "ERROR: Failed to parse interval as number: %s.\n",
value);
- return (-1);
+ return -1;
} else if ((endptr != NULL) && (*endptr != '\0')) {
fprintf(stderr, "WARNING: Ignoring trailing garbage after "
"interval: %s.\n",
}
} else {
fprintf(stderr, "ERROR: putval: Unknown option `%s'.\n", key);
- return (-1);
+ return -1;
}
} else { /* value list */
char *value;
if (tmp == NULL) {
fprintf(stderr, "ERROR: putval: Invalid value list: %s.\n", argv[i]);
- return (-1);
+ return -1;
}
*tmp = '\0';
if (endptr == argv[i]) {
fprintf(stderr, "ERROR: Failed to parse time as number: %s.\n",
argv[i]);
- return (-1);
+ return -1;
} else if ((endptr != NULL) && (*endptr != '\0')) {
fprintf(stderr, "ERROR: Garbage after time: %s.\n", endptr);
- return (-1);
+ return -1;
}
}
if (endptr == value) {
fprintf(stderr, "ERROR: Failed to parse value as number: %s.\n",
argv[i]);
- return (-1);
+ return -1;
} else if ((endptr != NULL) && (*endptr != '\0')) {
fprintf(stderr, "ERROR: Garbage after value: %s.\n", endptr);
- return (-1);
+ return -1;
}
value = tmp;
status = lcc_putval(c, &vl);
if (status != 0) {
fprintf(stderr, "ERROR: %s\n", lcc_strerror(c));
- return (-1);
+ return -1;
}
}
}
if (values_len == 0) {
fprintf(stderr, "ERROR: putval: Missing value list(s).\n");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* putval */
int main(int argc, char **argv) {
if (status != 0) {
fprintf(stderr, "ERROR: Failed to connect to daemon at %s: %s.\n", address,
strerror(errno));
- return (1);
+ return 1;
}
if (strcasecmp(argv[optind], "getval") == 0)
status = putval(c, argc - optind, argv + optind);
else {
fprintf(stderr, "%s: invalid command: %s\n", argv[0], argv[optind]);
- return (1);
+ return 1;
}
LCC_DESTROY(c);
if (status != 0)
- return (status);
- return (0);
+ return status;
+ return 0;
} /* main */
-
-/* vim: set sw=2 ts=2 tw=78 expandtab : */
free(collectd_argv);
return 0;
} /* main */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
char const *path = old_files ? CONNTRACK_FILE_OLD : CONNTRACK_FILE;
if (parse_value_file(path, &conntrack, DS_TYPE_GAUGE) != 0) {
ERROR("conntrack plugin: Reading \"%s\" failed.", path);
- return (-1);
+ return -1;
}
path = old_files ? CONNTRACK_MAX_FILE_OLD : CONNTRACK_MAX_FILE;
if (parse_value_file(path, &conntrack_max, DS_TYPE_GAUGE) != 0) {
ERROR("conntrack plugin: Reading \"%s\" failed.", path);
- return (-1);
+ return -1;
}
conntrack_pct.gauge = (conntrack.gauge / conntrack_max.gauge) * 100;
conntrack_submit("conntrack", "max", conntrack_max);
conntrack_submit("percent", "used", conntrack_pct);
- return (0);
+ return 0;
} /* static int conntrack_read */
void module_register(void) {
if (status != 0) {
ERROR("contextswitch plugin: sysctlbyname "
"(vm.stats.sys.v_swtch) failed");
- return (-1);
+ return -1;
}
cs_submit(value);
if (fh == NULL) {
ERROR("contextswitch plugin: unable to open /proc/stat: %s",
sstrerror(errno, buffer, sizeof(buffer)));
- return (-1);
+ return -1;
}
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
char errbuf[1024];
ERROR("contextswitch plugin: perfstat_cpu_total: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
cs_submit(perfcputotal.pswitch);
#define COLLECTD_CPU_STATE_INTERRUPT 5
#define COLLECTD_CPU_STATE_SOFTIRQ 6
#define COLLECTD_CPU_STATE_STEAL 7
-#define COLLECTD_CPU_STATE_IDLE 8
-#define COLLECTD_CPU_STATE_ACTIVE 9 /* sum of (!idle) */
-#define COLLECTD_CPU_STATE_MAX 10 /* #states */
+#define COLLECTD_CPU_STATE_GUEST 8
+#define COLLECTD_CPU_STATE_GUEST_NICE 9
+#define COLLECTD_CPU_STATE_IDLE 10
+#define COLLECTD_CPU_STATE_ACTIVE 11 /* sum of (!idle) */
+#define COLLECTD_CPU_STATE_MAX 12 /* #states */
#if HAVE_STATGRAB_H
#include <statgrab.h>
static const char *cpu_state_names[] = {"user", "system", "wait", "nice",
"swap", "interrupt", "softirq", "steal",
- "idle", "active"};
+ "guest", "guest_nice", "idle", "active"};
#ifdef PROCESSOR_CPU_LOAD_INFO
static mach_port_t port_host;
static _Bool report_by_state = 1;
static _Bool report_percent = 0;
static _Bool report_num_cpu = 0;
+static _Bool report_guest = 0;
+static _Bool subtract_guest = 1;
static const char *config_keys[] = {"ReportByCpu", "ReportByState",
- "ReportNumCpu", "ValuesPercentage"};
+ "ReportNumCpu", "ValuesPercentage",
+ "ReportGuestState", "SubtractGuestState"};
static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
static int cpu_config(char const *key, char const *value) /* {{{ */
report_by_state = IS_TRUE(value) ? 1 : 0;
else if (strcasecmp(key, "ReportNumCpu") == 0)
report_num_cpu = IS_TRUE(value) ? 1 : 0;
+ else if (strcasecmp(key, "ReportGuestState") == 0)
+ report_guest = IS_TRUE(value) ? 1 : 0;
+ else if (strcasecmp(key, "SubtractGuestState") == 0)
+ subtract_guest = IS_TRUE(value) ? 1 : 0;
else
- return (-1);
+ return -1;
- return (0);
+ return 0;
} /* }}} int cpu_config */
static int init(void) {
"load information. "
"<https://collectd.org/bugs/22>");
cpu_list_len = 0;
- return (-1);
+ return -1;
}
if (status != KERN_SUCCESS) {
ERROR("cpu plugin: host_processors() failed with status %d.", (int)status);
cpu_list_len = 0;
- return (-1);
+ return -1;
}
INFO("cpu plugin: Found %i processor%s.", (int)cpu_list_len,
numcpu = 0;
if (kc == NULL)
- return (-1);
+ return -1;
/* Solaris doesn't count linear.. *sigh* */
for (numcpu = 0, ksp_chain = kc->kc_chain;
if (status == -1) {
char errbuf[1024];
WARNING("cpu plugin: sysctl: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
/* #endif CAN_USE_SYSCTL */
char errbuf[1024];
WARNING("cpu plugin: sysctlbyname(hw.ncpu): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
#ifdef HAVE_SYSCTL_KERN_CP_TIMES
char errbuf[1024];
WARNING("cpu plugin: sysctlbyname(kern.smp.maxcpus): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
#else
if (numcpu != 1)
/* nothing to initialize */
#endif /* HAVE_PERFSTAT */
- return (0);
+ return 0;
} /* int init */
static void submit_value(int cpu_num, int cpu_state, const char *type,
sizeof(vl.type_instance));
if (cpu_num >= 0) {
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", cpu_num);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", cpu_num);
}
plugin_dispatch_values(&vl);
}
tmp = realloc(cpu_states, sz * sizeof(*cpu_states));
if (tmp == NULL) {
ERROR("cpu plugin: realloc failed.");
- return (ENOMEM);
+ return ENOMEM;
}
cpu_states = tmp;
tmp = cpu_states + cpu_states_num;
size_t index = ((cpu_num * COLLECTD_CPU_STATE_MAX) + state);
if (index >= cpu_states_num)
- return (NULL);
+ return NULL;
- return (&cpu_states[index]);
+ return &cpu_states[index];
} /* }}} cpu_state_t *get_cpu_state */
#if defined(HAVE_PERFSTAT) /* {{{ */
int status =
value_to_rate(&rate, (value_t){.derive = d}, DS_TYPE_DERIVE, now, conv);
if (status != 0)
- return (status);
+ return status;
sum_by_state[state] = rate;
if (state != COLLECTD_CPU_STATE_IDLE)
RATE_ADD(sum_by_state[COLLECTD_CPU_STATE_ACTIVE], sum_by_state[state]);
- return (0);
+ return 0;
}
#endif /* }}} HAVE_PERFSTAT */
static void cpu_commit(void) /* {{{ */
{
gauge_t global_rates[COLLECTD_CPU_STATE_MAX] = {
- NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN /* Batman! */
+ NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN /* Batman! */
};
if (report_num_cpu)
for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++) {
cpu_state_t *this_cpu_states = get_cpu_state(cpu_num, 0);
gauge_t local_rates[COLLECTD_CPU_STATE_MAX] = {NAN, NAN, NAN, NAN, NAN,
- NAN, NAN, NAN, NAN, NAN};
+ NAN, NAN, NAN, NAN, NAN,
+ NAN, NAN };
for (size_t state = 0; state < COLLECTD_CPU_STATE_MAX; state++)
if (this_cpu_states[state].has_value)
value_t val = {.derive = d};
if (state >= COLLECTD_CPU_STATE_ACTIVE)
- return (EINVAL);
+ return EINVAL;
status = cpu_states_alloc(cpu_num);
if (status != 0)
- return (status);
+ return status;
if (global_cpu_num <= cpu_num)
global_cpu_num = cpu_num + 1;
status = value_to_rate(&rate, val, DS_TYPE_DERIVE, now, &s->conv);
if (status != 0)
- return (status);
+ return status;
s->rate = rate;
s->has_value = 1;
- return (0);
+ return 0;
} /* }}} int cpu_stage */
static int cpu_read(void) {
FILE *fh;
char buf[1024];
- char *fields[9];
+ char *fields[11];
int numfields;
if ((fh = fopen("/proc/stat", "r")) == NULL) {
char errbuf[1024];
ERROR("cpu plugin: fopen (/proc/stat) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
while (fgets(buf, 1024, fh) != NULL) {
if ((buf[3] < '0') || (buf[3] > '9'))
continue;
- numfields = strsplit(buf, fields, 9);
+ numfields = strsplit(buf, fields, STATIC_ARRAY_SIZE(fields));
if (numfields < 5)
continue;
cpu = atoi(fields[0] + 3);
- cpu_stage(cpu, COLLECTD_CPU_STATE_USER, (derive_t)atoll(fields[1]), now);
- cpu_stage(cpu, COLLECTD_CPU_STATE_NICE, (derive_t)atoll(fields[2]), now);
+ /* Do not stage User and Nice immediately: we may need to alter them later: */
+ long long user_value = atoll(fields[1]);
+ long long nice_value = atoll(fields[2]);
cpu_stage(cpu, COLLECTD_CPU_STATE_SYSTEM, (derive_t)atoll(fields[3]), now);
cpu_stage(cpu, COLLECTD_CPU_STATE_IDLE, (derive_t)atoll(fields[4]), now);
now);
cpu_stage(cpu, COLLECTD_CPU_STATE_SOFTIRQ, (derive_t)atoll(fields[7]),
now);
+ }
- if (numfields >= 9)
- cpu_stage(cpu, COLLECTD_CPU_STATE_STEAL, (derive_t)atoll(fields[8]),
- now);
+ if (numfields >= 9) { /* Steal (since Linux 2.6.11) */
+ cpu_stage(cpu, COLLECTD_CPU_STATE_STEAL, (derive_t)atoll(fields[8]), now);
+ }
+
+ if (numfields >= 10) { /* Guest (since Linux 2.6.24) */
+ if (report_guest) {
+ long long value = atoll(fields[9]);
+ cpu_stage(cpu, COLLECTD_CPU_STATE_GUEST, (derive_t)value, now);
+ /* Guest is included in User; optionally subtract Guest from User: */
+ if (subtract_guest) {
+ user_value -= value;
+ if (user_value < 0) user_value = 0;
+ }
+ }
}
+
+ if (numfields >= 11) { /* Guest_nice (since Linux 2.6.33) */
+ if (report_guest) {
+ long long value = atoll(fields[10]);
+ cpu_stage(cpu, COLLECTD_CPU_STATE_GUEST_NICE, (derive_t)value, now);
+ /* Guest_nice is included in Nice; optionally subtract Guest_nice from
+ Nice: */
+ if (subtract_guest) {
+ nice_value -= value;
+ if (nice_value < 0) nice_value = 0;
+ }
+ }
+ }
+
+ /* Eventually stage User and Nice: */
+ cpu_stage(cpu, COLLECTD_CPU_STATE_USER, (derive_t)user_value, now);
+ cpu_stage(cpu, COLLECTD_CPU_STATE_NICE, (derive_t)nice_value, now);
}
fclose(fh);
/* }}} #endif defined(KERNEL_LINUX) */
static cpu_stat_t cs;
if (kc == NULL)
- return (-1);
+ return -1;
for (int cpu = 0; cpu < numcpu; cpu++) {
if (kstat_read(kc, ksp[cpu], &cs) == -1)
if (numcpu < 1) {
ERROR("cpu plugin: Could not determine number of "
"installed CPUs using sysctl(3).");
- return (-1);
+ return -1;
}
memset(cpuinfo, 0, sizeof(cpuinfo));
char errbuf[1024];
ERROR("cpu plugin: sysctl failed: %s.",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
}
} else
char errbuf[1024];
ERROR("cpu plugin: sysctl failed: %s.",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
for (int i = 0; i < CPUSTATES; i++) {
char errbuf[1024];
ERROR("cpu plugin: sysctlbyname failed: %s.",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
for (int i = 0; i < numcpu; i++) {
char errbuf[1024];
ERROR("cpu plugin: sysctlbyname failed: %s.",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
cpu_stage(0, COLLECTD_CPU_STATE_USER, (derive_t)cpuinfo[CP_USER], now);
if (cs == NULL) {
ERROR("cpu plugin: sg_get_cpu_stats failed.");
- return (-1);
+ return -1;
}
cpu_state(0, COLLECTD_CPU_STATE_IDLE, (derive_t)cs->idle);
char errbuf[1024];
WARNING("cpu plugin: perfstat_cpu: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
if (pnumcpu != numcpu || perfcpu == NULL) {
char errbuf[1024];
WARNING("cpu plugin: perfstat_cpu: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
for (int i = 0; i < cpus; i++) {
cpu_commit();
cpu_reset();
- return (0);
+ return 0;
}
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 : */
num_cpu = 0;
while (1) {
- status = ssnprintf(filename, sizeof(filename),
- "/sys/devices/system/cpu/cpu%d/cpufreq/"
- "scaling_cur_freq",
- num_cpu);
+ status = snprintf(filename, sizeof(filename),
+ "/sys/devices/system/cpu/cpu%d/cpufreq/"
+ "scaling_cur_freq",
+ num_cpu);
if ((status < 1) || ((unsigned int)status >= sizeof(filename)))
break;
if (num_cpu == 0)
plugin_unregister_read("cpufreq");
- return (0);
+ return 0;
} /* int cpufreq_init */
static void cpufreq_submit(int cpu_num, value_t value) {
vl.values_len = 1;
sstrncpy(vl.plugin, "cpufreq", sizeof(vl.plugin));
sstrncpy(vl.type, "cpufreq", sizeof(vl.type));
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%i", cpu_num);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%i", cpu_num);
plugin_dispatch_values(&vl);
}
static int cpufreq_read(void) {
for (int i = 0; i < num_cpu; i++) {
char filename[PATH_MAX];
- ssnprintf(filename, sizeof(filename),
- "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", i);
+ snprintf(filename, sizeof(filename),
+ "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", i);
value_t v;
if (parse_value_file(filename, &v, DS_TYPE_GAUGE) != 0) {
cpufreq_submit(i, v);
}
- return (0);
+ return 0;
} /* int cpufreq_read */
void module_register(void) {
struct timespec b, m;
if (clock_gettime(CLOCK_BOOTTIME, &b) < 0) {
ERROR("cpusleep plugin: clock_boottime failed");
- return (-1);
+ return -1;
}
if (clock_gettime(CLOCK_MONOTONIC, &m) < 0) {
ERROR("cpusleep plugin: clock_monotonic failed");
- return (-1);
+ return -1;
}
// to avoid false positives in counter overflow due to reboot,
cpusleep_submit(sleep);
- return (0);
+ return 0;
}
void module_register(void) {
/* Python object declarations. */
typedef struct {
+ // clang-format off
PyObject_HEAD /* No semicolon! */
- PyObject *parent; /* Config */
+ PyObject *parent; /* Config */
PyObject *key; /* String */
PyObject *values; /* Sequence */
PyObject *children; /* Sequence */
+ // clang-format on
} Config;
extern PyTypeObject ConfigType;
typedef struct {
+ // clang-format off
PyObject_HEAD /* No semicolon! */
- double time;
+ double time;
+ // clang-format on
char host[DATA_MAX_NAME_LEN];
char plugin[DATA_MAX_NAME_LEN];
char plugin_instance[DATA_MAX_NAME_LEN];
typedef struct {
PluginData data;
+ PyObject *meta; /* dict */
int severity;
char message[NOTIF_MAX_MSG_LEN];
} Notification;
memset(buffer, '\0', buffer_len);
- status = ssnprintf(buffer, buffer_len, "%.3f", CDTIME_T_TO_DOUBLE(vl->time));
+ status = snprintf(buffer, buffer_len, "%.3f", CDTIME_T_TO_DOUBLE(vl->time));
if ((status < 1) || (status >= buffer_len))
- return (-1);
+ return -1;
offset = status;
for (size_t i = 0; i < ds->ds_num; i++) {
(ds->ds[i].type != DS_TYPE_DERIVE) &&
(ds->ds[i].type != DS_TYPE_ABSOLUTE)) {
sfree(rates);
- return (-1);
+ return -1;
}
if (ds->ds[i].type == DS_TYPE_GAUGE) {
- status = ssnprintf(buffer + offset, buffer_len - offset, ",%lf",
- vl->values[i].gauge);
+ status = snprintf(buffer + offset, buffer_len - offset, ",%lf",
+ vl->values[i].gauge);
} else if (store_rates != 0) {
if (rates == NULL)
rates = uc_get_rate(ds, vl);
if (rates == NULL) {
WARNING("csv plugin: "
"uc_get_rate failed.");
- return (-1);
+ return -1;
}
- status =
- ssnprintf(buffer + offset, buffer_len - offset, ",%lf", rates[i]);
+ status = snprintf(buffer + offset, buffer_len - offset, ",%lf", rates[i]);
} else if (ds->ds[i].type == DS_TYPE_COUNTER) {
- status = ssnprintf(buffer + offset, buffer_len - offset, ",%llu",
- vl->values[i].counter);
+ status = snprintf(buffer + offset, buffer_len - offset, ",%llu",
+ vl->values[i].counter);
} else if (ds->ds[i].type == DS_TYPE_DERIVE) {
- status = ssnprintf(buffer + offset, buffer_len - offset, ",%" PRIi64,
- vl->values[i].derive);
+ status = snprintf(buffer + offset, buffer_len - offset, ",%" PRIi64,
+ vl->values[i].derive);
} else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) {
- status = ssnprintf(buffer + offset, buffer_len - offset, ",%" PRIu64,
- vl->values[i].absolute);
+ status = snprintf(buffer + offset, buffer_len - offset, ",%" PRIu64,
+ vl->values[i].absolute);
}
if ((status < 1) || (status >= (buffer_len - offset))) {
sfree(rates);
- return (-1);
+ return -1;
}
offset += status;
} /* for ds->ds_num */
sfree(rates);
- return (0);
+ return 0;
} /* int value_list_to_string */
static int value_list_to_filename(char *buffer, size_t buffer_size,
size_t len = strlen(datadir) + 1;
if (len >= ptr_size)
- return (ENOBUFS);
+ return ENOBUFS;
memcpy(ptr, datadir, len);
ptr[len - 1] = '/';
status = FORMAT_VL(ptr, ptr_size, vl);
if (status != 0)
- return (status);
+ return status;
/* Skip all the time formatting stuff when printing to STDOUT or
* STDERR. */
if (use_stdio)
- return (0);
+ return 0;
ptr_size -= strlen(ptr);
ptr += strlen(ptr);
/* "-2013-07-12" => 11 bytes */
if (ptr_size < 12) {
ERROR("csv plugin: Buffer too small.");
- return (ENOMEM);
+ return ENOMEM;
}
/* TODO: Find a way to minimize the calls to `localtime_r',
now = time(NULL);
if (localtime_r(&now, &struct_tm) == NULL) {
ERROR("csv plugin: localtime_r failed");
- return (-1);
+ return -1;
}
status = strftime(ptr, ptr_size, "-%Y-%m-%d", &struct_tm);
if (status == 0) /* yep, it returns zero on error. */
{
ERROR("csv plugin: strftime failed");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int value_list_to_filename */
static int csv_create_file(const char *filename, const data_set_t *ds) {
FILE *csv;
if (check_create_dir(filename))
- return (-1);
+ return -1;
csv = fopen(filename, "w");
if (csv == NULL) {
char errbuf[1024];
ERROR("csv plugin: fopen (%s) failed: %s", filename,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
fprintf(csv, "epoch");
}
if (strcasecmp("stdout", value) == 0) {
use_stdio = 1;
- return (0);
+ return 0;
} else if (strcasecmp("stderr", value) == 0) {
use_stdio = 2;
- return (0);
+ return 0;
}
datadir = strdup(value);
if (datadir != NULL) {
else
store_rates = 0;
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int csv_config */
static int csv_write(const data_set_t *ds, const value_list_t *vl,
status = value_list_to_filename(filename, sizeof(filename), vl);
if (status != 0)
- return (-1);
+ return -1;
DEBUG("csv plugin: csv_write: filename = %s;", filename);
if (value_list_to_string(values, sizeof(values), ds, vl) != 0)
- return (-1);
+ return -1;
if (use_stdio) {
escape_string(filename, sizeof(filename));
fprintf(use_stdio == 1 ? stdout : stderr, "PUTVAL %s interval=%.3f %s\n",
filename, CDTIME_T_TO_DOUBLE(vl->interval), values);
- return (0);
+ return 0;
}
if (stat(filename, &statbuf) == -1) {
if (errno == ENOENT) {
if (csv_create_file(filename, ds))
- return (-1);
+ return -1;
} else {
char errbuf[1024];
ERROR("stat(%s) failed: %s", filename,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
} else if (!S_ISREG(statbuf.st_mode)) {
ERROR("stat(%s): Not a regular file!", filename);
- return (-1);
+ return -1;
}
csv = fopen(filename, "a");
char errbuf[1024];
ERROR("csv plugin: fopen (%s) failed: %s", filename,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
csv_fd = fileno(csv);
ERROR("csv plugin: flock (%s) failed: %s", filename,
sstrerror(errno, errbuf, sizeof(errbuf)));
fclose(csv);
- return (-1);
+ return -1;
}
fprintf(csv, "%s\n", values);
* because the `FILE *' may need to flush a cache first */
fclose(csv);
- return (0);
+ return 0;
} /* int csv_write */
void module_register(void) {
typedef struct web_page_s web_page_t;
struct web_page_s /* {{{ */
{
+ char *plugin_name;
char *instance;
char *url;
len = size * nmemb;
if (len == 0)
- return (len);
+ return len;
wp = user_data;
if (wp == NULL)
- return (0);
+ return 0;
if ((wp->buffer_fill + len) >= wp->buffer_size) {
char *temp;
temp = realloc(wp->buffer, temp_size);
if (temp == NULL) {
ERROR("curl plugin: realloc failed.");
- return (0);
+ return 0;
}
wp->buffer = temp;
wp->buffer_size = temp_size;
wp->buffer_fill += len;
wp->buffer[wp->buffer_fill] = 0;
- return (len);
+ return len;
} /* }}} size_t cc_curl_callback */
static void cc_web_match_free(web_match_t *wm) /* {{{ */
curl_easy_cleanup(wp->curl);
wp->curl = NULL;
+ sfree(wp->plugin_name);
sfree(wp->instance);
sfree(wp->url);
struct curl_slist *temp = NULL;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("curl plugin: `%s' needs exactly one string argument.", name);
- return (-1);
+ return -1;
}
temp = curl_slist_append(*dest, ci->values[0].value.string);
if (temp == NULL)
- return (-1);
+ return -1;
*dest = temp;
- return (0);
+ return 0;
} /* }}} int cc_config_append_string */
static int cc_config_add_match_dstype(int *dstype_ret, /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("curl plugin: `DSType' needs exactly one string argument.");
- return (-1);
+ return -1;
}
if (strncasecmp("Gauge", ci->values[0].value.string, strlen("Gauge")) == 0) {
if (dstype == 0) {
WARNING("curl plugin: `%s' is not a valid argument to `DSType'.",
ci->values[0].value.string);
- return (-1);
+ return -1;
}
*dstype_ret = dstype;
- return (0);
+ return 0;
} /* }}} int cc_config_add_match_dstype */
static int cc_config_add_match(web_page_t *page, /* {{{ */
match = calloc(1, sizeof(*match));
if (match == NULL) {
ERROR("curl plugin: calloc failed.");
- return (-1);
+ return -1;
}
status = 0;
if (status != 0) {
cc_web_match_free(match);
- return (status);
+ return status;
}
match->match =
if (match->match == NULL) {
ERROR("curl plugin: match_create_simple failed.");
cc_web_match_free(match);
- return (-1);
+ return -1;
} else {
web_match_t *prev;
prev->next = match;
}
- return (0);
+ return 0;
} /* }}} int cc_config_add_match */
static int cc_page_init_curl(web_page_t *wp) /* {{{ */
wp->curl = curl_easy_init();
if (wp->curl == NULL) {
ERROR("curl plugin: curl_easy_init failed.");
- return (-1);
+ return -1;
}
curl_easy_setopt(wp->curl, CURLOPT_NOSIGNAL, 1L);
wp->credentials = malloc(credentials_size);
if (wp->credentials == NULL) {
ERROR("curl plugin: malloc failed.");
- return (-1);
+ return -1;
}
- ssnprintf(wp->credentials, credentials_size, "%s:%s", wp->user,
- (wp->pass == NULL) ? "" : wp->pass);
+ snprintf(wp->credentials, credentials_size, "%s:%s", wp->user,
+ (wp->pass == NULL) ? "" : wp->pass);
curl_easy_setopt(wp->curl, CURLOPT_USERPWD, wp->credentials);
#endif
(long)CDTIME_T_TO_MS(plugin_get_interval()));
#endif
- return (0);
+ return 0;
} /* }}} int cc_page_init_curl */
static int cc_config_add_page(oconfig_item_t *ci) /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("curl plugin: `Page' blocks need exactly one string argument.");
- return (-1);
+ return -1;
}
page = calloc(1, sizeof(*page));
if (page == NULL) {
ERROR("curl plugin: calloc failed.");
- return (-1);
+ return -1;
}
+ page->plugin_name = NULL;
page->url = NULL;
page->user = NULL;
page->pass = NULL;
if (page->instance == NULL) {
ERROR("curl plugin: strdup failed.");
sfree(page);
- return (-1);
+ return -1;
}
/* Process all children */
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
- if (strcasecmp("URL", child->key) == 0)
+ if (strcasecmp("Plugin", child->key) == 0)
+ status = cf_util_get_string(child, &page->plugin_name);
+ else if (strcasecmp("URL", child->key) == 0)
status = cf_util_get_string(child, &page->url);
else if (strcasecmp("User", child->key) == 0)
status = cf_util_get_string(child, &page->user);
if (status != 0) {
cc_web_page_free(page);
- return (status);
+ return status;
}
/* Add the new page to the linked list */
prev->next = page;
}
- return (0);
+ return 0;
} /* }}} int cc_config_add_page */
static int cc_config(oconfig_item_t *ci) /* {{{ */
if ((success == 0) && (errors > 0)) {
ERROR("curl plugin: All statements failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cc_config */
static int cc_init(void) /* {{{ */
{
if (pages_g == NULL) {
INFO("curl plugin: No pages have been defined.");
- return (-1);
+ return -1;
}
curl_global_init(CURL_GLOBAL_SSL);
- return (0);
+ return 0;
} /* }}} int cc_init */
static void cc_submit(const web_page_t *wp, const web_match_t *wm, /* {{{ */
vl.values = &value;
vl.values_len = 1;
- sstrncpy(vl.plugin, "curl", sizeof(vl.plugin));
+ sstrncpy(vl.plugin, (wp->plugin_name != NULL) ? wp->plugin_name : "curl",
+ sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, wp->instance, sizeof(vl.plugin_instance));
sstrncpy(vl.type, wm->type, sizeof(vl.type));
if (wm->instance != NULL)
vl.values = &(value_t){.gauge = (gauge_t)code};
vl.values_len = 1;
- sstrncpy(vl.plugin, "curl", sizeof(vl.plugin));
+ sstrncpy(vl.plugin, (wp->plugin_name != NULL) ? wp->plugin_name : "curl",
+ sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, wp->instance, sizeof(vl.plugin_instance));
sstrncpy(vl.type, "response_code", sizeof(vl.type));
vl.values = &(value_t){.gauge = response_time};
vl.values_len = 1;
- sstrncpy(vl.plugin, "curl", sizeof(vl.plugin));
+ sstrncpy(vl.plugin, (wp->plugin_name != NULL) ? wp->plugin_name : "curl",
+ sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, wp->instance, sizeof(vl.plugin_instance));
sstrncpy(vl.type, "response_time", sizeof(vl.type));
if (status != CURLE_OK) {
ERROR("curl plugin: curl_easy_perform failed with status %i: %s", status,
wp->curl_errbuf);
- return (-1);
+ return -1;
}
if (wp->response_time)
cc_submit_response_time(wp, CDTIME_T_TO_DOUBLE(cdtime() - start));
if (wp->stats != NULL)
- curl_stats_dispatch(wp->stats, wp->curl, hostname_g, "curl", wp->instance);
+ curl_stats_dispatch(wp->stats, wp->curl, NULL, "curl", wp->instance);
if (wp->response_code) {
long response_code = 0;
match_value_reset(mv);
} /* for (wm = wp->matches; wm != NULL; wm = wm->next) */
- return (0);
+ return 0;
} /* }}} int cc_read_page */
static int cc_read(void) /* {{{ */
for (web_page_t *wp = pages_g; wp != NULL; wp = wp->next)
cc_read_page(wp);
- return (0);
+ return 0;
} /* }}} int cc_read */
static int cc_shutdown(void) /* {{{ */
cc_web_page_free(pages_g);
pages_g = NULL;
- return (0);
+ return 0;
} /* }}} int cc_shutdown */
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 : */
#endif
#define CJ_DEFAULT_HOST "localhost"
-#define CJ_KEY_MAGIC 0x43484b59UL /* CHKY */
-#define CJ_IS_KEY(key) ((key)->magic == CJ_KEY_MAGIC)
#define CJ_ANY "*"
#define COUCH_MIN(x, y) ((x) < (y) ? (x) : (y))
typedef struct cj_key_s cj_key_t;
struct cj_key_s /* {{{ */
{
- unsigned long magic;
char *path;
char *type;
char *instance;
};
/* }}} */
+/* cj_tree_entry_t is a union of either a metric configuration ("key") or a tree
+ * mapping array indexes / map keys to a descendant cj_tree_entry_t*. */
+typedef struct {
+ enum { KEY, TREE } type;
+ union {
+ c_avl_tree_t *tree;
+ cj_key_t *key;
+ };
+} cj_tree_entry_t;
+
+/* cj_state_t is a stack providing the configuration relevant for the context
+ * that is currently being parsed. If entry->type == KEY, the parser should
+ * expect a metric (a numeric value). If entry->type == TREE, the parser should
+ * expect an array of map to descent into. If entry == NULL, no configuration
+ * exists for this part of the JSON structure. */
+typedef struct {
+ cj_tree_entry_t *entry;
+ _Bool in_array;
+ int index;
+ char name[DATA_MAX_NAME_LEN];
+} cj_state_t;
+
struct cj_s /* {{{ */
{
char *instance;
+ char *plugin_name;
char *host;
char *sock;
yajl_handle yajl;
c_avl_tree_t *tree;
- cj_key_t *key;
int depth;
- struct {
- union {
- c_avl_tree_t *tree;
- cj_key_t *key;
- };
- _Bool in_array;
- int index;
- char name[DATA_MAX_NAME_LEN];
- } state[YAJL_MAX_DEPTH];
+ cj_state_t state[YAJL_MAX_DEPTH];
};
typedef struct cj_s cj_t; /* }}} */
#endif
static int cj_read(user_data_t *ud);
-static void cj_submit(cj_t *db, cj_key_t *key, value_t *value);
+static void cj_submit_impl(cj_t *db, cj_key_t *key, value_t *value);
+
+/* cj_submit is a function pointer to cj_submit_impl, allowing the unit-test to
+ * overwrite which function is called. */
+static void (*cj_submit)(cj_t *, cj_key_t *, value_t *) = cj_submit_impl;
static size_t cj_curl_callback(void *buf, /* {{{ */
size_t size, size_t nmemb, void *user_data) {
len = size * nmemb;
if (len == 0)
- return (len);
+ return len;
db = user_data;
if (db == NULL)
- return (0);
+ return 0;
status = yajl_parse(db->yajl, (unsigned char *)buf, len);
if (status == yajl_status_ok)
- return (len);
+ return len;
#if !HAVE_YAJL_V2
else if (status == yajl_status_insufficient_data)
- return (len);
+ return len;
#endif
unsigned char *msg =
/* jsonText = */ (unsigned char *)buf, (unsigned int)len);
ERROR("curl_json plugin: yajl_parse failed: %s", msg);
yajl_free_error(db->yajl, msg);
- return (0); /* abort write callback */
+ return 0; /* abort write callback */
} /* }}} size_t cj_curl_callback */
static int cj_get_type(cj_key_t *key) {
- const data_set_t *ds;
-
- if ((key == NULL) || !CJ_IS_KEY(key))
+ if (key == NULL)
return -EINVAL;
- ds = plugin_get_ds(key->type);
+ const data_set_t *ds = plugin_get_ds(key->type);
if (ds == NULL) {
static char type[DATA_MAX_NAME_LEN] = "!!!invalid!!!";
sstrncpy(db->state[db->depth].name, key, sizeof(db->state[db->depth].name));
- c_avl_tree_t *tree = db->state[db->depth - 1].tree;
- if (tree == NULL) {
+ if (db->state[db->depth - 1].entry == NULL ||
+ db->state[db->depth - 1].entry->type != TREE) {
return 0;
}
- /* the parent has a key, so the tree pointer is invalid. */
- if (CJ_IS_KEY(db->state[db->depth - 1].key)) {
- return 0;
- }
+ c_avl_tree_t *tree = db->state[db->depth - 1].entry->tree;
+ cj_tree_entry_t *e = NULL;
- void *value = NULL;
- if (c_avl_get(tree, key, (void *)&value) == 0) {
- if (CJ_IS_KEY((cj_key_t *)value)) {
- db->state[db->depth].key = value;
- } else {
- db->state[db->depth].tree = value;
- }
- } else if (c_avl_get(tree, CJ_ANY, (void *)&value) == 0) {
- if (CJ_IS_KEY((cj_key_t *)value)) {
- db->state[db->depth].key = value;
- } else {
- db->state[db->depth].tree = value;
- }
+ if (c_avl_get(tree, key, (void *)&e) == 0) {
+ db->state[db->depth].entry = e;
+ } else if (c_avl_get(tree, CJ_ANY, (void *)&e) == 0) {
+ db->state[db->depth].entry = e;
} else {
- db->state[db->depth].key = NULL;
+ db->state[db->depth].entry = NULL;
}
return 0;
db->state[db->depth].index++;
char name[DATA_MAX_NAME_LEN];
- ssnprintf(name, sizeof(name), "%d", db->state[db->depth].index);
+ snprintf(name, sizeof(name), "%d", db->state[db->depth].index);
cj_load_key(db, name);
}
#define CJ_CB_ABORT 0
#define CJ_CB_CONTINUE 1
-static int cj_cb_boolean(void *ctx, int boolVal) {
- cj_advance_array(ctx);
- return (CJ_CB_CONTINUE);
-}
-
static int cj_cb_null(void *ctx) {
cj_advance_array(ctx);
- return (CJ_CB_CONTINUE);
+ return CJ_CB_CONTINUE;
}
static int cj_cb_number(void *ctx, const char *number, yajl_len_t number_len) {
- char buffer[number_len + 1];
-
cj_t *db = (cj_t *)ctx;
- cj_key_t *key = db->state[db->depth].key;
/* Create a null-terminated version of the string. */
+ char buffer[number_len + 1];
memcpy(buffer, number, number_len);
buffer[sizeof(buffer) - 1] = 0;
-
-
- if (key == NULL) {
- /* no config for this element. */
- cj_advance_array(ctx);
- return CJ_CB_CONTINUE;
- } else if (!CJ_IS_KEY(key)) {
- /* the config expects a map or an array. */
- NOTICE(
- "curl_json plugin: Found \"%s\", but the configuration expects a map.",
- buffer);
+ if (db->state[db->depth].entry == NULL ||
+ db->state[db->depth].entry->type != KEY) {
+ if (db->state[db->depth].entry != NULL) {
+ NOTICE("curl_json plugin: Found \"%s\", but the configuration expects a "
+ "map.",
+ buffer);
+ }
cj_advance_array(ctx);
return CJ_CB_CONTINUE;
}
+ cj_key_t *key = db->state[db->depth].entry->key;
+
int type = cj_get_type(key);
value_t vt;
int status = parse_value(buffer, &vt, type);
if (status != 0) {
NOTICE("curl_json plugin: Unable to parse number: \"%s\"", buffer);
cj_advance_array(ctx);
- return (CJ_CB_CONTINUE);
+ return CJ_CB_CONTINUE;
}
cj_submit(db, key, &vt);
cj_advance_array(ctx);
- return (CJ_CB_CONTINUE);
+ return CJ_CB_CONTINUE;
} /* int cj_cb_number */
/* Queries the key-tree of the parent context for "in_name" and, if found,
static int cj_cb_string(void *ctx, const unsigned char *val, yajl_len_t len) {
/* Handle the string as if it was a number. */
- return (cj_cb_number(ctx, (const char *)val, len));
+ return cj_cb_number(ctx, (const char *)val, len);
} /* int cj_cb_string */
+static int cj_cb_boolean(void *ctx, int boolVal) {
+ if (boolVal)
+ return cj_cb_number(ctx, "1", 1);
+ else
+ return cj_cb_number(ctx, "0", 1);
+} /* int cj_cb_boolean */
+
static int cj_cb_end(void *ctx) {
cj_t *db = (cj_t *)ctx;
- db->state[db->depth].tree = NULL;
+ memset(&db->state[db->depth], 0, sizeof(db->state[db->depth]));
db->depth--;
cj_advance_array(ctx);
- return (CJ_CB_CONTINUE);
+ return CJ_CB_CONTINUE;
}
static int cj_cb_start_map(void *ctx) {
if ((db->depth + 1) >= YAJL_MAX_DEPTH) {
ERROR("curl_json plugin: %s depth exceeds max, aborting.",
db->url ? db->url : db->sock);
- return (CJ_CB_ABORT);
+ return CJ_CB_ABORT;
}
db->depth++;
- return (CJ_CB_CONTINUE);
+ return CJ_CB_CONTINUE;
}
static int cj_cb_end_map(void *ctx) { return cj_cb_end(ctx); }
static void cj_tree_free(c_avl_tree_t *tree) /* {{{ */
{
char *name;
- void *value;
+ cj_tree_entry_t *e;
- while (c_avl_pick(tree, (void *)&name, (void *)&value) == 0) {
- cj_key_t *key = (cj_key_t *)value;
+ while (c_avl_pick(tree, (void *)&name, (void *)&e) == 0) {
+ sfree(name);
- if (CJ_IS_KEY(key))
- cj_key_free(key);
+ if (e->type == KEY)
+ cj_key_free(e->key);
else
- cj_tree_free((c_avl_tree_t *)value);
-
- sfree(name);
+ cj_tree_free(e->tree);
+ sfree(e);
}
c_avl_destroy(tree);
db->tree = NULL;
sfree(db->instance);
+ sfree(db->plugin_name);
sfree(db->host);
sfree(db->sock);
struct curl_slist *temp = NULL;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("curl_json plugin: `%s' needs exactly one string argument.", name);
- return (-1);
+ return -1;
}
temp = curl_slist_append(*dest, ci->values[0].value.string);
if (temp == NULL)
- return (-1);
+ return -1;
*dest = temp;
- return (0);
+ return 0;
} /* }}} int cj_config_append_string */
+/* cj_append_key adds key to the configuration stored in db.
+ *
+ * For example:
+ * "httpd/requests/count",
+ * "httpd/requests/current" ->
+ * { "httpd": { "requests": { "count": $key, "current": $key } } }
+ */
+static int cj_append_key(cj_t *db, cj_key_t *key) { /* {{{ */
+ if (db->tree == NULL)
+ db->tree = cj_avl_create();
+
+ c_avl_tree_t *tree = db->tree;
+
+ char const *start = key->path;
+ if (*start == '/')
+ ++start;
+
+ char const *end;
+ while ((end = strchr(start, '/')) != NULL) {
+ char name[PATH_MAX];
+
+ size_t len = end - start;
+ if (len == 0)
+ break;
+
+ len = COUCH_MIN(len, sizeof(name) - 1);
+ sstrncpy(name, start, len + 1);
+
+ cj_tree_entry_t *e;
+ if (c_avl_get(tree, name, (void *)&e) != 0) {
+ e = calloc(1, sizeof(*e));
+ if (e == NULL)
+ return ENOMEM;
+ e->type = TREE;
+ e->tree = cj_avl_create();
+
+ c_avl_insert(tree, strdup(name), e);
+ }
+
+ if (e->type != TREE)
+ return EINVAL;
+
+ tree = e->tree;
+ start = end + 1;
+ }
+
+ if (strlen(start) == 0) {
+ ERROR("curl_json plugin: invalid key: %s", key->path);
+ return -1;
+ }
+
+ cj_tree_entry_t *e = calloc(1, sizeof(*e));
+ if (e == NULL)
+ return ENOMEM;
+ e->type = KEY;
+ e->key = key;
+
+ c_avl_insert(tree, strdup(start), e);
+ return 0;
+} /* }}} int cj_append_key */
+
static int cj_config_add_key(cj_t *db, /* {{{ */
oconfig_item_t *ci) {
cj_key_t *key;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("curl_json plugin: The `Key' block "
"needs exactly one string argument.");
- return (-1);
+ return -1;
}
key = calloc(1, sizeof(*key));
if (key == NULL) {
ERROR("curl_json plugin: calloc failed.");
- return (-1);
+ return -1;
}
- key->magic = CJ_KEY_MAGIC;
if (strcasecmp("Key", ci->key) == 0) {
status = cf_util_get_string(ci, &key->path);
if (status != 0) {
sfree(key);
- return (status);
+ return status;
}
} else {
ERROR("curl_json plugin: cj_config: "
"Invalid key: %s",
ci->key);
cj_key_free(key);
- return (-1);
+ return -1;
}
status = 0;
if (status != 0) {
cj_key_free(key);
- return (-1);
+ return -1;
}
if (key->type == NULL) {
WARNING("curl_json plugin: `Type' missing in `Key' block.");
cj_key_free(key);
- return (-1);
- }
-
- /* store path in a tree that will match the json map structure, example:
- * "httpd/requests/count",
- * "httpd/requests/current" ->
- * { "httpd": { "requests": { "count": $key, "current": $key } } }
- */
- char *ptr;
- char *name;
- c_avl_tree_t *tree;
-
- if (db->tree == NULL)
- db->tree = cj_avl_create();
-
- tree = db->tree;
- ptr = key->path;
- if (*ptr == '/')
- ++ptr;
-
- name = ptr;
- while ((ptr = strchr(name, '/')) != NULL) {
- char ent[PATH_MAX];
- c_avl_tree_t *value;
- size_t len;
-
- len = ptr - name;
- if (len == 0)
- break;
-
- len = COUCH_MIN(len, sizeof(ent) - 1);
- sstrncpy(ent, name, len + 1);
-
- if (c_avl_get(tree, ent, (void *)&value) != 0) {
- value = cj_avl_create();
- c_avl_insert(tree, strdup(ent), value);
- }
-
- tree = value;
- name = ptr + 1;
+ return -1;
}
- if (strlen(name) == 0) {
- ERROR("curl_json plugin: invalid key: %s", key->path);
+ status = cj_append_key(db, key);
+ if (status != 0) {
cj_key_free(key);
- return (-1);
+ return -1;
}
- c_avl_insert(tree, strdup(name), key);
- return (status);
+ return 0;
} /* }}} int cj_config_add_key */
static int cj_init_curl(cj_t *db) /* {{{ */
db->curl = curl_easy_init();
if (db->curl == NULL) {
ERROR("curl_json plugin: curl_easy_init failed.");
- return (-1);
+ return -1;
}
curl_easy_setopt(db->curl, CURLOPT_NOSIGNAL, 1L);
db->credentials = malloc(credentials_size);
if (db->credentials == NULL) {
ERROR("curl_json plugin: malloc failed.");
- return (-1);
+ return -1;
}
- ssnprintf(db->credentials, credentials_size, "%s:%s", db->user,
- (db->pass == NULL) ? "" : db->pass);
+ snprintf(db->credentials, credentials_size, "%s:%s", db->user,
+ (db->pass == NULL) ? "" : db->pass);
curl_easy_setopt(db->curl, CURLOPT_USERPWD, db->credentials);
#endif
(long)CDTIME_T_TO_MS(plugin_get_interval()));
#endif
- return (0);
+ return 0;
} /* }}} int cj_init_curl */
static int cj_config_add_url(oconfig_item_t *ci) /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("curl_json plugin: The `URL' block "
"needs exactly one string argument.");
- return (-1);
+ return -1;
}
db = calloc(1, sizeof(*db));
if (db == NULL) {
ERROR("curl_json plugin: calloc failed.");
- return (-1);
+ return -1;
}
db->timeout = -1;
"Invalid key: %s",
ci->key);
cj_free(db);
- return (-1);
+ return -1;
}
if (status != 0) {
sfree(db);
- return (status);
+ return status;
}
/* Fill the `cj_t' structure.. */
if (strcasecmp("Instance", child->key) == 0)
status = cf_util_get_string(child, &db->instance);
+ else if (strcasecmp("Plugin", child->key) == 0)
+ status = cf_util_get_string(child, &db->plugin_name);
else if (strcasecmp("Host", child->key) == 0)
status = cf_util_get_string(child, &db->host);
else if (db->url && strcasecmp("User", child->key) == 0)
sfree(cb_name);
} else {
cj_free(db);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
/* }}} int cj_config_add_database */
if ((success == 0) && (errors > 0)) {
ERROR("curl_json plugin: All statements failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cj_config */
/* }}} End of configuration handling functions */
return db->host;
} /* }}} cj_host */
-static void cj_submit(cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
+static void cj_submit_impl(cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
{
value_list_t vl = VALUE_LIST_INIT;
if (key->instance == NULL) {
int len = 0;
for (int i = 0; i < db->depth; i++)
- len += ssnprintf(vl.type_instance + len, sizeof(vl.type_instance) - len,
- i ? "-%s" : "%s", db->state[i + 1].name);
+ len += snprintf(vl.type_instance + len, sizeof(vl.type_instance) - len,
+ i ? "-%s" : "%s", db->state[i + 1].name);
} else
sstrncpy(vl.type_instance, key->instance, sizeof(vl.type_instance));
sstrncpy(vl.host, cj_host(db), sizeof(vl.host));
- sstrncpy(vl.plugin, "curl_json", sizeof(vl.plugin));
+ sstrncpy(vl.plugin, (db->plugin_name != NULL) ? db->plugin_name : "curl_json",
+ sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, db->instance, sizeof(vl.plugin_instance));
sstrncpy(vl.type, key->type, sizeof(vl.type));
vl.interval = db->interval;
plugin_dispatch_values(&vl);
-} /* }}} int cj_submit */
+} /* }}} int cj_submit_impl */
static int cj_sock_perform(cj_t *db) /* {{{ */
{
char errbuf[1024];
- struct sockaddr_un sa_unix = {0};
- sa_unix.sun_family = AF_UNIX;
+ struct sockaddr_un sa_unix = {
+ .sun_family = AF_UNIX,
+ };
sstrncpy(sa_unix.sun_path, db->sock, sizeof(sa_unix.sun_path));
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
- return (-1);
+ return -1;
if (connect(fd, (struct sockaddr *)&sa_unix, sizeof(sa_unix)) < 0) {
ERROR("curl_json plugin: connect(%s) failed: %s",
(db->sock != NULL) ? db->sock : "<null>",
sstrerror(errno, errbuf, sizeof(errbuf)));
close(fd);
- return (-1);
+ return -1;
}
ssize_t red;
(db->sock != NULL) ? db->sock : "<null>",
sstrerror(errno, errbuf, sizeof(errbuf)));
close(fd);
- return (-1);
+ return -1;
}
if (!cj_curl_callback(buffer, red, 1, db))
break;
} while (red > 0);
close(fd);
- return (0);
+ return 0;
} /* }}} int cj_sock_perform */
static int cj_curl_perform(cj_t *db) /* {{{ */
if (status != CURLE_OK) {
ERROR("curl_json plugin: curl_easy_perform failed with status %i: %s (%s)",
status, db->curl_errbuf, db->url);
- return (-1);
+ return -1;
}
if (db->stats != NULL)
curl_stats_dispatch(db->stats, db->curl, cj_host(db), "curl_json",
ERROR("curl_json plugin: curl_easy_perform failed with "
"response code %ld (%s)",
rc, url);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cj_curl_perform */
static int cj_perform(cj_t *db) /* {{{ */
if (db->yajl == NULL) {
ERROR("curl_json plugin: yajl_alloc failed.");
db->yajl = yprev;
- return (-1);
+ return -1;
}
if (db->url)
if (status < 0) {
yajl_free(db->yajl);
db->yajl = yprev;
- return (-1);
+ return -1;
}
#if HAVE_YAJL_V2
yajl_free_error(db->yajl, errmsg);
yajl_free(db->yajl);
db->yajl = yprev;
- return (-1);
+ return -1;
}
yajl_free(db->yajl);
db->yajl = yprev;
- return (0);
+ return 0;
} /* }}} int cj_perform */
static int cj_read(user_data_t *ud) /* {{{ */
if ((ud == NULL) || (ud->data == NULL)) {
ERROR("curl_json plugin: cj_read: Invalid user data.");
- return (-1);
+ return -1;
}
db = (cj_t *)ud->data;
db->depth = 0;
memset(&db->state, 0, sizeof(db->state));
- db->state[db->depth].tree = db->tree;
- db->key = NULL;
- return cj_perform(db);
+ /* This is not a compound literal because EPEL6's GCC is not cool enough to
+ * handle anonymous unions within compound literals. */
+ cj_tree_entry_t root = {0};
+ root.type = TREE;
+ root.tree = db->tree;
+ db->state[0].entry = &root;
+
+ int status = cj_perform(db);
+
+ db->state[0].entry = NULL;
+
+ return status;
} /* }}} int cj_read */
static int cj_init(void) /* {{{ */
/* Call this while collectd is still single-threaded to avoid
* initialization issues in libgcrypt. */
curl_global_init(CURL_GLOBAL_SSL);
- return (0);
+ return 0;
} /* }}} int cj_init */
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 : */
--- /dev/null
+/**
+ * collectd - src/curl_json.c
+ * Copyright (C) 2017 Florian octo Forster
+ *
+ * Licensed under the same terms and conditions as src/curl_json.c.
+ *
+ * Authors:
+ * Florian octo Forster <octo at collectd.org>
+ **/
+
+#include "curl_json.c"
+
+#include "testing.h"
+
+static void test_submit(cj_t *db, cj_key_t *key, value_t *value) {
+ /* hack: we repurpose db->curl to store received values. */
+ c_avl_tree_t *values = (void *)db->curl;
+
+ value_t *value_copy = calloc(1, sizeof(*value_copy));
+ memmove(value_copy, value, sizeof(*value_copy));
+
+ assert(c_avl_insert(values, key->path, value_copy) == 0);
+}
+
+static derive_t test_metric(cj_t *db, char const *path) {
+ c_avl_tree_t *values = (void *)db->curl;
+
+ value_t *ret = NULL;
+ if (c_avl_get(values, path, (void *)&ret) == 0) {
+ return ret->derive;
+ }
+
+ return -1;
+}
+
+static cj_t *test_setup(char *json, char *key_path) {
+ cj_t *db = calloc(1, sizeof(*db));
+ db->yajl = yajl_alloc(&ycallbacks,
+#if HAVE_YAJL_V2
+ /* alloc funcs = */ NULL,
+#else
+ /* alloc funcs = */ NULL, NULL,
+#endif
+ /* context = */ (void *)db);
+
+ /* hack; see above. */
+ db->curl = (void *)cj_avl_create();
+
+ cj_key_t *key = calloc(1, sizeof(*key));
+ key->path = strdup(key_path);
+ key->type = strdup("MAGIC");
+
+ assert(cj_append_key(db, key) == 0);
+
+ cj_tree_entry_t root = {0};
+ root.type = TREE;
+ root.tree = db->tree;
+ db->state[0].entry = &root;
+
+ cj_curl_callback(json, strlen(json), 1, db);
+#if HAVE_YAJL_V2
+ yajl_complete_parse(db->yajl);
+#else
+ yajl_parse_complete(db->yajl);
+#endif
+
+ db->state[0].entry = NULL;
+
+ return db;
+}
+
+static void test_teardown(cj_t *db) {
+ c_avl_tree_t *values = (void *)db->curl;
+ db->curl = NULL;
+
+ void *key;
+ void *value;
+ while (c_avl_pick(values, &key, &value) == 0) {
+ /* key will be freed by cj_free. */
+ free(value);
+ }
+ c_avl_destroy(values);
+
+ yajl_free(db->yajl);
+ db->yajl = NULL;
+
+ cj_free(db);
+}
+
+DEF_TEST(parse) {
+ struct {
+ char *json;
+ char *key_path;
+ derive_t want;
+ } cases[] = {
+ /* simple map */
+ {"{\"foo\":42,\"bar\":23}", "foo", 42},
+ {"{\"foo\":42,\"bar\":23}", "bar", 23},
+ /* nested map */
+ {"{\"a\":{\"b\":{\"c\":123}}", "a/b/c", 123},
+ {"{\"x\":{\"y\":{\"z\":789}}", "x/*/z", 789},
+ /* simple array */
+ {"[10,11,12,13]", "0", 10},
+ {"[10,11,12,13]", "1", 11},
+ {"[10,11,12,13]", "2", 12},
+ {"[10,11,12,13]", "3", 13},
+ /* array index after non-numeric entry */
+ {"[true,11]", "1", 11},
+ {"[null,11]", "1", 11},
+ {"[\"s\",11]", "1", 11},
+ {"[{\"k\":\"v\"},11]", "1", 11},
+ {"[[0,1,2],11]", "1", 11},
+ /* nested array */
+ {"[[0,1,2],[3,4,5],[6,7,8]]", "0/0", 0},
+ {"[[0,1,2],[3,4,5],[6,7,8]]", "0/1", 1},
+ {"[[0,1,2],[3,4,5],[6,7,8]]", "0/2", 2},
+ {"[[0,1,2],[3,4,5],[6,7,8]]", "1/0", 3},
+ {"[[0,1,2],[3,4,5],[6,7,8]]", "1/1", 4},
+ {"[[0,1,2],[3,4,5],[6,7,8]]", "1/2", 5},
+ {"[[0,1,2],[3,4,5],[6,7,8]]", "2/0", 6},
+ {"[[0,1,2],[3,4,5],[6,7,8]]", "2/1", 7},
+ {"[[0,1,2],[3,4,5],[6,7,8]]", "2/2", 8},
+ /* testcase from #2266 */
+ {"{\"a\":[[10,11,12,13,14]]}", "a/0/0", 10},
+ {"{\"a\":[[10,11,12,13,14]]}", "a/0/1", 11},
+ {"{\"a\":[[10,11,12,13,14]]}", "a/0/2", 12},
+ {"{\"a\":[[10,11,12,13,14]]}", "a/0/3", 13},
+ {"{\"a\":[[10,11,12,13,14]]}", "a/0/4", 14},
+ };
+
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
+ cj_t *db = test_setup(cases[i].json, cases[i].key_path);
+
+ EXPECT_EQ_INT(cases[i].want, test_metric(db, cases[i].key_path));
+
+ test_teardown(db);
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ cj_submit = test_submit;
+
+ RUN_TEST(parse);
+
+ END_TEST;
+}
size_t values_len;
char *instance_prefix;
char *instance;
+ char *plugin_instance_from;
int is_table;
unsigned long magic;
};
struct cx_s /* {{{ */
{
char *instance;
+ char *plugin_name;
char *host;
char *url;
size_t buffer_size;
size_t buffer_fill;
- llist_t *list; /* list of xpath blocks */
+ llist_t *xpath_list; /* list of xpath blocks */
};
typedef struct cx_s cx_t; /* }}} */
static size_t cx_curl_callback(void *buf, /* {{{ */
size_t size, size_t nmemb, void *user_data) {
size_t len = size * nmemb;
- cx_t *db;
- db = user_data;
+ cx_t *db = user_data;
if (db == NULL) {
ERROR("curl_xml plugin: cx_curl_callback: "
"user_data pointer is NULL.");
- return (0);
+ return 0;
}
if (len == 0)
- return (len);
+ return len;
if ((db->buffer_fill + len) >= db->buffer_size) {
- char *temp;
-
- temp = realloc(db->buffer, db->buffer_fill + len + 1);
+ char *temp = realloc(db->buffer, db->buffer_fill + len + 1);
if (temp == NULL) {
ERROR("curl_xml plugin: realloc failed.");
- return (0);
+ return 0;
}
db->buffer = temp;
db->buffer_size = db->buffer_fill + len + 1;
db->buffer_fill += len;
db->buffer[db->buffer_fill] = 0;
- return (len);
+ return len;
} /* }}} size_t cx_curl_callback */
static void cx_xpath_free(cx_xpath_t *xpath) /* {{{ */
sfree(xpath->path);
sfree(xpath->type);
sfree(xpath->instance_prefix);
+ sfree(xpath->plugin_instance_from);
sfree(xpath->instance);
sfree(xpath->values);
sfree(xpath);
} /* }}} void cx_xpath_free */
-static void cx_list_free(llist_t *list) /* {{{ */
+static void cx_xpath_list_free(llist_t *list) /* {{{ */
{
llentry_t *le;
le = llist_head(list);
while (le != NULL) {
- llentry_t *le_next;
+ llentry_t *le_next = le->next;
- le_next = le->next;
-
- sfree(le->key);
+ /* this also frees xpath->path used for le->key */
cx_xpath_free(le->value);
le = le_next;
}
llist_destroy(list);
-} /* }}} void cx_list_free */
+} /* }}} void cx_xpath_list_free */
static void cx_free(void *arg) /* {{{ */
{
curl_easy_cleanup(db->curl);
db->curl = NULL;
- if (db->list != NULL)
- cx_list_free(db->list);
+ if (db->xpath_list != NULL)
+ cx_xpath_list_free(db->xpath_list);
sfree(db->buffer);
sfree(db->instance);
+ sfree(db->plugin_name);
sfree(db->host);
sfree(db->url);
sfree(db);
} /* }}} void cx_free */
-static const char *cx_host(cx_t *db) /* {{{ */
+static const char *cx_host(const cx_t *db) /* {{{ */
{
if (db->host == NULL)
return hostname_g;
struct curl_slist *temp = NULL;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("curl_xml plugin: `%s' needs exactly one string argument.", name);
- return (-1);
+ return -1;
}
temp = curl_slist_append(*dest, ci->values[0].value.string);
if (temp == NULL)
- return (-1);
+ return -1;
*dest = temp;
- return (0);
+ return 0;
} /* }}} int cx_config_append_string */
static int cx_check_type(const data_set_t *ds, cx_xpath_t *xpath) /* {{{ */
{
if (!ds) {
WARNING("curl_xml plugin: DataSet `%s' not defined.", xpath->type);
- return (-1);
+ return -1;
}
if (ds->ds_num != xpath->values_len) {
WARNING("curl_xml plugin: DataSet `%s' requires %zu values, but config "
"talks about %zu",
xpath->type, ds->ds_num, xpath->values_len);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} cx_check_type */
-static xmlXPathObjectPtr
-cx_evaluate_xpath(xmlXPathContextPtr xpath_ctx, /* {{{ */
- xmlChar *expr) {
- xmlXPathObjectPtr xpath_obj;
-
- /* XXX: When to free this? */
- xpath_obj = xmlXPathEvalExpression(BAD_CAST expr, xpath_ctx);
+static xmlXPathObjectPtr cx_evaluate_xpath(xmlXPathContextPtr xpath_ctx,
+ char *expr) /* {{{ */
+{
+ xmlXPathObjectPtr xpath_obj =
+ xmlXPathEvalExpression(BAD_CAST expr, xpath_ctx);
if (xpath_obj == NULL) {
WARNING("curl_xml plugin: "
"Error unable to evaluate xpath expression \"%s\". Skipping...",
{
if (node->type == XML_TEXT_NODE || node->type == XML_ATTRIBUTE_NODE ||
node->type == XML_ELEMENT_NODE)
- return (0);
+ return 0;
WARNING("curl_xml plugin: "
"Node \"%s\" doesn't seem to be a text node. Skipping...",
return -1;
} /* }}} cx_if_not_text_node */
-static int cx_handle_single_value_xpath(xmlXPathContextPtr xpath_ctx, /* {{{ */
- cx_xpath_t *xpath, const data_set_t *ds,
- value_list_t *vl, int index) {
- xmlXPathObjectPtr values_node_obj;
- xmlNodeSetPtr values_node;
- int tmp_size;
- char *node_value;
-
- values_node_obj =
- cx_evaluate_xpath(xpath_ctx, BAD_CAST xpath->values[index].path);
+/*
+ * Returned value should be freed with xmlFree().
+ */
+static char *cx_get_text_node_value(xmlXPathContextPtr xpath_ctx, /* {{{ */
+ char *expr, const char *from_option) {
+ xmlXPathObjectPtr values_node_obj = cx_evaluate_xpath(xpath_ctx, expr);
if (values_node_obj == NULL)
- return (-1); /* Error already logged. */
+ return NULL; /* Error already logged. */
- values_node = values_node_obj->nodesetval;
- tmp_size = (values_node) ? values_node->nodeNr : 0;
+ xmlNodeSetPtr values_node = values_node_obj->nodesetval;
+ size_t tmp_size = (values_node) ? values_node->nodeNr : 0;
if (tmp_size == 0) {
WARNING("curl_xml plugin: "
- "relative xpath expression \"%s\" doesn't match any of the nodes. "
- "Skipping...",
- xpath->values[index].path);
+ "relative xpath expression \"%s\" from '%s' doesn't match "
+ "any of the nodes.",
+ expr, from_option);
xmlXPathFreeObject(values_node_obj);
- return (-1);
+ return NULL;
}
if (tmp_size > 1) {
WARNING("curl_xml plugin: "
- "relative xpath expression \"%s\" is expected to return "
- "only one node. Skipping...",
- xpath->values[index].path);
+ "relative xpath expression \"%s\" from '%s' is expected to return "
+ "only one text node. Skipping the node.",
+ expr, from_option);
xmlXPathFreeObject(values_node_obj);
- return (-1);
+ return NULL;
}
/* ignoring the element if other than textnode/attribute*/
if (cx_if_not_text_node(values_node->nodeTab[0])) {
WARNING("curl_xml plugin: "
- "relative xpath expression \"%s\" is expected to return "
- "only text/attribute node which is not the case. Skipping...",
- xpath->values[index].path);
+ "relative xpath expression \"%s\" from '%s' is expected to return "
+ "only text/attribute node which is not the case. "
+ "Skipping the node.",
+ expr, from_option);
xmlXPathFreeObject(values_node_obj);
- return (-1);
+ return NULL;
}
- node_value = (char *)xmlNodeGetContent(values_node->nodeTab[0]);
+ char *node_value = (char *)xmlNodeGetContent(values_node->nodeTab[0]);
+
+ /* free up object */
+ xmlXPathFreeObject(values_node_obj);
+
+ return node_value;
+} /* }}} char * cx_get_text_node_value */
+
+static int cx_handle_single_value_xpath(xmlXPathContextPtr xpath_ctx, /* {{{ */
+ cx_xpath_t *xpath, const data_set_t *ds,
+ value_list_t *vl, int index) {
+
+ char *node_value = cx_get_text_node_value(
+ xpath_ctx, xpath->values[index].path, "ValuesFrom");
+
+ if (node_value == NULL)
+ return -1;
+
switch (ds->ds[index].type) {
case DS_TYPE_COUNTER:
vl->values[index].counter =
/* endptr = */ NULL);
}
- /* free up object */
- xmlXPathFreeObject(values_node_obj);
- sfree(node_value);
+ xmlFree(node_value);
/* We have reached here which means that
* we have got something to work */
- return (0);
+ return 0;
} /* }}} int cx_handle_single_value_xpath */
static int cx_handle_all_value_xpaths(xmlXPathContextPtr xpath_ctx, /* {{{ */
cx_xpath_t *xpath, const data_set_t *ds,
value_list_t *vl) {
value_t values[xpath->values_len];
- int status;
assert(xpath->values_len > 0);
assert(xpath->values_len == vl->values_len);
vl->values = values;
for (size_t i = 0; i < xpath->values_len; i++) {
- status = cx_handle_single_value_xpath(xpath_ctx, xpath, ds, vl, i);
- if (status != 0)
- return (-1); /* An error has been printed. */
- } /* for (i = 0; i < xpath->values_len; i++) */
+ if (cx_handle_single_value_xpath(xpath_ctx, xpath, ds, vl, i) != 0)
+ return -1; /* An error has been printed. */
+ } /* for (i = 0; i < xpath->values_len; i++) */
plugin_dispatch_values(vl);
vl->values = NULL;
- return (0);
+ return 0;
} /* }}} int cx_handle_all_value_xpaths */
static int cx_handle_instance_xpath(xmlXPathContextPtr xpath_ctx, /* {{{ */
- cx_xpath_t *xpath, value_list_t *vl,
- _Bool is_table) {
- xmlXPathObjectPtr instance_node_obj = NULL;
- xmlNodeSetPtr instance_node = NULL;
+ cx_xpath_t *xpath, value_list_t *vl) {
- memset(vl->type_instance, 0, sizeof(vl->type_instance));
+ /* Handle type instance */
+ if (xpath->instance != NULL) {
+ char *node_value =
+ cx_get_text_node_value(xpath_ctx, xpath->instance, "InstanceFrom");
+ if (node_value == NULL)
+ return -1;
+
+ if (xpath->instance_prefix != NULL)
+ snprintf(vl->type_instance, sizeof(vl->type_instance), "%s%s",
+ xpath->instance_prefix, node_value);
+ else
+ sstrncpy(vl->type_instance, node_value, sizeof(vl->type_instance));
- /* If the base xpath returns more than one block, the result is assumed to be
- * a table. The `Instance' option is not optional in this case. Check for the
- * condition and inform the user. */
- if (is_table && (xpath->instance == NULL)) {
- WARNING("curl_xml plugin: "
- "Base-XPath %s is a table (more than one result was returned), "
- "but no instance-XPath has been defined.",
- xpath->path);
- return (-1);
- }
+ xmlFree(node_value);
+ } else if (xpath->instance_prefix != NULL)
+ sstrncpy(vl->type_instance, xpath->instance_prefix,
+ sizeof(vl->type_instance));
- /* instance has to be an xpath expression */
- if (xpath->instance != NULL) {
- int tmp_size;
-
- instance_node_obj = cx_evaluate_xpath(xpath_ctx, BAD_CAST xpath->instance);
- if (instance_node_obj == NULL)
- return (-1); /* error is logged already */
-
- instance_node = instance_node_obj->nodesetval;
- tmp_size = (instance_node) ? instance_node->nodeNr : 0;
-
- if (tmp_size <= 0) {
- WARNING(
- "curl_xml plugin: "
- "relative xpath expression for 'InstanceFrom' \"%s\" doesn't match "
- "any of the nodes. Skipping the node.",
- xpath->instance);
- xmlXPathFreeObject(instance_node_obj);
- return (-1);
- }
+ /* Handle plugin instance */
+ if (xpath->plugin_instance_from != NULL) {
+ char *node_value = cx_get_text_node_value(
+ xpath_ctx, xpath->plugin_instance_from, "PluginInstanceFrom");
- if (tmp_size > 1) {
- WARNING("curl_xml plugin: "
- "relative xpath expression for 'InstanceFrom' \"%s\" is expected "
- "to return only one text node. Skipping the node.",
- xpath->instance);
- xmlXPathFreeObject(instance_node_obj);
- return (-1);
- }
+ if (node_value == NULL)
+ return -1;
- /* ignoring the element if other than textnode/attribute */
- if (cx_if_not_text_node(instance_node->nodeTab[0])) {
- WARNING("curl_xml plugin: "
- "relative xpath expression \"%s\" is expected to return only "
- "text node "
- "which is not the case. Skipping the node.",
- xpath->instance);
- xmlXPathFreeObject(instance_node_obj);
- return (-1);
- }
- } /* if (xpath->instance != NULL) */
-
- if (xpath->instance_prefix != NULL) {
- if (instance_node != NULL) {
- char *node_value = (char *)xmlNodeGetContent(instance_node->nodeTab[0]);
- ssnprintf(vl->type_instance, sizeof(vl->type_instance), "%s%s",
- xpath->instance_prefix, node_value);
- sfree(node_value);
- } else
- sstrncpy(vl->type_instance, xpath->instance_prefix,
- sizeof(vl->type_instance));
- } else {
- /* If instance_prefix and instance_node are NULL, then
- * don't set the type_instance */
- if (instance_node != NULL) {
- char *node_value = (char *)xmlNodeGetContent(instance_node->nodeTab[0]);
- sstrncpy(vl->type_instance, node_value, sizeof(vl->type_instance));
- sfree(node_value);
- }
+ sstrncpy(vl->plugin_instance, node_value, sizeof(vl->plugin_instance));
+ xmlFree(node_value);
}
- /* Free `instance_node_obj' this late, because `instance_node' points to
- * somewhere inside this structure. */
- xmlXPathFreeObject(instance_node_obj);
-
- return (0);
+ return 0;
} /* }}} int cx_handle_instance_xpath */
-static int cx_handle_base_xpath(char const *plugin_instance, /* {{{ */
- char const *host, xmlXPathContextPtr xpath_ctx,
- const data_set_t *ds, char *base_xpath,
- cx_xpath_t *xpath) {
- int total_nodes;
+static int cx_handle_xpath(const cx_t *db, /* {{{ */
+ xmlXPathContextPtr xpath_ctx, cx_xpath_t *xpath) {
- xmlXPathObjectPtr base_node_obj = NULL;
- xmlNodeSetPtr base_nodes = NULL;
-
- value_list_t vl = VALUE_LIST_INIT;
+ const data_set_t *ds = plugin_get_ds(xpath->type);
+ if (cx_check_type(ds, xpath) != 0)
+ return -1;
- base_node_obj = cx_evaluate_xpath(xpath_ctx, BAD_CAST base_xpath);
+ xmlXPathObjectPtr base_node_obj = cx_evaluate_xpath(xpath_ctx, xpath->path);
if (base_node_obj == NULL)
return -1; /* error is logged already */
- base_nodes = base_node_obj->nodesetval;
- total_nodes = (base_nodes) ? base_nodes->nodeNr : 0;
+ xmlNodeSetPtr base_nodes = base_node_obj->nodesetval;
+ int total_nodes = (base_nodes) ? base_nodes->nodeNr : 0;
if (total_nodes == 0) {
ERROR("curl_xml plugin: "
"xpath expression \"%s\" doesn't match any of the nodes. "
"Skipping the xpath block...",
- base_xpath);
+ xpath->path);
xmlXPathFreeObject(base_node_obj);
return -1;
}
/* If base_xpath returned multiple results, then */
- /* Instance in the xpath block is required */
- if (total_nodes > 1 && xpath->instance == NULL) {
+ /* InstanceFrom or PluginInstanceFrom in the xpath block is required */
+ if (total_nodes > 1 && xpath->instance == NULL &&
+ xpath->plugin_instance_from == NULL) {
ERROR("curl_xml plugin: "
- "InstanceFrom is must in xpath block since the base xpath expression "
- "\"%s\" "
+ "InstanceFrom or PluginInstanceFrom is must in xpath block "
+ "since the base xpath expression \"%s\" "
"returned multiple results. Skipping the xpath block...",
- base_xpath);
+ xpath->path);
+ xmlXPathFreeObject(base_node_obj);
return -1;
}
+ value_list_t vl = VALUE_LIST_INIT;
+
/* set the values for the value_list */
vl.values_len = ds->ds_num;
sstrncpy(vl.type, xpath->type, sizeof(vl.type));
- sstrncpy(vl.plugin, "curl_xml", sizeof(vl.plugin));
- sstrncpy(vl.host, host, sizeof(vl.host));
- if (plugin_instance != NULL)
- sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance));
+ sstrncpy(vl.plugin, (db->plugin_name != NULL) ? db->plugin_name : "curl_xml",
+ sizeof(vl.plugin));
+ sstrncpy(vl.host, cx_host(db), sizeof(vl.host));
for (int i = 0; i < total_nodes; i++) {
- int status;
-
xpath_ctx->node = base_nodes->nodeTab[i];
- status = cx_handle_instance_xpath(xpath_ctx, xpath, &vl,
- /* is_table = */ (total_nodes > 1));
- if (status != 0)
+ if (db->instance != NULL)
+ sstrncpy(vl.plugin_instance, db->instance, sizeof(vl.plugin_instance));
+
+ if (cx_handle_instance_xpath(xpath_ctx, xpath, &vl) != 0)
continue; /* An error has already been reported. */
- status = cx_handle_all_value_xpaths(xpath_ctx, xpath, ds, &vl);
- if (status != 0)
+ if (cx_handle_all_value_xpaths(xpath_ctx, xpath, ds, &vl) != 0)
continue; /* An error has been logged. */
} /* for (i = 0; i < total_nodes; i++) */
/* free up the allocated memory */
xmlXPathFreeObject(base_node_obj);
- return (0);
-} /* }}} cx_handle_base_xpath */
+ return 0;
+} /* }}} cx_handle_xpath */
-static int cx_handle_parsed_xml(xmlDocPtr doc, /* {{{ */
- xmlXPathContextPtr xpath_ctx, cx_t *db) {
- llentry_t *le;
- const data_set_t *ds;
- cx_xpath_t *xpath;
+static int cx_handle_parsed_xml(cx_t *db, xmlDocPtr doc, /* {{{ */
+ xmlXPathContextPtr xpath_ctx) {
int status = -1;
- le = llist_head(db->list);
+ llentry_t *le = llist_head(db->xpath_list);
while (le != NULL) {
- /* get the ds */
- xpath = (cx_xpath_t *)le->value;
- ds = plugin_get_ds(xpath->type);
+ cx_xpath_t *xpath = (cx_xpath_t *)le->value;
- if ((cx_check_type(ds, xpath) == 0) &&
- (cx_handle_base_xpath(db->instance, cx_host(db), xpath_ctx, ds, le->key,
- xpath) == 0))
+ if (cx_handle_xpath(db, xpath_ctx, xpath) == 0)
status = 0; /* we got atleast one success */
le = le->next;
return status;
} /* }}} cx_handle_parsed_xml */
-static int cx_parse_stats_xml(xmlChar *xml, cx_t *db) /* {{{ */
+static int cx_parse_xml(cx_t *db, char *xml) /* {{{ */
{
- int status;
- xmlDocPtr doc;
- xmlXPathContextPtr xpath_ctx;
-
/* Load the XML */
- doc = xmlParseDoc(xml);
+ xmlDocPtr doc = xmlParseDoc(BAD_CAST xml);
if (doc == NULL) {
ERROR("curl_xml plugin: Failed to parse the xml document - %s", xml);
- return (-1);
+ return -1;
}
- xpath_ctx = xmlXPathNewContext(doc);
+ xmlXPathContextPtr xpath_ctx = xmlXPathNewContext(doc);
if (xpath_ctx == NULL) {
ERROR("curl_xml plugin: Failed to create the xml context");
xmlFreeDoc(doc);
- return (-1);
+ return -1;
}
for (size_t i = 0; i < db->namespaces_num; i++) {
cx_namespace_t const *ns = db->namespaces + i;
- status =
+ int status =
xmlXPathRegisterNs(xpath_ctx, BAD_CAST ns->prefix, BAD_CAST ns->url);
if (status != 0) {
ERROR("curl_xml plugin: "
ns->prefix, ns->url);
xmlXPathFreeContext(xpath_ctx);
xmlFreeDoc(doc);
- return (status);
+ return status;
}
}
- status = cx_handle_parsed_xml(doc, xpath_ctx, db);
+ int status = cx_handle_parsed_xml(db, doc, xpath_ctx);
/* Cleanup */
xmlXPathFreeContext(xpath_ctx);
xmlFreeDoc(doc);
return status;
-} /* }}} cx_parse_stats_xml */
+} /* }}} cx_parse_xml */
-static int cx_curl_perform(cx_t *db, CURL *curl) /* {{{ */
+static int cx_read(user_data_t *ud) /* {{{ */
{
- int status;
+ if ((ud == NULL) || (ud->data == NULL)) {
+ ERROR("curl_xml plugin: cx_read: Invalid user data.");
+ return -1;
+ }
+
long rc;
- char *ptr;
char *url;
+ cx_t *db = (cx_t *)ud->data;
db->buffer_fill = 0;
curl_easy_setopt(db->curl, CURLOPT_URL, db->url);
- status = curl_easy_perform(curl);
+ int status = curl_easy_perform(db->curl);
if (status != CURLE_OK) {
ERROR("curl_xml plugin: curl_easy_perform failed with status %i: %s (%s)",
status, db->curl_errbuf, db->url);
- return (-1);
+ return -1;
}
if (db->stats != NULL)
curl_stats_dispatch(db->stats, db->curl, cx_host(db), "curl_xml",
db->instance);
- curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url);
- curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rc);
+ curl_easy_getinfo(db->curl, CURLINFO_EFFECTIVE_URL, &url);
+ curl_easy_getinfo(db->curl, CURLINFO_RESPONSE_CODE, &rc);
/* The response code is zero if a non-HTTP transport was used. */
if ((rc != 0) && (rc != 200)) {
ERROR(
"curl_xml plugin: curl_easy_perform failed with response code %ld (%s)",
rc, url);
- return (-1);
+ return -1;
}
- ptr = db->buffer;
-
- status = cx_parse_stats_xml(BAD_CAST ptr, db);
+ status = cx_parse_xml(db, db->buffer);
db->buffer_fill = 0;
return status;
-} /* }}} int cx_curl_perform */
-
-static int cx_read(user_data_t *ud) /* {{{ */
-{
- cx_t *db;
-
- if ((ud == NULL) || (ud->data == NULL)) {
- ERROR("curl_xml plugin: cx_read: Invalid user data.");
- return (-1);
- }
-
- db = (cx_t *)ud->data;
-
- return cx_curl_perform(db, db->curl);
} /* }}} int cx_read */
/* Configuration handling functions {{{ */
oconfig_item_t *ci) {
if (ci->values_num < 1) {
WARNING("curl_xml plugin: `ValuesFrom' needs at least one argument.");
- return (-1);
+ return -1;
}
for (int i = 0; i < ci->values_num; i++)
if (ci->values[i].type != OCONFIG_TYPE_STRING) {
WARNING("curl_xml plugin: `ValuesFrom' needs only string argument.");
- return (-1);
+ return -1;
}
sfree(xpath->values);
xpath->values_len = 0;
xpath->values = malloc(sizeof(cx_values_t) * ci->values_num);
if (xpath->values == NULL)
- return (-1);
+ return -1;
xpath->values_len = (size_t)ci->values_num;
/* populate cx_values_t structure */
sizeof(xpath->values[i].path));
}
- return (0);
+ return 0;
} /* }}} cx_config_add_values */
static int cx_config_add_xpath(cx_t *db, oconfig_item_t *ci) /* {{{ */
{
- cx_xpath_t *xpath;
- char *name;
- llentry_t *le;
- int status;
-
- xpath = calloc(1, sizeof(*xpath));
+ cx_xpath_t *xpath = calloc(1, sizeof(*xpath));
if (xpath == NULL) {
ERROR("curl_xml plugin: calloc failed.");
- return (-1);
+ return -1;
}
- status = cf_util_get_string(ci, &xpath->path);
+ int status = cf_util_get_string(ci, &xpath->path);
if (status != 0) {
cx_xpath_free(xpath);
- return (status);
+ return status;
}
/* error out if xpath->path is an empty string */
ERROR("curl_xml plugin: invalid xpath. "
"xpath value can't be an empty string");
cx_xpath_free(xpath);
- return (-1);
+ return -1;
}
status = 0;
status = cf_util_get_string(child, &xpath->instance_prefix);
else if (strcasecmp("InstanceFrom", child->key) == 0)
status = cf_util_get_string(child, &xpath->instance);
+ else if (strcasecmp("PluginInstanceFrom", child->key) == 0)
+ status = cf_util_get_string(child, &xpath->plugin_instance_from);
else if (strcasecmp("ValuesFrom", child->key) == 0)
status = cx_config_add_values("ValuesFrom", xpath, child);
else {
return -1;
}
- if (db->list == NULL) {
- db->list = llist_create();
- if (db->list == NULL) {
- ERROR("curl_xml plugin: list creation failed.");
- cx_xpath_free(xpath);
- return (-1);
- }
- }
-
- name = strdup(xpath->path);
- if (name == NULL) {
- ERROR("curl_xml plugin: strdup failed.");
+ if (xpath->values_len == 0) {
+ WARNING("curl_xml plugin: `ValuesFrom' missing in `xpath' block.");
cx_xpath_free(xpath);
- return (-1);
+ return -1;
}
- le = llentry_create(name, xpath);
+ llentry_t *le = llentry_create(xpath->path, xpath);
if (le == NULL) {
ERROR("curl_xml plugin: llentry_create failed.");
cx_xpath_free(xpath);
- sfree(name);
- return (-1);
+ return -1;
}
- llist_append(db->list, le);
- return (0);
+ llist_append(db->xpath_list, le);
+ return 0;
} /* }}} int cx_config_add_xpath */
static int cx_config_add_namespace(cx_t *db, /* {{{ */
oconfig_item_t *ci) {
- cx_namespace_t *ns;
if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) ||
(ci->values[1].type != OCONFIG_TYPE_STRING)) {
WARNING("curl_xml plugin: The `Namespace' option "
"needs exactly two string arguments.");
- return (EINVAL);
+ return EINVAL;
}
- ns = realloc(db->namespaces,
- sizeof(*db->namespaces) * (db->namespaces_num + 1));
+ cx_namespace_t *ns = realloc(
+ db->namespaces, sizeof(*db->namespaces) * (db->namespaces_num + 1));
if (ns == NULL) {
ERROR("curl_xml plugin: realloc failed.");
- return (ENOMEM);
+ return ENOMEM;
}
db->namespaces = ns;
ns = db->namespaces + db->namespaces_num;
sfree(ns->prefix);
sfree(ns->url);
ERROR("curl_xml plugin: strdup failed.");
- return (ENOMEM);
+ return ENOMEM;
}
db->namespaces_num++;
- return (0);
+ return 0;
} /* }}} int cx_config_add_namespace */
/* Initialize db->curl */
db->curl = curl_easy_init();
if (db->curl == NULL) {
ERROR("curl_xml plugin: curl_easy_init failed.");
- return (-1);
+ return -1;
}
curl_easy_setopt(db->curl, CURLOPT_NOSIGNAL, 1L);
db->credentials = malloc(credentials_size);
if (db->credentials == NULL) {
ERROR("curl_xml plugin: malloc failed.");
- return (-1);
+ return -1;
}
- ssnprintf(db->credentials, credentials_size, "%s:%s", db->user,
- (db->pass == NULL) ? "" : db->pass);
+ snprintf(db->credentials, credentials_size, "%s:%s", db->user,
+ (db->pass == NULL) ? "" : db->pass);
curl_easy_setopt(db->curl, CURLOPT_USERPWD, db->credentials);
#endif
(long)CDTIME_T_TO_MS(plugin_get_interval()));
#endif
- return (0);
+ return 0;
} /* }}} int cx_init_curl */
static int cx_config_add_url(oconfig_item_t *ci) /* {{{ */
{
- cx_t *db;
- int status = 0;
-
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("curl_xml plugin: The `URL' block "
"needs exactly one string argument.");
- return (-1);
+ return -1;
}
- db = calloc(1, sizeof(*db));
+ cx_t *db = calloc(1, sizeof(*db));
if (db == NULL) {
ERROR("curl_xml plugin: calloc failed.");
- return (-1);
+ return -1;
+ }
+
+ db->instance = strdup("default");
+ if (db->instance == NULL) {
+ ERROR("curl_xml plugin: strdup failed.");
+ sfree(db);
+ return -1;
+ }
+
+ db->xpath_list = llist_create();
+ if (db->xpath_list == NULL) {
+ ERROR("curl_xml plugin: list creation failed.");
+ sfree(db->instance);
+ sfree(db);
+ return -1;
}
db->timeout = -1;
- if (strcasecmp("URL", ci->key) == 0) {
- status = cf_util_get_string(ci, &db->url);
- if (status != 0) {
- sfree(db);
- return (status);
- }
- } else {
- ERROR("curl_xml plugin: cx_config: "
- "Invalid key: %s",
- ci->key);
- cx_free(db);
- return (-1);
+ int status = cf_util_get_string(ci, &db->url);
+ if (status != 0) {
+ llist_destroy(db->xpath_list);
+ sfree(db->instance);
+ sfree(db);
+ return status;
}
/* Fill the `cx_t' structure.. */
if (strcasecmp("Instance", child->key) == 0)
status = cf_util_get_string(child, &db->instance);
+ else if (strcasecmp("Plugin", child->key) == 0)
+ status = cf_util_get_string(child, &db->plugin_name);
else if (strcasecmp("Host", child->key) == 0)
status = cf_util_get_string(child, &db->host);
else if (strcasecmp("User", child->key) == 0)
break;
}
- if (status == 0) {
- if (db->list == NULL) {
- WARNING("curl_xml plugin: No (valid) `Key' block "
- "within `URL' block `%s'.",
- db->url);
- status = -1;
- }
- if (status == 0)
- status = cx_init_curl(db);
+ if (status != 0) {
+ cx_free(db);
+ return status;
}
- /* If all went well, register this database for reading */
- if (status == 0) {
- char *cb_name;
-
- if (db->instance == NULL)
- db->instance = strdup("default");
-
- DEBUG("curl_xml plugin: Registering new read callback: %s", db->instance);
-
- cb_name = ssnprintf_alloc("curl_xml-%s-%s", db->instance, db->url);
+ if (llist_size(db->xpath_list) == 0) {
+ WARNING("curl_xml plugin: No `xpath' block within `URL' block `%s'.",
+ db->url);
+ cx_free(db);
+ return -1;
+ }
- plugin_register_complex_read(/* group = */ "curl_xml", cb_name, cx_read,
- /* interval = */ 0,
- &(user_data_t){
- .data = db, .free_func = cx_free,
- });
- sfree(cb_name);
- } else {
+ if (cx_init_curl(db) != 0) {
cx_free(db);
- return (-1);
+ return -1;
}
- return (0);
+ /* If all went well, register this database for reading */
+ DEBUG("curl_xml plugin: Registering new read callback: %s", db->instance);
+
+ char *cb_name = ssnprintf_alloc("curl_xml-%s-%s", db->instance, db->url);
+
+ plugin_register_complex_read(/* group = */ "curl_xml", cb_name, cx_read,
+ /* interval = */ 0,
+ &(user_data_t){
+ .data = db, .free_func = cx_free,
+ });
+ sfree(cb_name);
+ return 0;
} /* }}} int cx_config_add_url */
/* }}} End of configuration handling functions */
static int cx_config(oconfig_item_t *ci) /* {{{ */
{
- int success;
- int errors;
- int status;
-
- success = 0;
- errors = 0;
+ int success = 0;
+ int errors = 0;
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
if (strcasecmp("URL", child->key) == 0) {
- status = cx_config_add_url(child);
- if (status == 0)
+ if (cx_config_add_url(child) == 0)
success++;
else
errors++;
if ((success == 0) && (errors > 0)) {
ERROR("curl_xml plugin: All statements failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cx_config */
static int cx_init(void) /* {{{ */
/* Call this while collectd is still single-threaded to avoid
* initialization issues in libgcrypt. */
curl_global_init(CURL_GLOBAL_SSL);
- return (0);
+ return 0;
} /* }}} int cx_init */
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 : */
+++ /dev/null
-AM_CPPFLAGS = -I$(top_srcdir)/src
-AM_CPPFLAGS += -DPREFIX='"${prefix}"'
-AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"'
-AM_CPPFLAGS += -DLOCALSTATEDIR='"${localstatedir}"'
-AM_CPPFLAGS += -DPKGLOCALSTATEDIR='"${localstatedir}/lib/${PACKAGE_NAME}"'
-if BUILD_FEATURE_DAEMON
-AM_CPPFLAGS += -DPIDFILE='"${localstatedir}/run/${PACKAGE_NAME}.pid"'
-endif
-AM_CPPFLAGS += -DPLUGINDIR='"${pkglibdir}"'
-AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"'
-
-# Link to these libraries..
-COMMON_LIBS = $(PTHREAD_LIBS)
-if BUILD_WITH_CAPABILITY
-COMMON_LIBS += -lcap
-endif
-if BUILD_WITH_LIBRT
-COMMON_LIBS += -lrt
-endif
-if BUILD_WITH_LIBPOSIX4
-COMMON_LIBS += -lposix4
-endif
-if BUILD_WITH_LIBSOCKET
-COMMON_LIBS += -lsocket
-endif
-if BUILD_WITH_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
#define COLLECTD_LOCALE "C"
#endif
-/*
- * Global variables
- */
-char hostname_g[DATA_MAX_NAME_LEN];
-cdtime_t interval_g;
-int timeout_g;
-#if HAVE_LIBKSTAT
-kstat_ctl_t *kc;
-#endif /* HAVE_LIBKSTAT */
-
static int loop = 0;
static void *do_flush(void __attribute__((unused)) * arg) {
}
static int init_hostname(void) {
- const char *str;
-
- struct addrinfo *ai_list;
- int status;
-
- str = global_option_get("Hostname");
+ const char *str = global_option_get("Hostname");
if ((str != NULL) && (str[0] != 0)) {
- sstrncpy(hostname_g, str, sizeof(hostname_g));
- return (0);
+ hostname_set(str);
+ return 0;
+ }
+
+ long hostname_len = sysconf(_SC_HOST_NAME_MAX);
+ if (hostname_len == -1) {
+ hostname_len = NI_MAXHOST;
}
+ char hostname[hostname_len];
- if (gethostname(hostname_g, sizeof(hostname_g)) != 0) {
+ if (gethostname(hostname, hostname_len) != 0) {
fprintf(stderr, "`gethostname' failed and no "
"hostname was configured.\n");
- return (-1);
+ return -1;
}
+ hostname_set(hostname);
+
str = global_option_get("FQDNLookup");
if (IS_FALSE(str))
- return (0);
+ return 0;
+ struct addrinfo *ai_list;
struct addrinfo ai_hints = {.ai_flags = AI_CANONNAME};
- status = getaddrinfo(hostname_g, NULL, &ai_hints, &ai_list);
+ int status = getaddrinfo(hostname, NULL, &ai_hints, &ai_list);
if (status != 0) {
ERROR("Looking up \"%s\" failed. You have set the "
"\"FQDNLookup\" option, but I cannot resolve "
"my hostname to a fully qualified domain "
"name. Please fix the network "
"configuration.",
- hostname_g);
- return (-1);
+ hostname);
+ return -1;
}
for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
if (ai_ptr->ai_canonname == NULL)
continue;
- sstrncpy(hostname_g, ai_ptr->ai_canonname, sizeof(hostname_g));
+ hostname_set(ai_ptr->ai_canonname);
break;
}
freeaddrinfo(ai_list);
- return (0);
+ return 0;
} /* int init_hostname */
static int init_global_variables(void) {
if (timeout_g <= 1) {
fprintf(stderr, "Cannot set the timeout to a correct value.\n"
"Please check your settings.\n");
- return (-1);
+ return -1;
}
DEBUG("timeout_g = %i;", timeout_g);
if (init_hostname() != 0)
- return (-1);
+ return -1;
DEBUG("hostname_g = %s;", hostname_g);
- return (0);
+ return 0;
} /* int init_global_variables */
-static int change_basedir(const char *orig_dir) {
+static int change_basedir(const char *orig_dir, _Bool create) {
char *dir;
size_t dirlen;
int status;
if (dir == NULL) {
char errbuf[1024];
ERROR("strdup failed: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
dirlen = strlen(dir);
if (dirlen == 0) {
free(dir);
- return (-1);
+ return -1;
}
status = chdir(dir);
if (status == 0) {
free(dir);
- return (0);
- } else if (errno != ENOENT) {
+ return 0;
+ } else if (!create || (errno != ENOENT)) {
char errbuf[1024];
ERROR("change_basedir: chdir (%s): %s", dir,
sstrerror(errno, errbuf, sizeof(errbuf)));
free(dir);
- return (-1);
+ return -1;
}
status = mkdir(dir, S_IRWXU | S_IRWXG | S_IRWXO);
ERROR("change_basedir: mkdir (%s): %s", dir,
sstrerror(errno, errbuf, sizeof(errbuf)));
free(dir);
- return (-1);
+ return -1;
}
status = chdir(dir);
ERROR("change_basedir: chdir (%s): %s", dir,
sstrerror(errno, errbuf, sizeof(errbuf)));
free(dir);
- return (-1);
+ return -1;
}
free(dir);
- return (0);
+ return 0;
} /* static int change_basedir (char *dir) */
#if HAVE_LIBKSTAT
#if COLLECT_DAEMON
" -f Don't fork to the background.\n"
#endif
+ " -B Don't create the BaseDir\n"
" -h Display help (this message)\n"
"\nBuiltin defaults:\n"
" Config file " CONFIGFILE "\n"
#endif
)) {
ERROR("sg_init: %s", sg_str_error(sg_get_error()));
- return (-1);
+ return -1;
}
if (sg_drop_privileges()) {
ERROR("sg_drop_privileges: %s", sg_str_error(sg_get_error()));
- return (-1);
+ return -1;
}
#endif
if (errno != EINTR) {
char errbuf[1024];
ERROR("nanosleep failed: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
}
} /* while (loop == 0) */
- return (0);
+ return 0;
} /* int do_loop */
static int do_shutdown(void) {
if ((fh = fopen(file, "w")) == NULL) {
char errbuf[1024];
ERROR("fopen (%s): %s", file, sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
+ return 1;
}
fprintf(fh, "%i\n", (int)getpid());
fclose(fh);
- return (0);
+ return 0;
} /* static int pidfile_create (const char *file) */
static int pidfile_remove(void) {
if (file == NULL)
return 0;
- return (unlink(file));
+ return unlink(file);
} /* static int pidfile_remove (const char *file) */
#endif /* COLLECT_DAEMON */
}
#endif /* KERNEL_LINUX */
-int main(int argc, char **argv) {
- const char *configfile = CONFIGFILE;
- int test_config = 0;
- int test_readall = 0;
- const char *basedir;
-#if COLLECT_DAEMON
- pid_t pid;
- int daemonize = 1;
-#endif
- int exit_status = 0;
+struct cmdline_config {
+ _Bool test_config;
+ _Bool test_readall;
+ _Bool create_basedir;
+ const char *configfile;
+ _Bool daemonize;
+};
+void read_cmdline(int argc, char **argv, struct cmdline_config *config) {
/* read options */
while (1) {
int c;
-
c = getopt(argc, argv, "htTC:"
#if COLLECT_DAEMON
"fP:"
break;
switch (c) {
+ case 'B':
+ config->create_basedir = 0;
+ break;
case 'C':
- configfile = optarg;
+ config->configfile = optarg;
break;
case 't':
- test_config = 1;
+ config->test_config = 1;
break;
case 'T':
- test_readall = 1;
+ config->test_readall = 1;
global_option_set("ReadThreads", "-1", 1);
#if COLLECT_DAEMON
- daemonize = 0;
+ config->daemonize = 0;
#endif /* COLLECT_DAEMON */
break;
#if COLLECT_DAEMON
global_option_set("PIDFile", optarg, 1);
break;
case 'f':
- daemonize = 0;
+ config->daemonize = 0;
break;
#endif /* COLLECT_DAEMON */
case 'h':
exit_usage(1);
} /* switch (c) */
} /* while (1) */
+}
- if (optind < argc)
- exit_usage(1);
-
- plugin_init_ctx();
-
+int configure_collectd(struct cmdline_config *config) {
+ const char *basedir;
/*
* Read options from the config file, the environment and the command
* line (in that order, with later options overwriting previous ones in
* general).
* Also, this will automatically load modules.
*/
- if (cf_read(configfile)) {
+ if (cf_read(config->configfile)) {
fprintf(stderr, "Error: Reading the config file failed!\n"
"Read the logs for details.\n");
- return (1);
+ return 1;
}
/*
if ((basedir = global_option_get("BaseDir")) == NULL) {
fprintf(stderr,
"Don't have a basedir to use. This should not happen. Ever.");
- return (1);
- } else if (change_basedir(basedir)) {
+ return 1;
+ } else if (change_basedir(basedir, config->create_basedir)) {
fprintf(stderr, "Error: Unable to change to directory `%s'.\n", basedir);
- return (1);
+ return 1;
}
/*
- * Set global variables or, if that failes, exit. We cannot run with
+ * Set global variables or, if that fails, exit. We cannot run with
* them being uninitialized. If nothing is configured, then defaults
* are being used. So this means that the user has actually done
* something wrong.
*/
if (init_global_variables() != 0)
- exit(EXIT_FAILURE);
+ return 1;
- if (test_config)
- return (0);
+ return 0;
+}
+
+int main(int argc, char **argv) {
+#if COLLECT_DAEMON
+ pid_t pid;
+#endif
+ int exit_status = 0;
+
+ struct cmdline_config config = {
+ .daemonize = 1, .create_basedir = 1, .configfile = CONFIGFILE,
+ };
+
+ read_cmdline(argc, argv, &config);
+
+ if (config.test_config)
+ return 0;
+
+ if (optind < argc)
+ exit_usage(1);
+
+ plugin_init_ctx();
+
+ int status;
+ if ((status = configure_collectd(&config)) != 0)
+ exit(EXIT_FAILURE);
#if COLLECT_DAEMON
/*
* Only daemonize if we're not being supervised
* by upstart or systemd (when using Linux).
*/
- if (daemonize
+ if (config.daemonize
#ifdef KERNEL_LINUX
&& notify_upstart() == 0 && notify_systemd() == 0
#endif
/* error */
char errbuf[1024];
fprintf(stderr, "fork: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
+ return 1;
} else if (pid != 0) {
/* parent */
/* printf ("Running (PID %i)\n", pid); */
- return (0);
+ return 0;
}
/* Detach from session */
if (status != 0) {
ERROR("Error: Could not connect `STDIN' to `/dev/null' (status %d)",
status);
- return (1);
+ return 1;
}
status = dup(0);
if (status != 1) {
ERROR("Error: Could not connect `STDOUT' to `/dev/null' (status %d)",
status);
- return (1);
+ return 1;
}
status = dup(0);
if (status != 2) {
ERROR("Error: Could not connect `STDERR' to `/dev/null', (status %d)",
status);
- return (1);
+ return 1;
}
- } /* if (daemonize) */
+ } /* if (config.daemonize) */
#endif /* COLLECT_DAEMON */
struct sigaction sig_pipe_action = {.sa_handler = SIG_IGN};
char errbuf[1024];
ERROR("Error: Failed to install a signal handler for signal INT: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
+ return 1;
}
struct sigaction sig_term_action = {.sa_handler = sig_term_handler};
char errbuf[1024];
ERROR("Error: Failed to install a signal handler for signal TERM: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
+ return 1;
}
struct sigaction sig_usr1_action = {.sa_handler = sig_usr1_handler};
char errbuf[1024];
ERROR("Error: Failed to install a signal handler for signal USR1: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
+ return 1;
}
/*
exit_status = 1;
}
- if (test_readall) {
+ if (config.test_readall) {
if (plugin_read_all_once() != 0) {
ERROR("Error: one or more plugin read callbacks failed.");
exit_status = 1;
}
#if COLLECT_DAEMON
- if (daemonize)
+ if (config.daemonize)
pidfile_remove();
#endif /* COLLECT_DAEMON */
- return (exit_status);
+ return exit_status;
} /* int main */
#include "config.h"
#endif
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
-#if STDC_HEADERS
-#include <stddef.h>
-#include <stdlib.h>
-#else
-#if HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#endif
-#if HAVE_STRING_H
-#if !STDC_HEADERS && HAVE_MEMORY_H
-#include <memory.h>
-#endif
-#include <string.h>
-#endif
#if HAVE_STRINGS_H
#include <strings.h>
#endif
-#if HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifndef WIFEXITED
#define WIFEXITED(stat_val) (((stat_val)&255) == 0)
#endif
-#if HAVE_SIGNAL_H
-#include <signal.h>
-#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
-#if HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#if HAVE_LIMITS_H
-#include <limits.h>
-#endif
#if TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#include <sys/socket.h>
#endif
-#if HAVE_ASSERT_H
-#include <assert.h>
-#else
-#define assert(...) /* nop */
-#endif
-
-#if !defined(HAVE__BOOL) || !HAVE__BOOL
-typedef int _Bool;
-#undef HAVE__BOOL
-#define HAVE__BOOL 1
-#endif
-
#if NAN_STATIC_DEFAULT
#include <math.h>
/* #endif NAN_STATIC_DEFAULT*/
#endif
#endif
-#if HAVE_STDARG_H
-#include <stdarg.h>
-#endif
-#if HAVE_CTYPE_H
-#include <ctype.h>
-#endif
#if HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
-#if HAVE_KSTAT_H
-#include <kstat.h>
-#endif
-
#ifndef PACKAGE_NAME
#define PACKAGE_NAME "collectd"
#endif
/* Only enable __attribute__() for compilers known to support it. */
#if !defined(__clang__) && !defined(__GNUC__)
-#if !defined(__attribute__)
#define __attribute__(x) /**/
#endif
-#endif
#if defined(COLLECT_DEBUG) && COLLECT_DEBUG && defined(__GNUC__) && __GNUC__
#undef strcpy
#define GAUGE_FORMAT "%.15g"
#endif
-/* Type for time as used by "utils_time.h" */
-typedef uint64_t cdtime_t;
-
-extern char hostname_g[];
-extern cdtime_t interval_g;
-extern int timeout_g;
+#include "globals.h"
#endif /* COLLECTD_H */
#include "plugin.h"
#include "utils_cache.h"
-#ifdef HAVE_MATH_H
-#include <math.h>
-#endif
-
/* for getaddrinfo */
#include <netdb.h>
#include <sys/types.h>
strncpy(dest, src, n);
dest[n - 1] = '\0';
- return (dest);
+ return dest;
} /* char *sstrncpy */
-int ssnprintf(char *dest, size_t n, const char *format, ...) {
- int ret = 0;
- va_list ap;
-
- va_start(ap, format);
- ret = vsnprintf(dest, n, format, ap);
- dest[n - 1] = '\0';
- va_end(ap);
-
- return (ret);
-} /* int ssnprintf */
-
char *ssnprintf_alloc(char const *format, ...) /* {{{ */
{
char static_buffer[1024] = "";
status = vsnprintf(static_buffer, sizeof(static_buffer), format, ap);
va_end(ap);
if (status < 0)
- return (NULL);
+ return NULL;
/* "status" does not include the null byte. */
alloc_buffer_size = (size_t)(status + 1);
if (alloc_buffer_size <= sizeof(static_buffer))
- return (strdup(static_buffer));
+ return strdup(static_buffer);
/* Allocate a buffer large enough to hold the string. */
alloc_buffer = calloc(1, alloc_buffer_size);
if (alloc_buffer == NULL)
- return (NULL);
+ return NULL;
/* Print again into this new buffer. */
va_start(ap, format);
va_end(ap);
if (status < 0) {
sfree(alloc_buffer);
- return (NULL);
+ return NULL;
}
- return (alloc_buffer);
+ return alloc_buffer;
} /* }}} char *ssnprintf_alloc */
char *sstrdup(const char *s) {
size_t sz;
if (s == NULL)
- return (NULL);
+ return NULL;
/* Do not use `strdup' here, because it's not specified in POSIX. It's
* ``only'' an XSI extension. */
ERROR("sstrdup: Out of memory.");
exit(3);
}
- memcpy(r, s, sizeof(char) * sz);
+ memcpy(r, s, sz);
- return (r);
+ return r;
} /* char *sstrdup */
/* Even though Posix requires "strerror_r" to return an "int",
#else
if (strerror_r(errnum, buf, buflen) != 0) {
- ssnprintf(buf, buflen, "Error #%i; "
- "Additionally, strerror_r failed.",
- errnum);
+ snprintf(buf, buflen, "Error #%i; "
+ "Additionally, strerror_r failed.",
+ errnum);
}
#endif /* STRERROR_R_CHAR_P */
- return (buf);
+ return buf;
} /* char *sstrerror */
void *smalloc(size_t size) {
exit(3);
}
- return (r);
+ return r;
} /* void *smalloc */
#if 0
}
#endif
-ssize_t sread(int fd, void *buf, size_t count) {
+int sread(int fd, void *buf, size_t count) {
char *ptr;
size_t nleft;
ssize_t status;
continue;
if (status < 0)
- return (status);
+ return status;
if (status == 0) {
- DEBUG("Received EOF from fd %i. "
- "Closing fd and returning error.",
- fd);
- close(fd);
- return (-1);
+ DEBUG("Received EOF from fd %i. ", fd);
+ return -1;
}
assert((0 > status) || (nleft >= (size_t)status));
ptr = ptr + ((size_t)status);
}
- return (0);
+ return 0;
}
-ssize_t swrite(int fd, const void *buf, size_t count) {
+int swrite(int fd, const void *buf, size_t count) {
const char *ptr;
size_t nleft;
ssize_t status;
if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) {
/* if recv returns zero (even though poll() said there is data to be
* read), that means the connection has been closed */
- return errno ? errno : -1;
+ errno = ECONNRESET;
+ return -1;
}
}
ptr = ptr + ((size_t)status);
}
- return (0);
+ return 0;
}
int strsplit(char *string, char **fields, size_t size) {
break;
}
- return ((int)i);
+ return (int)i;
}
int strjoin(char *buffer, size_t buffer_size, char **fields, size_t fields_num,
if (((fields_num != 0) && (fields == NULL)) ||
((buffer_size != 0) && (buffer == NULL)))
- return (-EINVAL);
+ return -EINVAL;
if (buffer != NULL)
buffer[0] = 0;
/* Check if we need to escape at all first */
temp = strpbrk(buffer, " \t\"\\");
if (temp == NULL)
- return (0);
+ return 0;
if (buffer_size < 3)
- return (EINVAL);
+ return EINVAL;
temp = calloc(1, buffer_size);
if (temp == NULL)
- return (ENOMEM);
+ return ENOMEM;
temp[0] = '"';
j = 1;
sstrncpy(buffer, temp, buffer_size);
sfree(temp);
- return (0);
+ return 0;
} /* int escape_string */
int strunescape(char *buf, size_t buf_len) {
ERROR("string unescape: backslash found at end of string.");
/* Ensure null-byte at the end of the buffer. */
buf[i] = 0;
- return (-1);
+ return -1;
}
switch (buf[i + 1]) {
memmove(buf + i + 1, buf + i + 2, buf_len - i - 2);
buf[buf_len - 1] = 0;
}
- return (0);
+ return 0;
} /* int strunescape */
size_t strstripnewline(char *buffer) {
buffer[buffer_len] = 0;
}
- return (buffer_len);
+ return buffer_len;
} /* size_t strstripnewline */
int escape_slashes(char *buffer, size_t buffer_size) {
if (buffer_len <= 1) {
if (strcmp("/", buffer) == 0) {
if (buffer_size < 5)
- return (-1);
+ return -1;
sstrncpy(buffer, "root", buffer_size);
}
- return (0);
+ return 0;
}
/* Move one to the left */
buffer[i] = '_';
}
- return (0);
+ return 0;
} /* int escape_slashes */
void replace_special(char *buffer, size_t buffer_size) {
delta->tv_sec = 0;
delta->tv_usec = 0;
}
- return (0);
+ return 0;
}
if ((tv0.tv_sec < tv1.tv_sec) ||
assert((delta == NULL) ||
((0 <= delta->tv_usec) && (delta->tv_usec < 1000000)));
- return (status);
+ return status;
} /* int timeval_cmp */
int check_create_dir(const char *file_orig) {
* Sanity checks first
*/
if (file_orig == NULL)
- return (-1);
+ return -1;
if ((len = strlen(file_orig)) < 1)
- return (-1);
+ return -1;
else if (len >= sizeof(file_copy))
- return (-1);
+ return -1;
/*
* If `file_orig' ends in a slash the last component is a directory,
ERROR("Cowardly refusing to create a directory that "
"begins with a `.' (dot): `%s'",
file_orig);
- return (-2);
+ return -2;
}
/*
if (strjoin(dir + path_is_absolute, (size_t)(dir_len - path_is_absolute),
fields, (size_t)(i + 1), "/") < 0) {
ERROR("strjoin failed: `%s', component #%i", file_orig, i);
- return (-1);
+ return -1;
}
while (42) {
char errbuf[1024];
ERROR("check_create_dir: mkdir (%s): %s", dir,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
} else {
char errbuf[1024];
ERROR("check_create_dir: stat (%s): %s", dir,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
} else if (!S_ISDIR(statbuf.st_mode)) {
ERROR("check_create_dir: `%s' exists but is not "
"a directory!",
dir);
- return (-1);
+ return -1;
}
break;
}
}
- return (0);
+ return 0;
} /* check_create_dir */
#ifdef HAVE_LIBKSTAT
*ksp_ptr = NULL;
if (kc == NULL)
- return (-1);
+ return -1;
- ssnprintf(ident, sizeof(ident), "%s,%i,%s", module, instance, name);
+ snprintf(ident, sizeof(ident), "%s,%i,%s", module, instance, name);
*ksp_ptr = kstat_lookup(kc, module, instance, name);
if (*ksp_ptr == NULL) {
ERROR("get_kstat: Cound not find kstat %s", ident);
- return (-1);
+ return -1;
}
if ((*ksp_ptr)->ks_type != KSTAT_TYPE_NAMED) {
ERROR("get_kstat: kstat %s has wrong type", ident);
*ksp_ptr = NULL;
- return (-1);
+ return -1;
}
#ifdef assert
if (kstat_read(kc, *ksp_ptr, NULL) == -1) {
ERROR("get_kstat: kstat %s could not be read", ident);
- return (-1);
+ return -1;
}
if ((*ksp_ptr)->ks_type != KSTAT_TYPE_NAMED) {
ERROR("get_kstat: kstat %s has wrong type", ident);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
long long get_kstat_value(kstat_t *ksp, char *name) {
if (ksp == NULL) {
ERROR("get_kstat_value (\"%s\"): ksp is NULL.", name);
- return (-1LL);
+ return -1LL;
} else if (ksp->ks_type != KSTAT_TYPE_NAMED) {
ERROR("get_kstat_value (\"%s\"): ksp->ks_type (%#x) "
"is not KSTAT_TYPE_NAMED (%#x).",
name, (unsigned int)ksp->ks_type, (unsigned int)KSTAT_TYPE_NAMED);
- return (-1LL);
+ return -1LL;
}
if ((kn = (kstat_named_t *)kstat_data_lookup(ksp, name)) == NULL)
- return (-1LL);
+ return -1LL;
if (kn->data_type == KSTAT_DATA_INT32)
retval = (long long)kn->value.i32;
else
WARNING("get_kstat_value: Not a numeric value: %s", name);
- return (retval);
+ return retval;
}
#endif /* HAVE_LIBKSTAT */
#ifndef HAVE_HTONLL
unsigned long long ntohll(unsigned long long n) {
#if BYTE_ORDER == BIG_ENDIAN
- return (n);
+ return n;
#else
return (((unsigned long long)ntohl(n)) << 32) + ntohl(n >> 32);
#endif
unsigned long long htonll(unsigned long long n) {
#if BYTE_ORDER == BIG_ENDIAN
- return (n);
+ return n;
#else
return (((unsigned long long)htonl(n)) << 32) + htonl(n >> 32);
#endif
if ((ret.byte[0] == 0x00) && (ret.byte[1] == 0x00) && (ret.byte[2] == 0x00) &&
(ret.byte[3] == 0x00) && (ret.byte[4] == 0x00) && (ret.byte[5] == 0x00) &&
(ret.byte[6] == 0xf8) && (ret.byte[7] == 0x7f)) {
- return (NAN);
+ return NAN;
} else {
uint64_t tmp;
tmp = ret.integer;
ret.integer = FP_CONVERT(tmp);
- return (ret.floating);
+ return ret.floating;
}
} /* double ntohd */
ret.byte[4] = ret.byte[5] = 0x00;
ret.byte[6] = 0xf8;
ret.byte[7] = 0x7f;
- return (ret.floating);
+ return ret.floating;
} else {
uint64_t tmp;
ret.floating = d;
tmp = FP_CONVERT(ret.integer);
ret.integer = tmp;
- return (ret.floating);
+ return ret.floating;
}
} /* double htond */
#endif /* FP_LAYOUT_NEED_ENDIANFLIP || FP_LAYOUT_NEED_INTSWAP */
do { \
size_t l = strlen(str); \
if (l >= buffer_size) \
- return (ENOBUFS); \
+ return ENOBUFS; \
memcpy(buffer, (str), l); \
buffer += l; \
buffer_size -= l; \
buffer[0] = 0;
#undef APPEND
- return (0);
+ return 0;
} /* int format_name */
int format_values(char *ret, size_t ret_len, /* {{{ */
#define BUFFER_ADD(...) \
do { \
- status = ssnprintf(ret + offset, ret_len - offset, __VA_ARGS__); \
+ status = snprintf(ret + offset, ret_len - offset, __VA_ARGS__); \
if (status < 1) { \
sfree(rates); \
- return (-1); \
+ return -1; \
} else if (((size_t)status) >= (ret_len - offset)) { \
sfree(rates); \
- return (-1); \
+ return -1; \
} else \
offset += ((size_t)status); \
} while (0)
rates = uc_get_rate(ds, vl);
if (rates == NULL) {
WARNING("format_values: uc_get_rate failed.");
- return (-1);
+ return -1;
}
BUFFER_ADD(":" GAUGE_FORMAT, rates[i]);
} else if (ds->ds[i].type == DS_TYPE_COUNTER)
else {
ERROR("format_values: Unknown data source type: %i", ds->ds[i].type);
sfree(rates);
- return (-1);
+ return -1;
}
} /* for ds->ds_num */
#undef BUFFER_ADD
sfree(rates);
- return (0);
+ return 0;
} /* }}} int format_values */
int parse_identifier(char *str, char **ret_host, char **ret_plugin,
hostname = str;
if (hostname == NULL)
- return (-1);
+ return -1;
plugin = strchr(hostname, '/');
if (plugin == NULL)
- return (-1);
+ return -1;
*plugin = '\0';
plugin++;
type = strchr(plugin, '/');
if (type == NULL) {
if (default_host == NULL)
- return (-1);
+ return -1;
/* else: no host specified; use default */
type = plugin;
plugin = hostname;
*ret_plugin_instance = plugin_instance;
*ret_type = type;
*ret_type_instance = type_instance;
- return (0);
+ return 0;
} /* int parse_identifier */
int parse_identifier_vl(const char *str, value_list_t *vl) /* {{{ */
int status;
if ((str == NULL) || (vl == NULL))
- return (EINVAL);
+ return EINVAL;
sstrncpy(str_copy, str, sizeof(str_copy));
&type_instance,
/* default_host = */ NULL);
if (status != 0)
- return (status);
+ return status;
sstrncpy(vl->host, host, sizeof(vl->host));
sstrncpy(vl->plugin, plugin, sizeof(vl->plugin));
sstrncpy(vl->type_instance, (type_instance != NULL) ? type_instance : "",
sizeof(vl->type_instance));
- return (0);
+ return 0;
} /* }}} int parse_identifier_vl */
int parse_value(const char *value_orig, value_t *ret_value, int ds_type) {
size_t value_len;
if (value_orig == NULL)
- return (EINVAL);
+ return EINVAL;
value = strdup(value_orig);
if (value == NULL)
- return (ENOMEM);
+ return ENOMEM;
value_len = strlen(value);
while ((value_len > 0) && isspace((int)value[value_len - 1])) {
|| (endptr == ptr) /* Invalid string */
|| (endptr == NULL) /* This should not happen */
|| (*endptr != 0)) /* Trailing chars */
- return (-1);
+ return -1;
vl->time = DOUBLE_TO_CDTIME_T(tmp);
}
} /* while (strtok_r) */
if ((ptr != NULL) || (i == 0))
- return (-1);
- return (0);
+ return -1;
+ return 0;
} /* int parse_values */
int parse_value_file(char const *path, value_t *ret_value, int ds_type) {
fh = fopen(path, "r");
if (fh == NULL)
- return (-1);
+ return -1;
if (fgets(buffer, sizeof(buffer), fh) == NULL) {
fclose(fh);
- return (-1);
+ return -1;
}
fclose(fh);
pthread_mutex_unlock(&getpwnam_r_lock);
- return (status);
+ return status;
} /* int getpwnam_r */
#endif /* !HAVE_GETPWNAM_R */
if (type_instance != NULL)
sstrncpy(n->type_instance, type_instance, sizeof(n->type_instance));
- return (0);
+ return 0;
} /* int notification_init */
int walk_directory(const char *dir, dirwalk_callback_f callback,
closedir(dh);
if ((success == 0) && (failure > 0))
- return (-1);
- return (0);
+ return -1;
+ return 0;
}
ssize_t read_file_contents(const char *filename, char *buf, size_t bufsize) {
fh = fopen(filename, "r");
if (fh == NULL)
- return (-1);
+ return -1;
ret = (ssize_t)fread(buf, 1, bufsize, fh);
if ((ret == 0) && (ferror(fh) != 0)) {
}
fclose(fh);
- return (ret);
+ return ret;
}
counter_t counter_diff(counter_t old_value, counter_t new_value) {
diff = new_value - old_value;
}
- return (diff);
+ return diff;
} /* counter_t counter_diff */
int rate_to_value(value_t *ret_value, gauge_t rate, /* {{{ */
state->last_time = t;
*ret_value = state->last_value;
- return (0);
+ return 0;
}
/* Counter and absolute can't handle negative rates. Reset "last time"
if ((rate < 0.0) &&
((ds_type == DS_TYPE_COUNTER) || (ds_type == DS_TYPE_ABSOLUTE))) {
memset(state, 0, sizeof(*state));
- return (EINVAL);
+ return EINVAL;
}
/* Another invalid state: The time is not increasing. */
if (t <= state->last_time) {
memset(state, 0, sizeof(*state));
- return (EINVAL);
+ return EINVAL;
}
delta_t = t - state->last_time;
}
state->last_time = t;
- return (EAGAIN);
+ return EAGAIN;
} /* }}} */
if (ds_type == DS_TYPE_DERIVE) {
state->last_time = t;
*ret_value = state->last_value;
- return (0);
+ return 0;
} /* }}} value_t rate_to_value */
int value_to_rate(gauge_t *ret_rate, /* {{{ */
/* Another invalid state: The time is not increasing. */
if (t <= state->last_time) {
memset(state, 0, sizeof(*state));
- return (EINVAL);
+ return EINVAL;
}
interval = CDTIME_T_TO_DOUBLE(t - state->last_time);
if (state->last_time == 0) {
state->last_value = value;
state->last_time = t;
- return (EAGAIN);
+ return EAGAIN;
}
switch (ds_type) {
state->last_value = value;
state->last_time = t;
- return (0);
+ return 0;
} /* }}} value_t rate_to_value */
int service_name_to_port_number(const char *service_name) {
int service_number;
if (service_name == NULL)
- return (-1);
+ return -1;
struct addrinfo ai_hints = {.ai_family = AF_UNSPEC};
if (status != 0) {
ERROR("service_name_to_port_number: getaddrinfo failed: %s",
gai_strerror(status));
- return (-1);
+ return -1;
}
service_number = -1;
freeaddrinfo(ai_list);
if ((service_number > 0) && (service_number <= 65535))
- return (service_number);
- return (-1);
+ return service_number;
+ return -1;
} /* int service_name_to_port_number */
void set_sock_opts(int sockfd) /* {{{ */
char *endptr;
if ((string == NULL) || (ret_value == NULL))
- return (EINVAL);
+ return EINVAL;
errno = 0;
endptr = NULL;
tmp = (derive_t)strtoll(string, &endptr, /* base = */ 0);
if ((endptr == string) || (errno != 0))
- return (-1);
+ return -1;
*ret_value = tmp;
- return (0);
+ return 0;
} /* }}} int strtoderive */
int strtogauge(const char *string, gauge_t *ret_value) /* {{{ */
char *endptr = NULL;
if ((string == NULL) || (ret_value == NULL))
- return (EINVAL);
+ return EINVAL;
errno = 0;
endptr = NULL;
tmp = (gauge_t)strtod(string, &endptr);
if (errno != 0)
- return (errno);
+ return errno;
else if ((endptr == NULL) || (*endptr != 0))
- return (EINVAL);
+ return EINVAL;
*ret_value = tmp;
- return (0);
+ return 0;
} /* }}} int strtogauge */
int strarray_add(char ***ret_array, size_t *ret_array_len,
size_t array_len = *ret_array_len;
if (str == NULL)
- return (EINVAL);
+ return EINVAL;
array = realloc(*ret_array, (array_len + 1) * sizeof(*array));
if (array == NULL)
- return (ENOMEM);
+ return ENOMEM;
*ret_array = array;
array[array_len] = strdup(str);
if (array[array_len] == NULL)
- return (ENOMEM);
+ return ENOMEM;
array_len++;
*ret_array_len = array_len;
- return (0);
+ return 0;
} /* }}} int strarray_add */
void strarray_free(char **array, size_t array_len) /* {{{ */
cap_flag_value_t cap_flag_value;
if (!CAP_IS_SUPPORTED(cap_value))
- return (-1);
+ return -1;
if (!(cap = cap_get_proc())) {
ERROR("check_capability: cap_get_proc failed.");
- return (-1);
+ return -1;
}
if (cap_get_flag(cap, cap_value, CAP_EFFECTIVE, &cap_flag_value) < 0) {
ERROR("check_capability: cap_get_flag failed.");
cap_free(cap);
- return (-1);
+ return -1;
}
cap_free(cap);
- return (cap_flag_value != CAP_SET);
+ return cap_flag_value != CAP_SET;
} /* }}} int check_capability */
#else
int check_capability(__attribute__((unused)) int arg) /* {{{ */
{
WARNING("check_capability: unsupported capability implementation. "
"Some plugin(s) may require elevated privileges to work properly.");
- return (0);
+ return 0;
} /* }}} int check_capability */
#endif /* HAVE_CAPABILITY */
char *sstrncpy(char *dest, const char *src, size_t n);
-__attribute__((format(printf, 3, 4))) int ssnprintf(char *dest, size_t n,
- const char *format, ...);
-
__attribute__((format(printf, 1, 2))) char *ssnprintf_alloc(char const *format,
...);
*
* DESCRIPTION
* Reads exactly `n' bytes or fails. Syntax and other behavior is analogous
- * to `read(2)'. If EOF is received the file descriptor is closed and an
- * error is returned.
+ * to `read(2)'.
*
* PARAMETERS
* `fd' File descriptor to write to.
* Zero upon success or non-zero if an error occurred. `errno' is set in this
* case.
*/
-ssize_t sread(int fd, void *buf, size_t count);
+int sread(int fd, void *buf, size_t count);
/*
* NAME
* Zero upon success or non-zero if an error occurred. `errno' is set in this
* case.
*/
-ssize_t swrite(int fd, const void *buf, size_t count);
+int swrite(int fd, const void *buf, size_t count);
/*
* NAME
EXPECT_EQ_STR("collect", ptr);
OK(buffer[3] == buffer[12]);
- return (0);
-}
-
-DEF_TEST(ssnprintf) {
- char buffer[16] = "";
- char *ptr = &buffer[4];
- int status;
-
- buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xff;
- buffer[12] = buffer[13] = buffer[14] = buffer[15] = 0xff;
-
- status = ssnprintf(ptr, 8, "%i", 1337);
- OK(status == 4);
- EXPECT_EQ_STR("1337", ptr);
-
- status = ssnprintf(ptr, 8, "%s", "collectd");
- OK(status == 8);
- OK(ptr[7] == 0);
- EXPECT_EQ_STR("collect", ptr);
- OK(buffer[3] == buffer[12]);
-
- return (0);
+ return 0;
}
DEF_TEST(sstrdup) {
ptr = sstrdup(NULL);
OK(ptr == NULL);
- return (0);
+ return 0;
}
DEF_TEST(strsplit) {
status = strsplit(buffer, fields, 8);
OK(status == 0);
- return (0);
+ return 0;
}
DEF_TEST(strjoin) {
/* use (NULL, 0) to determine required buffer size. */
EXPECT_EQ_INT(3, strjoin(NULL, 0, (char *[]){"a", "b"}, 2, "-"));
- return (0);
+ return 0;
}
DEF_TEST(escape_slashes) {
status = strunescape(buffer, sizeof(buffer));
OK(status != 0);
EXPECT_EQ_STR("\tbackslash end", buffer);
- return (0);
+ return 0;
/* Backslash at buffer end */
strncpy(buffer, "\\t3\\56", sizeof(buffer));
OK(buffer[5] == '6');
OK(buffer[6] == '7');
- return (0);
+ return 0;
}
DEF_TEST(parse_values) {
EXPECT_EQ_DOUBLE(cases[i].value, vl.values[0].gauge);
}
- return (0);
+ return 0;
}
DEF_TEST(value_to_rate) {
int main(void) {
RUN_TEST(sstrncpy);
- RUN_TEST(ssnprintf);
RUN_TEST(sstrdup);
RUN_TEST(strsplit);
RUN_TEST(strjoin);
END_TEST;
}
-
-/* vim: set sw=2 sts=2 et : */
cf_callback_t *cf_cb;
if (type == NULL)
- return (NULL);
+ return NULL;
for (cf_cb = first_callback; cf_cb != NULL; cf_cb = cf_cb->next)
if (strcasecmp(cf_cb->type, type) == 0)
break;
- return (cf_cb);
+ return cf_cb;
}
static int cf_dispatch(const char *type, const char *orig_key,
int i = 0;
if (orig_key == NULL)
- return (EINVAL);
+ return EINVAL;
DEBUG("type = %s, key = %s, value = %s", ESCAPE_NULL(type), orig_key,
ESCAPE_NULL(orig_value));
"the plugin isn't loaded or didn't register "
"a configuration callback.",
type);
- return (-1);
+ return -1;
}
if ((key = strdup(orig_key)) == NULL)
- return (1);
+ return 1;
if ((value = strdup(orig_value)) == NULL) {
free(key);
- return (2);
+ return 2;
}
ret = -1;
free(key);
free(value);
- return (ret);
+ return ret;
} /* int cf_dispatch */
static int dispatch_global_option(const oconfig_item_t *ci) {
if (ci->values_num != 1)
- return (-1);
+ return -1;
if (ci->values[0].type == OCONFIG_TYPE_STRING)
- return (global_option_set(ci->key, ci->values[0].value.string, 0));
+ return global_option_set(ci->key, ci->values[0].value.string, 0);
else if (ci->values[0].type == OCONFIG_TYPE_NUMBER) {
char tmp[128];
- ssnprintf(tmp, sizeof(tmp), "%lf", ci->values[0].value.number);
- return (global_option_set(ci->key, tmp, 0));
+ snprintf(tmp, sizeof(tmp), "%lf", ci->values[0].value.number);
+ return global_option_set(ci->key, tmp, 0);
} else if (ci->values[0].type == OCONFIG_TYPE_BOOLEAN) {
if (ci->values[0].value.boolean)
- return (global_option_set(ci->key, "true", 0));
+ return global_option_set(ci->key, "true", 0);
else
- return (global_option_set(ci->key, "false", 0));
+ return global_option_set(ci->key, "false", 0);
}
- return (-1);
+ return -1;
} /* int dispatch_global_option */
static int dispatch_value_typesdb(oconfig_item_t *ci) {
if (ci->values_num < 1) {
ERROR("configfile: `TypesDB' needs at least one argument.");
- return (-1);
+ return -1;
}
for (int i = 0; i < ci->values_num; ++i) {
read_types_list(ci->values[i].value.string);
}
- return (0);
+ return 0;
} /* int dispatch_value_typesdb */
static int dispatch_value_plugindir(oconfig_item_t *ci) {
assert(strcasecmp(ci->key, "PluginDir") == 0);
if (ci->values_num != 1)
- return (-1);
+ return -1;
if (ci->values[0].type != OCONFIG_TYPE_STRING)
- return (-1);
+ return -1;
plugin_set_dir(ci->values[0].value.string);
- return (0);
+ return 0;
}
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;
assert(strcasecmp(ci->key, "LoadPlugin") == 0);
if (ci->values_num != 1)
- return (-1);
+ return -1;
if (ci->values[0].type != OCONFIG_TYPE_STRING)
- return (-1);
+ return -1;
name = ci->values[0].value.string;
if (strcmp("libvirt", name) == 0)
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)
}
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);
- return (ret_val);
+ return ret_val;
} /* int dispatch_value_loadplugin */
static int dispatch_value_plugin(const char *plugin, oconfig_item_t *ci) {
if (ci->values[i].type == OCONFIG_TYPE_STRING)
status =
- ssnprintf(buffer_ptr, buffer_free, " %s", ci->values[i].value.string);
+ snprintf(buffer_ptr, buffer_free, " %s", ci->values[i].value.string);
else if (ci->values[i].type == OCONFIG_TYPE_NUMBER)
- status = ssnprintf(buffer_ptr, buffer_free, " %lf",
- ci->values[i].value.number);
+ status =
+ snprintf(buffer_ptr, buffer_free, " %lf", ci->values[i].value.number);
else if (ci->values[i].type == OCONFIG_TYPE_BOOLEAN)
- status = ssnprintf(buffer_ptr, buffer_free, " %s",
- ci->values[i].value.boolean ? "true" : "false");
+ status = snprintf(buffer_ptr, buffer_free, " %s",
+ ci->values[i].value.boolean ? "true" : "false");
if ((status < 0) || (status >= buffer_free))
- return (-1);
+ return -1;
buffer_free -= status;
buffer_ptr += status;
}
/* skip the initial space */
buffer_ptr = buffer + 1;
- return (cf_dispatch(plugin, ci->key, buffer_ptr));
+ return cf_dispatch(plugin, ci->key, buffer_ptr);
} /* int dispatch_value_plugin */
static int dispatch_value(oconfig_item_t *ci) {
break;
}
- return (ret);
+ return ret;
} /* int dispatch_value */
static int dispatch_block_plugin(oconfig_item_t *ci) {
const char *name;
if (strcasecmp(ci->key, "Plugin") != 0)
- return (-1);
+ return -1;
if (ci->values_num < 1)
- return (-1);
+ return -1;
if (ci->values[0].type != OCONFIG_TYPE_STRING)
- return (-1);
+ return -1;
name = ci->values[0].value.string;
if (strcmp("libvirt", name) == 0) {
ERROR("Automatically loading plugin \"%s\" failed "
"with status %i.",
name, status);
- return (status);
+ return status;
}
}
old_ctx = plugin_set_ctx(cb->ctx);
ret_val = (cb->callback(ci));
plugin_set_ctx(old_ctx);
- return (ret_val);
+ return ret_val;
}
}
}
}
- return (0);
+ return 0;
}
static int dispatch_block(oconfig_item_t *ci) {
if (strcasecmp(ci->key, "LoadPlugin") == 0)
- return (dispatch_loadplugin(ci));
+ return dispatch_loadplugin(ci);
else if (strcasecmp(ci->key, "Plugin") == 0)
- return (dispatch_block_plugin(ci));
+ return dispatch_block_plugin(ci);
else if (strcasecmp(ci->key, "Chain") == 0)
- return (fc_configure(ci));
+ return fc_configure(ci);
- return (0);
+ return 0;
}
static int cf_ci_replace_child(oconfig_item_t *dst, oconfig_item_t *src,
* all children. */
if (dst->children_num + src->children_num - 1 == 0) {
dst->children_num = 0;
- return (0);
+ return 0;
}
- temp =
- realloc(dst->children, sizeof(oconfig_item_t) *
- (dst->children_num + src->children_num - 1));
+ temp = realloc(dst->children,
+ sizeof(oconfig_item_t) *
+ (dst->children_num + src->children_num - 1));
if (temp == NULL) {
ERROR("configfile: realloc failed.");
- return (-1);
+ return -1;
}
dst->children = temp;
/* Update the number of children. */
dst->children_num += (src->children_num - 1);
- return (0);
+ return 0;
} /* int cf_ci_replace_child */
static int cf_ci_append_children(oconfig_item_t *dst, oconfig_item_t *src) {
oconfig_item_t *temp;
if ((src == NULL) || (src->children_num == 0))
- return (0);
+ return 0;
- temp = realloc(dst->children, sizeof(oconfig_item_t) *
- (dst->children_num + src->children_num));
+ temp =
+ realloc(dst->children,
+ sizeof(oconfig_item_t) * (dst->children_num + src->children_num));
if (temp == NULL) {
ERROR("configfile: realloc failed.");
- return (-1);
+ return -1;
}
dst->children = temp;
sizeof(oconfig_item_t) * src->children_num);
dst->children_num += src->children_num;
- return (0);
+ return 0;
} /* int cf_ci_append_children */
#define CF_MAX_DEPTH 8
sfree(pattern);
if (new == NULL)
- return (-1);
+ return -1;
/* Now replace the i'th child in `root' with `new'. */
if (cf_ci_replace_child(root, new, i) < 0) {
sfree(new->values);
sfree(new);
- return (-1);
+ return -1;
}
/* ... and go back to the new i'th child. */
sfree(new);
} /* for (i = 0; i < root->children_num; i++) */
- return (0);
+ return 0;
} /* int cf_include_all */
static oconfig_item_t *cf_read_file(const char *file, const char *pattern,
"does not match pattern `%s'.",
filename, pattern);
free(tmp);
- return (NULL);
+ return NULL;
}
free(tmp);
root = oconfig_parse_file(file);
if (root == NULL) {
ERROR("configfile: Cannot read file `%s'.", file);
- return (NULL);
+ return NULL;
}
status = cf_include_all(root, depth);
if (status != 0) {
oconfig_free(root);
- return (NULL);
+ return NULL;
}
- return (root);
+ return root;
} /* oconfig_item_t *cf_read_file */
static int cf_compare_string(const void *p1, const void *p2) {
char errbuf[1024];
ERROR("configfile: opendir failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (NULL);
+ return NULL;
}
root = calloc(1, sizeof(*root));
if (root == NULL) {
ERROR("configfile: calloc failed.");
closedir(dh);
- return (NULL);
+ return NULL;
}
while ((de = readdir(dh)) != NULL) {
if ((de->d_name[0] == '.') || (de->d_name[0] == 0))
continue;
- status = ssnprintf(name, sizeof(name), "%s/%s", dir, de->d_name);
+ status = snprintf(name, sizeof(name), "%s/%s", dir, de->d_name);
if ((status < 0) || ((size_t)status >= sizeof(name))) {
ERROR("configfile: Not including `%s/%s' because its"
" name is too long.",
free(filenames[i]);
free(filenames);
free(root);
- return (NULL);
+ return NULL;
}
++filenames_num;
free(filenames[i]);
free(filenames);
free(root);
- return (NULL);
+ return NULL;
}
filenames = tmp;
if (filenames == NULL) {
closedir(dh);
- return (root);
+ return root;
}
qsort((void *)filenames, filenames_num, sizeof(*filenames),
closedir(dh);
free(filenames);
- return (root);
+ return root;
} /* oconfig_item_t *cf_read_dir */
/*
ERROR("configfile: Not including `%s' because the maximum "
"nesting depth has been reached.",
path);
- return (NULL);
+ return NULL;
}
status = wordexp(path, &we, WRDE_NOCMD);
if (status != 0) {
ERROR("configfile: wordexp (%s) failed.", path);
- return (NULL);
+ return NULL;
}
root = calloc(1, sizeof(*root));
if (root == NULL) {
ERROR("configfile: calloc failed.");
- return (NULL);
+ return NULL;
}
/* wordexp() might return a sorted list already. That's not
if (temp == NULL) {
oconfig_free(root);
- return (NULL);
+ return NULL;
}
cf_ci_append_children(root, temp);
wordfree(&we);
- return (root);
+ return root;
} /* oconfig_item_t *cf_read_generic */
/* #endif HAVE_WORDEXP_H */
ERROR("configfile: Not including `%s' because the maximum "
"nesting depth has been reached.",
path);
- return (NULL);
+ return NULL;
}
status = stat(path, &statbuf);
char errbuf[1024];
ERROR("configfile: stat (%s) failed: %s", path,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (NULL);
+ return NULL;
}
if (S_ISREG(statbuf.st_mode))
- return (cf_read_file(path, pattern, depth));
+ return cf_read_file(path, pattern, depth);
else if (S_ISDIR(statbuf.st_mode))
- return (cf_read_dir(path, pattern, depth));
+ return cf_read_dir(path, pattern, depth);
ERROR("configfile: %s is neither a file nor a directory.", path);
- return (NULL);
+ return NULL;
} /* oconfig_item_t *cf_read_generic */
#endif /* !HAVE_WORDEXP_H */
if (i >= cf_global_options_num) {
ERROR("configfile: Cannot set unknown global option `%s'.", option);
- return (-1);
+ return -1;
}
if (cf_global_options[i].from_cli && (!from_cli)) {
DEBUG("configfile: Ignoring %s `%s' option because "
"it was overriden by a command-line option.",
option, value);
- return (0);
+ return 0;
}
sfree(cf_global_options[i].value);
cf_global_options[i].from_cli = from_cli;
- return (0);
+ return 0;
}
const char *global_option_get(const char *option) {
if (i >= cf_global_options_num) {
ERROR("configfile: Cannot get unknown global option `%s'.", option);
- return (NULL);
+ return NULL;
}
- return ((cf_global_options[i].value != NULL) ? cf_global_options[i].value
- : cf_global_options[i].def);
+ return (cf_global_options[i].value != NULL) ? cf_global_options[i].value
+ : cf_global_options[i].def;
} /* char *global_option_get */
long global_option_get_long(const char *option, long default_value) {
str = global_option_get(option);
if (NULL == str)
- return (default_value);
+ return default_value;
errno = 0;
value = strtol(str, /* endptr = */ NULL, /* base = */ 0);
if (errno != 0)
- return (default_value);
+ return default_value;
- return (value);
+ return value;
} /* char *global_option_get_long */
cdtime_t global_option_get_time(const char *name, cdtime_t def) /* {{{ */
optstr = global_option_get(name);
if (optstr == NULL)
- return (def);
+ return def;
errno = 0;
v = strtod(optstr, &endptr);
if ((endptr == NULL) || (*endptr != 0) || (errno != 0))
- return (def);
+ return def;
else if (v <= 0.0)
- return (def);
+ return def;
- return (DOUBLE_TO_CDTIME_T(v));
+ return DOUBLE_TO_CDTIME_T(v);
} /* }}} cdtime_t global_option_get_time */
cdtime_t cf_get_default_interval(void) {
- return (global_option_get_time(
- "Interval", DOUBLE_TO_CDTIME_T(COLLECTD_DEFAULT_INTERVAL)));
+ return global_option_get_time("Interval",
+ DOUBLE_TO_CDTIME_T(COLLECTD_DEFAULT_INTERVAL));
}
void cf_unregister(const char *type) {
new = malloc(sizeof(*new));
if (new == NULL)
- return (-1);
+ return -1;
new->type = strdup(type);
if (new->type == NULL) {
sfree(new);
- return (-1);
+ return -1;
}
new->callback = callback;
last->next = new;
}
- return (0);
+ return 0;
} /* int cf_register_complex */
int cf_read(const char *filename) {
conf = cf_read_generic(filename, /* pattern = */ NULL, /* depth = */ 0);
if (conf == NULL) {
ERROR("Unable to read config file %s.", filename);
- return (-1);
+ return -1;
} else if (conf->children_num == 0) {
ERROR("Configuration file %s is empty.", filename);
oconfig_free(conf);
- return (-1);
+ return -1;
}
for (int i = 0; i < conf->children_num; i++) {
}
return ret;
+
} /* int cf_read */
/* Assures the config option is a string, duplicates it and returns the copy in
ERROR("cf_util_get_string: The %s option requires "
"exactly one string argument.",
ci->key);
- return (-1);
+ return -1;
}
string = strdup(ci->values[0].value.string);
if (string == NULL)
- return (-1);
+ return -1;
if (*ret_string != NULL)
sfree(*ret_string);
*ret_string = string;
- return (0);
+ return 0;
} /* }}} int cf_util_get_string */
/* Assures the config option is a string and copies it to the provided buffer.
int cf_util_get_string_buffer(const oconfig_item_t *ci, char *buffer, /* {{{ */
size_t buffer_size) {
if ((ci == NULL) || (buffer == NULL) || (buffer_size < 1))
- return (EINVAL);
+ return EINVAL;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
ERROR("cf_util_get_string_buffer: The %s option requires "
"exactly one string argument.",
ci->key);
- return (-1);
+ return -1;
}
strncpy(buffer, ci->values[0].value.string, buffer_size);
buffer[buffer_size - 1] = 0;
- return (0);
+ return 0;
} /* }}} int cf_util_get_string_buffer */
/* Assures the config option is a number and returns it as an int. */
int cf_util_get_int(const oconfig_item_t *ci, int *ret_value) /* {{{ */
{
if ((ci == NULL) || (ret_value == NULL))
- return (EINVAL);
+ return EINVAL;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) {
ERROR("cf_util_get_int: The %s option requires "
"exactly one numeric argument.",
ci->key);
- return (-1);
+ return -1;
}
*ret_value = (int)ci->values[0].value.number;
- return (0);
+ return 0;
} /* }}} int cf_util_get_int */
int cf_util_get_double(const oconfig_item_t *ci, double *ret_value) /* {{{ */
{
if ((ci == NULL) || (ret_value == NULL))
- return (EINVAL);
+ return EINVAL;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) {
ERROR("cf_util_get_double: The %s option requires "
"exactly one numeric argument.",
ci->key);
- return (-1);
+ return -1;
}
*ret_value = ci->values[0].value.number;
- return (0);
+ return 0;
} /* }}} int cf_util_get_double */
int cf_util_get_boolean(const oconfig_item_t *ci, _Bool *ret_bool) /* {{{ */
{
if ((ci == NULL) || (ret_bool == NULL))
- return (EINVAL);
+ return EINVAL;
if ((ci->values_num != 1) || ((ci->values[0].type != OCONFIG_TYPE_BOOLEAN) &&
(ci->values[0].type != OCONFIG_TYPE_STRING))) {
ERROR("cf_util_get_boolean: The %s option requires "
"exactly one boolean argument.",
ci->key);
- return (-1);
+ return -1;
}
switch (ci->values[0].type) {
ERROR("cf_util_get_boolean: Cannot parse string value `%s' of the `%s' "
"option as a boolean value.",
ci->values[0].value.string, ci->key);
- return (-1);
+ return -1;
}
break;
}
- return (0);
+ return 0;
} /* }}} int cf_util_get_boolean */
int cf_util_get_flag(const oconfig_item_t *ci, /* {{{ */
_Bool b;
if (ret_value == NULL)
- return (EINVAL);
+ return EINVAL;
b = 0;
status = cf_util_get_boolean(ci, &b);
if (status != 0)
- return (status);
+ return status;
if (b) {
*ret_value |= flag;
*ret_value &= ~flag;
}
- return (0);
+ return 0;
} /* }}} int cf_util_get_flag */
/* Assures that the config option is a string or a number if the correct range
ERROR("cf_util_get_port_number: The \"%s\" option requires "
"exactly one string argument.",
ci->key);
- return (-1);
+ return -1;
}
if (ci->values[0].type == OCONFIG_TYPE_STRING)
- return (service_name_to_port_number(ci->values[0].value.string));
+ return service_name_to_port_number(ci->values[0].value.string);
assert(ci->values[0].type == OCONFIG_TYPE_NUMBER);
tmp = (int)(ci->values[0].value.number + 0.5);
"you specified, %i, is not in the valid "
"range of 1-65535.",
ci->key, tmp);
- return (-1);
+ return -1;
}
- return (tmp);
+ return tmp;
} /* }}} int cf_util_get_port_number */
int cf_util_get_service(const oconfig_item_t *ci, char **ret_string) /* {{{ */
ERROR("cf_util_get_service: The %s option requires exactly "
"one argument.",
ci->key);
- return (-1);
+ return -1;
}
if (ci->values[0].type == OCONFIG_TYPE_STRING)
- return (cf_util_get_string(ci, ret_string));
+ return cf_util_get_string(ci, ret_string);
if (ci->values[0].type != OCONFIG_TYPE_NUMBER) {
ERROR("cf_util_get_service: The %s option requires "
"exactly one string or numeric argument.",
port = 0;
status = cf_util_get_int(ci, &port);
if (status != 0)
- return (status);
+ return status;
else if ((port < 1) || (port > 65535)) {
ERROR("cf_util_get_service: The port number given "
"for the %s option is out of "
"range (%i).",
ci->key, port);
- return (-1);
+ return -1;
}
service = malloc(6);
if (service == NULL) {
ERROR("cf_util_get_service: Out of memory.");
- return (-1);
+ return -1;
}
- ssnprintf(service, 6, "%i", port);
+ snprintf(service, 6, "%i", port);
sfree(*ret_string);
*ret_string = service;
- return (0);
+ return 0;
} /* }}} int cf_util_get_service */
int cf_util_get_cdtime(const oconfig_item_t *ci, cdtime_t *ret_value) /* {{{ */
{
if ((ci == NULL) || (ret_value == NULL))
- return (EINVAL);
+ return EINVAL;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) {
ERROR("cf_util_get_cdtime: The %s option requires "
"exactly one numeric argument.",
ci->key);
- return (-1);
+ return -1;
}
if (ci->values[0].value.number < 0.0) {
ERROR("cf_util_get_cdtime: The numeric argument of the %s "
"option must not be negative.",
ci->key);
- return (-1);
+ return -1;
}
*ret_value = DOUBLE_TO_CDTIME_T(ci->values[0].value.number);
- return (0);
+ return 0;
} /* }}} int cf_util_get_cdtime */
char *dest;
if (orig == NULL)
- return (NULL);
+ return NULL;
sz = strlen(orig) + 1;
dest = malloc(sz);
if (dest == NULL)
- return (NULL);
+ return NULL;
memcpy(dest, orig, sz);
- return (dest);
+ return dest;
} /* }}} char *fc_strdup */
/*
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("Filter subsystem: `Match' blocks require "
"exactly one string argument.");
- return (-1);
+ return -1;
}
ptr = match_list_head;
WARNING("Filter subsystem: Cannot find a \"%s\" match. "
"Did you load the appropriate plugin?",
ci->values[0].value.string);
- return (-1);
+ return -1;
}
m = calloc(1, sizeof(*m));
if (m == NULL) {
ERROR("fc_config_add_match: calloc failed.");
- return (-1);
+ return -1;
}
sstrncpy(m->name, ptr->name, sizeof(m->name));
if (status != 0) {
WARNING("Filter subsystem: Failed to create a %s match.", m->name);
fc_free_matches(m);
- return (-1);
+ return -1;
}
}
*matches_head = m;
}
- return (0);
+ return 0;
} /* }}} int fc_config_add_match */
static int fc_config_add_target(fc_target_t **targets_head, /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("Filter subsystem: `Target' blocks require "
"exactly one string argument.");
- return (-1);
+ return -1;
}
ptr = target_list_head;
WARNING("Filter subsystem: Cannot find a \"%s\" target. "
"Did you load the appropriate plugin?",
ci->values[0].value.string);
- return (-1);
+ return -1;
}
t = calloc(1, sizeof(*t));
if (t == NULL) {
ERROR("fc_config_add_target: calloc failed.");
- return (-1);
+ return -1;
}
sstrncpy(t->name, ptr->name, sizeof(t->name));
if (status != 0) {
WARNING("Filter subsystem: Failed to create a %s target.", t->name);
fc_free_targets(t);
- return (-1);
+ return -1;
}
} else {
t->user_data = NULL;
*targets_head = t;
}
- return (0);
+ return 0;
} /* }}} int fc_config_add_target */
static int fc_config_add_rule(fc_chain_t *chain, /* {{{ */
if (ci->values_num > 1) {
WARNING("Filter subsystem: `Rule' blocks have at most one argument.");
- return (-1);
+ return -1;
} else if ((ci->values_num == 1) &&
(ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("Filter subsystem: `Rule' blocks expect one string argument "
"or no argument at all.");
- return (-1);
+ return -1;
}
rule = calloc(1, sizeof(*rule));
if (rule == NULL) {
ERROR("fc_config_add_rule: calloc failed.");
- return (-1);
+ return -1;
}
if (ci->values_num == 1) {
sstrncpy(rule->name, ci->values[0].value.string, sizeof(rule->name));
- ssnprintf(rule_name, sizeof(rule_name), "Rule \"%s\"",
- ci->values[0].value.string);
+ snprintf(rule_name, sizeof(rule_name), "Rule \"%s\"",
+ ci->values[0].value.string);
}
for (int i = 0; i < ci->children_num; i++) {
if (status != 0) {
fc_free_rules(rule);
- return (-1);
+ return -1;
}
if (chain->rules != NULL) {
chain->rules = rule;
}
- return (0);
+ return 0;
} /* }}} int fc_config_add_rule */
static int fc_config_add_chain(const oconfig_item_t *ci) /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("Filter subsystem: <Chain> blocks require exactly one "
"string argument.");
- return (-1);
+ return -1;
}
if (chain_list_head != NULL) {
chain = calloc(1, sizeof(*chain));
if (chain == NULL) {
ERROR("fc_config_add_chain: calloc failed.");
- return (-1);
+ return -1;
}
sstrncpy(chain->name, ci->values[0].value.string, sizeof(chain->name));
}
if (status != 0) {
fc_free_chains(chain);
- return (-1);
+ return -1;
}
if (chain_list_head != NULL) {
if (!new_chain)
- return (0);
+ return 0;
fc_chain_t *ptr;
chain_list_head = chain;
}
- return (0);
+ return 0;
} /* }}} int fc_config_add_chain */
/*
if (ci->children_num != 1) {
ERROR("Filter subsystem: The built-in target `jump' needs exactly "
"one `Chain' argument!");
- return (-1);
+ return -1;
}
ci_chain = ci->children;
ERROR("Filter subsystem: The built-in target `jump' does not "
"support the configuration option `%s'.",
ci_chain->key);
- return (-1);
+ return -1;
}
if ((ci_chain->values_num != 1) ||
(ci_chain->values[0].type != OCONFIG_TYPE_STRING)) {
ERROR("Filter subsystem: Built-in target `jump': The `Chain' option "
"needs exactly one string argument.");
- return (-1);
+ return -1;
}
*user_data = fc_strdup(ci_chain->values[0].value.string);
if (*user_data == NULL) {
ERROR("fc_bit_jump_create: fc_strdup failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int fc_bit_jump_create */
static int fc_bit_jump_destroy(void **user_data) /* {{{ */
*user_data = NULL;
}
- return (0);
+ return 0;
} /* }}} int fc_bit_jump_destroy */
static int fc_bit_jump_invoke(const data_set_t *ds, /* {{{ */
ERROR("Filter subsystem: Built-in target `jump': There is no chain "
"named `%s'.",
chain_name);
- return (-1);
+ return -1;
}
status = fc_process_chain(ds, vl, chain);
if (status < 0)
- return (status);
+ return status;
else if (status == FC_TARGET_STOP)
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
else
- return (FC_TARGET_CONTINUE);
+ return FC_TARGET_CONTINUE;
} /* }}} int fc_bit_jump_invoke */
static int
value_list_t __attribute__((unused)) * vl,
notification_meta_t __attribute__((unused)) * *meta,
void __attribute__((unused)) * *user_data) {
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
} /* }}} int fc_bit_stop_invoke */
static int
value_list_t __attribute__((unused)) * vl,
notification_meta_t __attribute__((unused)) * *meta,
void __attribute__((unused)) * *user_data) {
- return (FC_TARGET_RETURN);
+ return FC_TARGET_RETURN;
} /* }}} int fc_bit_return_invoke */
static int fc_bit_write_create(const oconfig_item_t *ci, /* {{{ */
*user_data = plugin_list;
- return (0);
+ return 0;
} /* }}} int fc_bit_write_create */
static int fc_bit_write_destroy(void **user_data) /* {{{ */
fc_writer_t *plugin_list;
if ((user_data == NULL) || (*user_data == NULL))
- return (0);
+ return 0;
plugin_list = *user_data;
free(plugin_list[i].plugin);
free(plugin_list);
- return (0);
+ return 0;
} /* }}} int fc_bit_write_destroy */
static int fc_bit_write_invoke(const data_set_t *ds, /* {{{ */
} /* for (i = 0; plugin_list[i] != NULL; i++) */
}
- return (FC_TARGET_CONTINUE);
+ return FC_TARGET_CONTINUE;
} /* }}} int fc_bit_write_invoke */
static int fc_init_once(void) /* {{{ */
target_proc_t tproc = {0};
if (done != 0)
- return (0);
+ return 0;
tproc.create = fc_bit_jump_create;
tproc.destroy = fc_bit_jump_destroy;
fc_register_target("write", tproc);
done++;
- return (0);
+ return 0;
} /* }}} int fc_init_once */
/*
m = calloc(1, sizeof(*m));
if (m == NULL)
- return (-ENOMEM);
+ return -ENOMEM;
sstrncpy(m->name, name, sizeof(m->name));
memcpy(&m->proc, &proc, sizeof(m->proc));
ptr->next = m;
}
- return (0);
+ return 0;
} /* }}} int fc_register_match */
/* Add a target to list of available targets. */
t = calloc(1, sizeof(*t));
if (t == NULL)
- return (-ENOMEM);
+ return -ENOMEM;
sstrncpy(t->name, name, sizeof(t->name));
memcpy(&t->proc, &proc, sizeof(t->proc));
ptr->next = t;
}
- return (0);
+ return 0;
} /* }}} int fc_register_target */
fc_chain_t *fc_chain_get_by_name(const char *chain_name) /* {{{ */
{
if (chain_name == NULL)
- return (NULL);
+ return NULL;
for (fc_chain_t *chain = chain_list_head; chain != NULL; chain = chain->next)
if (strcasecmp(chain_name, chain->name) == 0)
- return (chain);
+ return chain;
- return (NULL);
+ return NULL;
} /* }}} int fc_chain_get_by_name */
int fc_process_chain(const data_set_t *ds, value_list_t *vl, /* {{{ */
int status = FC_TARGET_CONTINUE;
if (chain == NULL)
- return (-1);
+ return -1;
DEBUG("fc_process_chain (chain = %s);", chain->name);
} /* for (rule) */
if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN))
- return (status);
+ return status;
DEBUG("fc_process_chain (%s): Executing the default targets.", chain->name);
chain->name, target->name,
(status == FC_TARGET_STOP) ? "stop" : "return");
if (status == FC_TARGET_STOP)
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
else
- return (FC_TARGET_CONTINUE);
+ return FC_TARGET_CONTINUE;
}
DEBUG("fc_process_chain (%s): Signaling `continue' at end of chain.",
chain->name);
- return (FC_TARGET_CONTINUE);
+ return FC_TARGET_CONTINUE;
} /* }}} int fc_process_chain */
/* Iterate over all rules in the chain and execute all targets for which all
int fc_default_action(const data_set_t *ds, value_list_t *vl) /* {{{ */
{
/* FIXME: Pass the meta-data to match targets here (when implemented). */
- return (fc_bit_write_invoke(ds, vl,
- /* meta = */ NULL, /* user_data = */ NULL));
+ return fc_bit_write_invoke(ds, vl, NULL, NULL);
} /* }}} int fc_default_action */
int fc_configure(const oconfig_item_t *ci) /* {{{ */
fc_init_once();
if (ci == NULL)
- return (-EINVAL);
+ return -EINVAL;
if (strcasecmp("Chain", ci->key) == 0)
- return (fc_config_add_chain(ci));
+ return fc_config_add_chain(ci);
WARNING("Filter subsystem: Unknown top level config option `%s'.", ci->key);
- return (-1);
+ return -1;
} /* }}} int fc_configure */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
int fc_configure(const oconfig_item_t *ci);
#endif /* FILTER_CHAIN_H */
-/* vim: set sw=2 sts=2 et : */
--- /dev/null
+/**
+ * collectd - src/globals.c
+ * Copyright (C) 2017 Google LLC
+ *
+ * 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.
+ **/
+
+#include "common.h"
+#include "globals.h"
+
+#if HAVE_KSTAT_H
+#include <kstat.h>
+#endif
+
+/*
+ * Global variables
+ */
+char *hostname_g;
+cdtime_t interval_g;
+int timeout_g;
+#if HAVE_KSTAT_H
+kstat_ctl_t *kc;
+#endif
+
+void hostname_set(char const *hostname) {
+ char *h = strdup(hostname);
+ if (h == NULL)
+ return;
+
+ sfree(hostname_g);
+ hostname_g = h;
+}
--- /dev/null
+/**
+ * collectd - src/globals.h
+ * Copyright (C) 2017 Google LLC
+ *
+ * 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.
+ **/
+
+#ifndef GLOBALS_H
+#define GLOBALS_H
+
+#include <inttypes.h>
+
+#ifndef DATA_MAX_NAME_LEN
+#define DATA_MAX_NAME_LEN 128
+#endif
+
+/* Type for time as used by "utils_time.h" */
+typedef uint64_t cdtime_t;
+
+/* hostname_set updates hostname_g */
+void hostname_set(char const *hostname);
+
+extern char *hostname_g;
+extern cdtime_t interval_g;
+extern int pidfile_from_cli;
+extern int timeout_g;
+#endif /* GLOBALS_H */
char *dest;
if (orig == NULL)
- return (NULL);
+ return NULL;
sz = strlen(orig) + 1;
dest = malloc(sz);
if (dest == NULL)
- return (NULL);
+ return NULL;
memcpy(dest, orig, sz);
- return (dest);
+ return dest;
} /* }}} char *md_strdup */
static meta_entry_t *md_entry_alloc(const char *key) /* {{{ */
e = calloc(1, sizeof(*e));
if (e == NULL) {
ERROR("md_entry_alloc: calloc failed.");
- return (NULL);
+ return NULL;
}
e->key = md_strdup(key);
if (e->key == NULL) {
free(e);
ERROR("md_entry_alloc: md_strdup failed.");
- return (NULL);
+ return NULL;
}
e->type = 0;
e->next = NULL;
- return (e);
+ return e;
} /* }}} meta_entry_t *md_entry_alloc */
/* XXX: The lock on md must be held while calling this function! */
copy = md_entry_alloc(orig->key);
if (copy == NULL)
- return (NULL);
+ return NULL;
copy->type = orig->type;
if (copy->type == MD_TYPE_STRING)
copy->value.mv_string = strdup(orig->value.mv_string);
else
copy->value = orig->value;
- return (copy);
+ return copy;
} /* }}} meta_entry_t *md_entry_clone_contents */
static meta_entry_t *md_entry_clone(const meta_entry_t *orig) /* {{{ */
meta_entry_t *copy;
if (orig == NULL)
- return (NULL);
+ return NULL;
copy = md_entry_clone_contents(orig);
copy->next = md_entry_clone(orig->next);
- return (copy);
+ return copy;
} /* }}} meta_entry_t *md_entry_clone */
static void md_entry_free(meta_entry_t *e) /* {{{ */
meta_entry_t *prev;
if ((md == NULL) || (e == NULL))
- return (-EINVAL);
+ return -EINVAL;
pthread_mutex_lock(&md->lock);
md_entry_free(this);
}
- return (0);
+ return 0;
} /* }}} int md_entry_insert */
/* XXX: The lock on md must be held while calling this function! */
md_entry_free(this);
}
- return (0);
+ return 0;
} /* }}} int md_entry_insert_clone */
/* XXX: The lock on md must be held while calling this function! */
meta_entry_t *e;
if ((md == NULL) || (key == NULL))
- return (NULL);
+ return NULL;
for (e = md->head; e != NULL; e = e->next)
if (strcasecmp(key, e->key) == 0)
break;
- return (e);
+ return e;
} /* }}} meta_entry_t *md_entry_lookup */
/*
md = calloc(1, sizeof(*md));
if (md == NULL) {
ERROR("meta_data_create: calloc failed.");
- return (NULL);
+ return NULL;
}
pthread_mutex_init(&md->lock, /* attr = */ NULL);
- return (md);
+ return md;
} /* }}} meta_data_t *meta_data_create */
meta_data_t *meta_data_clone(meta_data_t *orig) /* {{{ */
meta_data_t *copy;
if (orig == NULL)
- return (NULL);
+ return NULL;
copy = meta_data_create();
if (copy == NULL)
- return (NULL);
+ return NULL;
pthread_mutex_lock(&orig->lock);
copy->head = md_entry_clone(orig->head);
pthread_mutex_unlock(&orig->lock);
- return (copy);
+ return copy;
} /* }}} meta_data_t *meta_data_clone */
int meta_data_clone_merge(meta_data_t **dest, meta_data_t *orig) /* {{{ */
{
if (orig == NULL)
- return (0);
+ return 0;
if (*dest == NULL) {
*dest = meta_data_clone(orig);
- return (0);
+ return 0;
}
pthread_mutex_lock(&orig->lock);
}
pthread_mutex_unlock(&orig->lock);
- return (0);
+ return 0;
} /* }}} int meta_data_clone_merge */
void meta_data_destroy(meta_data_t *md) /* {{{ */
int meta_data_exists(meta_data_t *md, const char *key) /* {{{ */
{
if ((md == NULL) || (key == NULL))
- return (-EINVAL);
+ return -EINVAL;
pthread_mutex_lock(&md->lock);
for (meta_entry_t *e = md->head; e != NULL; e = e->next) {
if (strcasecmp(key, e->key) == 0) {
pthread_mutex_unlock(&md->lock);
- return (1);
+ return 1;
}
}
pthread_mutex_unlock(&md->lock);
- return (0);
+ return 0;
} /* }}} int meta_data_exists */
int meta_data_type(meta_data_t *md, const char *key) /* {{{ */
if (count == 0) {
pthread_mutex_unlock(&md->lock);
- return (count);
+ return count;
}
*toc = calloc(count, sizeof(**toc));
meta_entry_t *prev;
if ((md == NULL) || (key == NULL))
- return (-EINVAL);
+ return -EINVAL;
pthread_mutex_lock(&md->lock);
if (this == NULL) {
pthread_mutex_unlock(&md->lock);
- return (-ENOENT);
+ return -ENOENT;
}
if (prev == NULL)
this->next = NULL;
md_entry_free(this);
- return (0);
+ return 0;
} /* }}} int meta_data_delete */
/*
meta_entry_t *e;
if ((md == NULL) || (key == NULL) || (value == NULL))
- return (-EINVAL);
+ return -EINVAL;
e = md_entry_alloc(key);
if (e == NULL)
- return (-ENOMEM);
+ return -ENOMEM;
e->value.mv_string = md_strdup(value);
if (e->value.mv_string == NULL) {
ERROR("meta_data_add_string: md_strdup failed.");
md_entry_free(e);
- return (-ENOMEM);
+ return -ENOMEM;
}
e->type = MD_TYPE_STRING;
- return (md_entry_insert(md, e));
+ return md_entry_insert(md, e);
} /* }}} int meta_data_add_string */
int meta_data_add_signed_int(meta_data_t *md, /* {{{ */
meta_entry_t *e;
if ((md == NULL) || (key == NULL))
- return (-EINVAL);
+ return -EINVAL;
e = md_entry_alloc(key);
if (e == NULL)
- return (-ENOMEM);
+ return -ENOMEM;
e->value.mv_signed_int = value;
e->type = MD_TYPE_SIGNED_INT;
- return (md_entry_insert(md, e));
+ return md_entry_insert(md, e);
} /* }}} int meta_data_add_signed_int */
int meta_data_add_unsigned_int(meta_data_t *md, /* {{{ */
meta_entry_t *e;
if ((md == NULL) || (key == NULL))
- return (-EINVAL);
+ return -EINVAL;
e = md_entry_alloc(key);
if (e == NULL)
- return (-ENOMEM);
+ return -ENOMEM;
e->value.mv_unsigned_int = value;
e->type = MD_TYPE_UNSIGNED_INT;
- return (md_entry_insert(md, e));
+ return md_entry_insert(md, e);
} /* }}} int meta_data_add_unsigned_int */
int meta_data_add_double(meta_data_t *md, /* {{{ */
meta_entry_t *e;
if ((md == NULL) || (key == NULL))
- return (-EINVAL);
+ return -EINVAL;
e = md_entry_alloc(key);
if (e == NULL)
- return (-ENOMEM);
+ return -ENOMEM;
e->value.mv_double = value;
e->type = MD_TYPE_DOUBLE;
- return (md_entry_insert(md, e));
+ return md_entry_insert(md, e);
} /* }}} int meta_data_add_double */
int meta_data_add_boolean(meta_data_t *md, /* {{{ */
meta_entry_t *e;
if ((md == NULL) || (key == NULL))
- return (-EINVAL);
+ return -EINVAL;
e = md_entry_alloc(key);
if (e == NULL)
- return (-ENOMEM);
+ return -ENOMEM;
e->value.mv_boolean = value;
e->type = MD_TYPE_BOOLEAN;
- return (md_entry_insert(md, e));
+ return md_entry_insert(md, e);
} /* }}} int meta_data_add_boolean */
/*
char *temp;
if ((md == NULL) || (key == NULL) || (value == NULL))
- return (-EINVAL);
+ return -EINVAL;
pthread_mutex_lock(&md->lock);
e = md_entry_lookup(md, key);
if (e == NULL) {
pthread_mutex_unlock(&md->lock);
- return (-ENOENT);
+ return -ENOENT;
}
if (e->type != MD_TYPE_STRING) {
ERROR("meta_data_get_string: Type mismatch for key `%s'", e->key);
pthread_mutex_unlock(&md->lock);
- return (-ENOENT);
+ return -ENOENT;
}
temp = md_strdup(e->value.mv_string);
if (temp == NULL) {
pthread_mutex_unlock(&md->lock);
ERROR("meta_data_get_string: md_strdup failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
pthread_mutex_unlock(&md->lock);
*value = temp;
- return (0);
+ return 0;
} /* }}} int meta_data_get_string */
int meta_data_get_signed_int(meta_data_t *md, /* {{{ */
meta_entry_t *e;
if ((md == NULL) || (key == NULL) || (value == NULL))
- return (-EINVAL);
+ return -EINVAL;
pthread_mutex_lock(&md->lock);
e = md_entry_lookup(md, key);
if (e == NULL) {
pthread_mutex_unlock(&md->lock);
- return (-ENOENT);
+ return -ENOENT;
}
if (e->type != MD_TYPE_SIGNED_INT) {
ERROR("meta_data_get_signed_int: Type mismatch for key `%s'", e->key);
pthread_mutex_unlock(&md->lock);
- return (-ENOENT);
+ return -ENOENT;
}
*value = e->value.mv_signed_int;
pthread_mutex_unlock(&md->lock);
- return (0);
+ return 0;
} /* }}} int meta_data_get_signed_int */
int meta_data_get_unsigned_int(meta_data_t *md, /* {{{ */
meta_entry_t *e;
if ((md == NULL) || (key == NULL) || (value == NULL))
- return (-EINVAL);
+ return -EINVAL;
pthread_mutex_lock(&md->lock);
e = md_entry_lookup(md, key);
if (e == NULL) {
pthread_mutex_unlock(&md->lock);
- return (-ENOENT);
+ return -ENOENT;
}
if (e->type != MD_TYPE_UNSIGNED_INT) {
ERROR("meta_data_get_unsigned_int: Type mismatch for key `%s'", e->key);
pthread_mutex_unlock(&md->lock);
- return (-ENOENT);
+ return -ENOENT;
}
*value = e->value.mv_unsigned_int;
pthread_mutex_unlock(&md->lock);
- return (0);
+ return 0;
} /* }}} int meta_data_get_unsigned_int */
int meta_data_get_double(meta_data_t *md, /* {{{ */
meta_entry_t *e;
if ((md == NULL) || (key == NULL) || (value == NULL))
- return (-EINVAL);
+ return -EINVAL;
pthread_mutex_lock(&md->lock);
e = md_entry_lookup(md, key);
if (e == NULL) {
pthread_mutex_unlock(&md->lock);
- return (-ENOENT);
+ return -ENOENT;
}
if (e->type != MD_TYPE_DOUBLE) {
ERROR("meta_data_get_double: Type mismatch for key `%s'", e->key);
pthread_mutex_unlock(&md->lock);
- return (-ENOENT);
+ return -ENOENT;
}
*value = e->value.mv_double;
pthread_mutex_unlock(&md->lock);
- return (0);
+ return 0;
} /* }}} int meta_data_get_double */
int meta_data_get_boolean(meta_data_t *md, /* {{{ */
meta_entry_t *e;
if ((md == NULL) || (key == NULL) || (value == NULL))
- return (-EINVAL);
+ return -EINVAL;
pthread_mutex_lock(&md->lock);
e = md_entry_lookup(md, key);
if (e == NULL) {
pthread_mutex_unlock(&md->lock);
- return (-ENOENT);
+ return -ENOENT;
}
if (e->type != MD_TYPE_BOOLEAN) {
ERROR("meta_data_get_boolean: Type mismatch for key `%s'", e->key);
pthread_mutex_unlock(&md->lock);
- return (-ENOENT);
+ return -ENOENT;
}
*value = e->value.mv_boolean;
pthread_mutex_unlock(&md->lock);
- return (0);
+ return 0;
} /* }}} int meta_data_get_boolean */
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;
if ((md == NULL) || (key == NULL) || (value == NULL))
- return (-EINVAL);
+ return -EINVAL;
pthread_mutex_lock(&md->lock);
e = md_entry_lookup(md, key);
if (e == NULL) {
pthread_mutex_unlock(&md->lock);
- return (-ENOENT);
+ return -ENOENT;
}
type = e->type;
actual = e->value.mv_string;
break;
case MD_TYPE_SIGNED_INT:
- ssnprintf(buffer, sizeof(buffer), "%" PRIi64, e->value.mv_signed_int);
+ snprintf(buffer, sizeof(buffer), "%" PRIi64, e->value.mv_signed_int);
actual = buffer;
break;
case MD_TYPE_UNSIGNED_INT:
- ssnprintf(buffer, sizeof(buffer), "%" PRIu64, e->value.mv_unsigned_int);
+ snprintf(buffer, sizeof(buffer), "%" PRIu64, e->value.mv_unsigned_int);
actual = buffer;
break;
case MD_TYPE_DOUBLE:
- ssnprintf(buffer, sizeof(buffer), GAUGE_FORMAT, e->value.mv_double);
+ snprintf(buffer, sizeof(buffer), GAUGE_FORMAT, e->value.mv_double);
actual = buffer;
break;
case MD_TYPE_BOOLEAN:
default:
pthread_mutex_unlock(&md->lock);
ERROR("meta_data_as_string: unknown type %d for key `%s'", type, key);
- return (-ENOENT);
+ return -ENOENT;
}
pthread_mutex_unlock(&md->lock);
temp = md_strdup(actual);
if (temp == NULL) {
ERROR("meta_data_as_string: md_strdup failed for key `%s'.", key);
- return (-ENOMEM);
+ return -ENOMEM;
}
*value = temp;
- return (0);
+ return 0;
} /* }}} int meta_data_as_string */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
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 : */
END_TEST;
}
-
-/* vim: set sw=2 sts=2 et : */
#include <pthread_np.h> /* for pthread_set_name_np(3) */
#endif
-#include <ltdl.h>
+#include <dlfcn.h>
/*
* Private structures
static const char *plugin_get_dir(void) {
if (plugindir == NULL)
- return (PLUGINDIR);
+ return PLUGINDIR;
else
- return (plugindir);
+ return plugindir;
}
static int plugin_update_internal_statistics(void) { /* {{{ */
return 0;
} /* }}} int plugin_update_internal_statistics */
-static void destroy_callback(callback_func_t *cf) /* {{{ */
+static void free_userdata(user_data_t const *ud) /* {{{ */
{
- if (cf == NULL)
+ if (ud == NULL)
return;
- if ((cf->cf_udata.data != NULL) && (cf->cf_udata.free_func != NULL)) {
- cf->cf_udata.free_func(cf->cf_udata.data);
- cf->cf_udata.data = NULL;
- cf->cf_udata.free_func = NULL;
+ if ((ud->data != NULL) && (ud->free_func != NULL)) {
+ ud->free_func(ud->data);
}
+} /* }}} void free_userdata */
+
+static void destroy_callback(callback_func_t *cf) /* {{{ */
+{
+ if (cf == NULL)
+ return;
+ free_userdata(&cf->cf_udata);
sfree(cf);
} /* }}} void destroy_callback */
ERROR("plugin: register_callback: "
"llist_create failed.");
destroy_callback(cf);
- return (-1);
+ return -1;
}
}
if (key == NULL) {
ERROR("plugin: register_callback: strdup failed.");
destroy_callback(cf);
- return (-1);
+ return -1;
}
le = llist_search(*list, name);
"llentry_create failed.");
sfree(key);
destroy_callback(cf);
- return (-1);
+ return -1;
}
llist_append(*list, le);
sfree(key);
}
- return (0);
+ return 0;
} /* }}} int register_callback */
static void log_list_callbacks(llist_t **list, /* {{{ */
cf = calloc(1, sizeof(*cf));
if (cf == NULL) {
+ free_userdata(ud);
ERROR("plugin: create_register_callback: calloc failed.");
- return (-1);
+ return -1;
}
cf->cf_callback = callback;
cf->cf_ctx = plugin_get_ctx();
- return (register_callback(list, name, cf));
+ return register_callback(list, name, cf);
} /* }}} int create_register_callback */
static int plugin_unregister(llist_t *list, const char *name) /* {{{ */
llentry_t *e;
if (list == NULL)
- return (-1);
+ return -1;
e = llist_search(list, name);
if (e == NULL)
- return (-1);
+ return -1;
llist_remove(list, e);
llentry_destroy(e);
- return (0);
+ return 0;
} /* }}} int plugin_unregister */
/*
* 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. "
- "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());
+ snprintf(errbuf, sizeof(errbuf),
+ "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, dlerror());
ERROR("%s", errbuf);
/* Make sure this is printed to STDERR in any case, but also
if (list_log != NULL)
fprintf(stderr, "ERROR: %s\n", errbuf);
- return (1);
+ 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);
- return (-1);
+ dlerror());
+ dlclose(dlh);
+ return -1;
}
(*reg_handle)();
- return (0);
+ return 0;
}
static void *plugin_read_thread(void __attribute__((unused)) * args) {
} /* while (read_loop) */
pthread_exit(NULL);
- return ((void *)0);
+ return (void *)0;
} /* void *plugin_read_thread */
#ifdef PTHREAD_MAX_NAMELEN_NP
}
char name[THREAD_NAME_MAX];
- ssnprintf(name, sizeof(name), "reader#%zu", read_threads_num);
+ snprintf(name, sizeof(name), "reader#%zu", read_threads_num);
set_thread_name(read_threads[read_threads_num], name);
read_threads_num++;
value_list_t *vl;
if (vl_orig == NULL)
- return (NULL);
+ return NULL;
vl = malloc(sizeof(*vl));
if (vl == NULL)
- return (NULL);
+ return NULL;
memcpy(vl, vl_orig, sizeof(*vl));
if (vl->host[0] == 0)
vl->values = calloc(vl_orig->values_len, sizeof(*vl->values));
if (vl->values == NULL) {
plugin_value_list_free(vl);
- return (NULL);
+ return NULL;
}
memcpy(vl->values, vl_orig->values,
vl_orig->values_len * sizeof(*vl->values));
vl->meta = meta_data_clone(vl->meta);
if ((vl_orig->meta != NULL) && (vl->meta == NULL)) {
plugin_value_list_free(vl);
- return (NULL);
+ return NULL;
}
if (vl->time == 0)
}
}
- return (vl);
+ return vl;
} /* }}} value_list_t *plugin_value_list_clone */
static int plugin_write_enqueue(value_list_t const *vl) /* {{{ */
q = malloc(sizeof(*q));
if (q == NULL)
- return (ENOMEM);
+ return ENOMEM;
q->next = NULL;
q->vl = plugin_value_list_clone(vl);
if (q->vl == NULL) {
sfree(q);
- return (ENOMEM);
+ return ENOMEM;
}
/* Store context of caller (read plugin); otherwise, it would not be
pthread_cond_signal(&write_cond);
pthread_mutex_unlock(&write_lock);
- return (0);
+ return 0;
} /* }}} int plugin_write_enqueue */
static value_list_t *plugin_write_dequeue(void) /* {{{ */
if (write_queue_head == NULL) {
pthread_mutex_unlock(&write_lock);
- return (NULL);
+ return NULL;
}
q = write_queue_head;
vl = q->vl;
sfree(q);
- return (vl);
+ return vl;
} /* }}} value_list_t *plugin_write_dequeue */
static void *plugin_write_thread(void __attribute__((unused)) * args) /* {{{ */
}
pthread_exit(NULL);
- return ((void *)0);
+ return (void *)0;
} /* }}} void *plugin_write_thread */
static void start_write_threads(size_t num) /* {{{ */
}
char name[THREAD_NAME_MAX];
- ssnprintf(name, sizeof(name), "writer#%zu", write_threads_num);
+ snprintf(name, sizeof(name), "writer#%zu", write_threads_num);
set_thread_name(write_threads[write_threads_num], name);
write_threads_num++;
assert(plugins_loaded != NULL);
status = c_avl_get(plugins_loaded, name, /* ret_value = */ NULL);
- return (status == 0);
+ return status == 0;
}
static int plugin_mark_loaded(char const *name) {
name_copy = strdup(name);
if (name_copy == NULL)
- return (ENOMEM);
+ return ENOMEM;
status = c_avl_insert(plugins_loaded,
/* key = */ name_copy, /* value = */ NULL);
- return (status);
+ return status;
}
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] = "";
int status;
if (plugin_name == NULL)
- return (EINVAL);
+ return EINVAL;
/* Check if plugin is already loaded and don't do anything in this
* case. */
if (plugin_is_loaded(plugin_name))
- return (0);
+ return 0;
dir = plugin_get_dir();
ret = 1;
*/
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 */
- status = ssnprintf(typename, sizeof(typename), "%s.so", plugin_name);
+ status = snprintf(typename, sizeof(typename), "%s.so", plugin_name);
if ((status < 0) || ((size_t)status >= sizeof(typename))) {
WARNING("plugin_load: Filename too long: \"%s.so\"", plugin_name);
- return (-1);
+ return -1;
}
if ((dh = opendir(dir)) == NULL) {
char errbuf[1024];
ERROR("plugin_load: opendir (%s) failed: %s", dir,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
while ((de = readdir(dh)) != NULL) {
if (strcasecmp(de->d_name, typename))
continue;
- status = ssnprintf(filename, sizeof(filename), "%s/%s", dir, de->d_name);
+ status = snprintf(filename, sizeof(filename), "%s/%s", dir, de->d_name);
if ((status < 0) || ((size_t)status >= sizeof(filename))) {
WARNING("plugin_load: Filename too long: \"%s/%s\"", dir, de->d_name);
continue;
continue;
}
- status = plugin_load_file(filename, flags);
+ status = plugin_load_file(filename, global);
if (status == 0) {
/* success */
plugin_mark_loaded(plugin_name);
if (filename[0] == 0)
ERROR("plugin_load: Could not find plugin \"%s\" in %s", plugin_name, dir);
- return (ret);
+ return ret;
}
/*
int (*callback)(const char *key, const char *val),
const char **keys, int keys_num) {
cf_register(name, callback, keys, keys_num);
- return (0);
+ return 0;
} /* int plugin_register_config */
int plugin_register_complex_config(const char *type,
int (*callback)(oconfig_item_t *)) {
- return (cf_register_complex(type, callback));
+ return cf_register_complex(type, callback);
} /* int plugin_register_complex_config */
int plugin_register_init(const char *name, int (*callback)(void)) {
- return (create_register_callback(&list_init, name, (void *)callback,
- /* user_data = */ NULL));
+ return create_register_callback(&list_init, name, (void *)callback, NULL);
} /* plugin_register_init */
static int plugin_compare_read_func(const void *arg0, const void *arg1) {
rf1 = arg1;
if (rf0->rf_next_read < rf1->rf_next_read)
- return (-1);
+ return -1;
else if (rf0->rf_next_read > rf1->rf_next_read)
- return (1);
+ return 1;
else
- return (0);
+ return 0;
} /* int plugin_compare_read_func */
/* Add a read function to both, the heap and a linked list. The linked list if
if (read_list == NULL) {
pthread_mutex_unlock(&read_lock);
ERROR("plugin_insert_read: read_list failed.");
- return (-1);
+ return -1;
}
}
if (read_heap == NULL) {
pthread_mutex_unlock(&read_lock);
ERROR("plugin_insert_read: c_heap_create failed.");
- return (-1);
+ return -1;
}
}
if (le != NULL) {
pthread_mutex_unlock(&read_lock);
WARNING("The read function \"%s\" is already registered. "
- "Check for duplicate \"LoadPlugin\" lines "
- "in your configuration!",
+ "Check for duplicates in your configuration!",
rf->rf_name);
- return (EINVAL);
+ return EINVAL;
}
le = llentry_create(rf->rf_name, rf);
if (le == NULL) {
pthread_mutex_unlock(&read_lock);
ERROR("plugin_insert_read: llentry_create failed.");
- return (-1);
+ return -1;
}
status = c_heap_insert(read_heap, rf);
pthread_mutex_unlock(&read_lock);
ERROR("plugin_insert_read: c_heap_insert failed.");
llentry_destroy(le);
- return (-1);
+ return -1;
}
/* This does not fail. */
/* Wake up all the read threads. */
pthread_cond_broadcast(&read_cond);
pthread_mutex_unlock(&read_lock);
- return (0);
+ return 0;
} /* int plugin_insert_read */
int plugin_register_read(const char *name, int (*callback)(void)) {
rf = calloc(1, sizeof(*rf));
if (rf == NULL) {
ERROR("plugin_register_read: calloc failed.");
- return (ENOMEM);
+ return ENOMEM;
}
rf->rf_callback = (void *)callback;
sfree(rf);
}
- return (status);
+ return status;
} /* int plugin_register_read */
int plugin_register_complex_read(const char *group, const char *name,
rf = calloc(1, sizeof(*rf));
if (rf == NULL) {
+ free_userdata(user_data);
ERROR("plugin_register_complex_read: calloc failed.");
- return (ENOMEM);
+ return ENOMEM;
}
rf->rf_callback = (void *)callback;
status = plugin_insert_read(rf);
if (status != 0) {
+ free_userdata(&rf->rf_udata);
sfree(rf->rf_name);
sfree(rf);
}
- return (status);
+ return status;
} /* int plugin_register_complex_read */
int plugin_register_write(const char *name, plugin_write_cb callback,
user_data_t const *ud) {
- return (create_register_callback(&list_write, name, (void *)callback, ud));
+ return create_register_callback(&list_write, name, (void *)callback, ud);
} /* int plugin_register_write */
static int plugin_flush_timeout_callback(user_data_t *ud) {
flush_callback_t *cb = ud->data;
- return plugin_flush(cb->name, cb->timeout, /* identifier = */ NULL);
+ return plugin_flush(cb->name, cb->timeout, NULL);
} /* static int plugin_flush_callback */
static void plugin_flush_timeout_callback_free(void *data) {
flush_name = malloc(name_size + prefix_size + 1);
if (flush_name == NULL) {
ERROR("plugin_flush_callback_name: malloc failed.");
- return (NULL);
+ return NULL;
}
sstrncpy(flush_name, flush_prefix, prefix_size + 1);
flush_name = plugin_flush_callback_name(name);
if (flush_name == NULL)
- return (-1);
+ return -1;
cb = malloc(sizeof(*cb));
if (cb == NULL) {
ERROR("plugin_register_flush: malloc failed.");
sfree(flush_name);
- return (-1);
+ return -1;
}
cb->name = strdup(name);
ERROR("plugin_register_flush: strdup failed.");
sfree(cb);
sfree(flush_name);
- return (-1);
+ return -1;
}
cb->timeout = ctx.flush_timeout;
});
sfree(flush_name);
- if (status != 0) {
- sfree(cb->name);
- sfree(cb);
- return status;
- }
+ return status;
}
return 0;
int plugin_register_missing(const char *name, plugin_missing_cb callback,
user_data_t const *ud) {
- return (create_register_callback(&list_missing, name, (void *)callback, ud));
+ return create_register_callback(&list_missing, name, (void *)callback, ud);
} /* int plugin_register_missing */
int plugin_register_shutdown(const char *name, int (*callback)(void)) {
- return (create_register_callback(&list_shutdown, name, (void *)callback,
- /* user_data = */ NULL));
+ return create_register_callback(&list_shutdown, name, (void *)callback, NULL);
} /* int plugin_register_shutdown */
static void plugin_free_data_sets(void) {
} else if (data_sets == NULL) {
data_sets = c_avl_create((int (*)(const void *, const void *))strcmp);
if (data_sets == NULL)
- return (-1);
+ return -1;
}
ds_copy = malloc(sizeof(*ds_copy));
if (ds_copy == NULL)
- return (-1);
+ return -1;
memcpy(ds_copy, ds, sizeof(data_set_t));
ds_copy->ds = malloc(sizeof(*ds_copy->ds) * ds->ds_num);
if (ds_copy->ds == NULL) {
sfree(ds_copy);
- return (-1);
+ return -1;
}
for (size_t i = 0; i < ds->ds_num; i++)
memcpy(ds_copy->ds + i, ds->ds + i, sizeof(data_source_t));
- return (c_avl_insert(data_sets, (void *)ds_copy->type, (void *)ds_copy));
+ return c_avl_insert(data_sets, (void *)ds_copy->type, (void *)ds_copy);
} /* int plugin_register_data_set */
int plugin_register_log(const char *name, plugin_log_cb callback,
user_data_t const *ud) {
- return (create_register_callback(&list_log, name, (void *)callback, ud));
+ return create_register_callback(&list_log, name, (void *)callback, ud);
} /* int plugin_register_log */
int plugin_register_notification(const char *name,
plugin_notification_cb callback,
user_data_t const *ud) {
- return (
- create_register_callback(&list_notification, name, (void *)callback, ud));
+ return create_register_callback(&list_notification, name, (void *)callback,
+ ud);
} /* int plugin_register_log */
int plugin_unregister_config(const char *name) {
cf_unregister(name);
- return (0);
+ return 0;
} /* int plugin_unregister_config */
int plugin_unregister_complex_config(const char *name) {
cf_unregister_complex(name);
- return (0);
+ return 0;
} /* int plugin_unregister_complex_config */
int plugin_unregister_init(const char *name) {
- return (plugin_unregister(list_init, name));
+ return plugin_unregister(list_init, name);
}
int plugin_unregister_read(const char *name) /* {{{ */
read_func_t *rf;
if (name == NULL)
- return (-ENOENT);
+ return -ENOENT;
pthread_mutex_lock(&read_lock);
if (read_list == NULL) {
pthread_mutex_unlock(&read_lock);
- return (-ENOENT);
+ return -ENOENT;
}
le = llist_search(read_list, name);
if (le == NULL) {
pthread_mutex_unlock(&read_lock);
WARNING("plugin_unregister_read: No such read function: %s", name);
- return (-ENOENT);
+ return -ENOENT;
}
llist_remove(read_list, le);
DEBUG("plugin_unregister_read: Marked `%s' for removal.", name);
- return (0);
+ return 0;
} /* }}} int plugin_unregister_read */
void plugin_log_available_writers(void) {
int found = 0;
if (group == NULL)
- return (-ENOENT);
+ return -ENOENT;
pthread_mutex_lock(&read_lock);
if (read_list == NULL) {
pthread_mutex_unlock(&read_lock);
- return (-ENOENT);
+ return -ENOENT;
}
while (42) {
WARNING("plugin_unregister_read_group: No such "
"group of read function: %s",
group);
- return (-ENOENT);
+ return -ENOENT;
}
- return (0);
+ return 0;
} /* }}} int plugin_unregister_read_group */
int plugin_unregister_write(const char *name) {
- return (plugin_unregister(list_write, name));
+ return plugin_unregister(list_write, name);
}
int plugin_unregister_flush(const char *name) {
}
int plugin_unregister_missing(const char *name) {
- return (plugin_unregister(list_missing, name));
+ return plugin_unregister(list_missing, name);
}
int plugin_unregister_shutdown(const char *name) {
- return (plugin_unregister(list_shutdown, name));
+ return plugin_unregister(list_shutdown, name);
}
int plugin_unregister_data_set(const char *name) {
data_set_t *ds;
if (data_sets == NULL)
- return (-1);
+ return -1;
if (c_avl_remove(data_sets, name, NULL, (void *)&ds) != 0)
- return (-1);
+ return -1;
sfree(ds->ds);
sfree(ds);
- return (0);
+ return 0;
} /* int plugin_unregister_data_set */
int plugin_unregister_log(const char *name) {
- return (plugin_unregister(list_log, name));
+ return plugin_unregister(list_log, name);
}
int plugin_unregister_notification(const char *name) {
- return (plugin_unregister(list_notification, name));
+ return plugin_unregister(list_notification, name);
}
int plugin_init_all(void) {
if (read_heap == NULL) {
NOTICE("No read-functions are registered.");
- return (0);
+ return 0;
}
while (42) {
destroy_callback((void *)rf);
}
- return (return_status);
+ return return_status;
} /* int plugin_read_all_once */
int plugin_write(const char *plugin, /* {{{ */
int status;
if (vl == NULL)
- return (EINVAL);
+ return EINVAL;
if (list_write == NULL)
- return (ENOENT);
+ return ENOENT;
if (ds == NULL) {
ds = plugin_get_ds(vl->type);
if (ds == NULL) {
ERROR("plugin_write: Unable to lookup type `%s'.", vl->type);
- return (ENOENT);
+ return ENOENT;
}
}
}
if (le == NULL)
- return (ENOENT);
+ return ENOENT;
cf = le->value;
status = (*callback)(ds, vl, &cf->cf_udata);
}
- return (status);
+ return status;
} /* }}} int plugin_write */
int plugin_flush(const char *plugin, cdtime_t timeout, const char *identifier) {
llentry_t *le;
if (list_flush == NULL)
- return (0);
+ return 0;
le = llist_head(list_flush);
while (le != NULL) {
le = le->next;
}
- return (0);
+ return 0;
} /* int plugin_flush */
int plugin_shutdown_all(void) {
plugin_free_loaded();
plugin_free_data_sets();
- return (ret);
+ return ret;
} /* void plugin_shutdown_all */
int plugin_dispatch_missing(const value_list_t *vl) /* {{{ */
{
- llentry_t *le;
-
if (list_missing == NULL)
- return (0);
+ return 0;
- le = llist_head(list_missing);
+ llentry_t *le = llist_head(list_missing);
while (le != NULL) {
- callback_func_t *cf;
- plugin_missing_cb callback;
- plugin_ctx_t old_ctx;
- int status;
+ callback_func_t *cf = le->value;
+ plugin_ctx_t old_ctx = plugin_set_ctx(cf->cf_ctx);
+ plugin_missing_cb callback = cf->cf_callback;
- cf = le->value;
- old_ctx = plugin_set_ctx(cf->cf_ctx);
- callback = cf->cf_callback;
-
- status = (*callback)(vl, &cf->cf_udata);
+ int status = (*callback)(vl, &cf->cf_udata);
plugin_set_ctx(old_ctx);
if (status != 0) {
if (status < 0) {
ERROR("plugin_dispatch_missing: Callback function \"%s\" "
"failed with status %i.",
le->key, status);
- return (status);
+ return status;
} else {
- return (0);
+ return 0;
}
}
le = le->next;
}
- return (0);
+ return 0;
} /* int }}} plugin_dispatch_missing */
static int plugin_dispatch_values_internal(value_list_t *vl) {
int status;
static c_complain_t no_write_complaint = C_COMPLAIN_INIT_STATIC;
- data_set_t *ds;
-
_Bool free_meta_data = 0;
assert(vl != NULL);
ERROR("plugin_dispatch_values: Invalid value list "
"from plugin %s.",
vl->plugin);
- return (-1);
+ return -1;
}
/* Free meta data only if the calling function didn't specify any. In
ERROR("plugin_dispatch_values: No data sets registered. "
"Could the types database be read? Check "
"your `TypesDB' setting!");
- return (-1);
+ return -1;
}
+ data_set_t *ds = NULL;
if (c_avl_get(data_sets, vl->type, (void *)&ds) != 0) {
char ident[6 * DATA_MAX_NAME_LEN];
INFO("plugin_dispatch_values: Dataset not found: %s "
"(from \"%s\"), check your types.db!",
vl->type, ident);
- return (-1);
+ return -1;
}
DEBUG("plugin_dispatch_values: time = %.3f; interval = %.3f; "
"(ds->ds_num = %zu) != "
"(vl->values_len = %zu)",
ds->type, ds->ds_num, vl->values_len);
- return (-1);
+ return -1;
}
#endif
"status %i (%#x).",
status, status);
} else if (status == FC_TARGET_STOP)
- return (0);
+ return 0;
}
/* Update the value cache */
vl->meta = NULL;
}
- return (0);
+ return 0;
} /* int plugin_dispatch_values_internal */
static double get_drop_probability(void) /* {{{ */
pthread_mutex_unlock(&write_lock);
if (wql < write_limit_low)
- return (0.0);
+ return 0.0;
if (wql >= write_limit_high)
- return (1.0);
+ return 1.0;
pos = 1 + wql - write_limit_low;
size = 1 + write_limit_high - write_limit_low;
- return (((double)pos) / ((double)size));
+ return (double)pos / (double)size;
} /* }}} double get_drop_probability */
static _Bool check_drop_value(void) /* {{{ */
int status;
if (write_limit_high == 0)
- return (0);
+ return 0;
p = get_drop_probability();
if (p == 0.0)
- return (0);
+ return 0;
status = pthread_mutex_trylock(&last_message_lock);
if (status == 0) {
}
if (p == 1.0)
- return (1);
+ return 1;
q = cdrand_d();
if (q > p)
- return (1);
+ return 1;
else
- return (0);
+ return 0;
} /* }}} _Bool check_drop_value */
int plugin_dispatch_values(value_list_t const *vl) {
stats_values_dropped++;
pthread_mutex_unlock(&statistics_lock);
}
- return (0);
+ return 0;
}
status = plugin_write_enqueue(vl);
ERROR("plugin_dispatch_values: plugin_write_enqueue failed "
"with status %i (%s).",
status, sstrerror(status, errbuf, sizeof(errbuf)));
- return (status);
+ return status;
}
- return (0);
+ return 0;
}
__attribute__((sentinel)) int
va_end(ap);
plugin_value_list_free(vl);
- return (failed);
+ return failed;
} /* }}} int plugin_dispatch_multivalue */
int plugin_dispatch_notification(const notification_t *notif) {
/* Nobody cares for notifications */
if (list_notification == NULL)
- return (-1);
+ return -1;
le = llist_head(list_notification);
while (le != NULL) {
le = le->next;
}
- return (0);
+ return 0;
} /* int plugin_dispatch_notification */
void plugin_log(int level, const char *format, ...) {
log_level = LOG_DEBUG;
#endif /* COLLECT_DEBUG */
- return (log_level);
+ return log_level;
} /* int parse_log_severity */
int parse_notif_severity(const char *severity) {
(strcmp(severity, "WARN") == 0))
notif_severity = NOTIF_WARNING;
- return (notif_severity);
+ return notif_severity;
} /* int parse_notif_severity */
const data_set_t *plugin_get_ds(const char *name) {
if (data_sets == NULL) {
ERROR("plugin_get_ds: No data sets are defined yet.");
- return (NULL);
+ return NULL;
}
if (c_avl_get(data_sets, name, (void *)&ds) != 0) {
DEBUG("No such dataset registered: %s", name);
- return (NULL);
+ return NULL;
}
- return (ds);
+ return ds;
} /* data_set_t *plugin_get_ds */
static int plugin_notification_meta_add(notification_t *n, const char *name,
if ((n == NULL) || (name == NULL) || (value == NULL)) {
ERROR("plugin_notification_meta_add: A pointer is NULL!");
- return (-1);
+ return -1;
}
meta = calloc(1, sizeof(*meta));
if (meta == NULL) {
ERROR("plugin_notification_meta_add: calloc failed.");
- return (-1);
+ return -1;
}
sstrncpy(meta->name, name, sizeof(meta->name));
if (meta->nm_value.nm_string == NULL) {
ERROR("plugin_notification_meta_add: strdup failed.");
sfree(meta);
- return (-1);
+ return -1;
}
break;
}
default: {
ERROR("plugin_notification_meta_add: Unknown type: %i", type);
sfree(meta);
- return (-1);
+ return -1;
}
} /* switch (type) */
else
tail->next = meta;
- return (0);
+ return 0;
} /* int plugin_notification_meta_add */
int plugin_notification_meta_add_string(notification_t *n, const char *name,
const char *value) {
- return (plugin_notification_meta_add(n, name, NM_TYPE_STRING, value));
+ return plugin_notification_meta_add(n, name, NM_TYPE_STRING, value);
}
int plugin_notification_meta_add_signed_int(notification_t *n, const char *name,
int64_t value) {
- return (plugin_notification_meta_add(n, name, NM_TYPE_SIGNED_INT, &value));
+ return plugin_notification_meta_add(n, name, NM_TYPE_SIGNED_INT, &value);
}
int plugin_notification_meta_add_unsigned_int(notification_t *n,
const char *name,
uint64_t value) {
- return (plugin_notification_meta_add(n, name, NM_TYPE_UNSIGNED_INT, &value));
+ return plugin_notification_meta_add(n, name, NM_TYPE_UNSIGNED_INT, &value);
}
int plugin_notification_meta_add_double(notification_t *n, const char *name,
double value) {
- return (plugin_notification_meta_add(n, name, NM_TYPE_DOUBLE, &value));
+ return plugin_notification_meta_add(n, name, NM_TYPE_DOUBLE, &value);
}
int plugin_notification_meta_add_boolean(notification_t *n, const char *name,
_Bool value) {
- return (plugin_notification_meta_add(n, name, NM_TYPE_BOOLEAN, &value));
+ return plugin_notification_meta_add(n, name, NM_TYPE_BOOLEAN, &value);
}
int plugin_notification_meta_copy(notification_t *dst,
meta->nm_value.nm_boolean);
}
- return (0);
+ return 0;
} /* int plugin_notification_meta_copy */
int plugin_notification_meta_free(notification_meta_t *n) {
if (n == NULL) {
ERROR("plugin_notification_meta_free: n == NULL!");
- return (-1);
+ return -1;
}
this = n;
this = next;
}
- return (0);
+ return 0;
} /* int plugin_notification_meta_free */
static void plugin_ctx_destructor(void *ctx) {
assert(plugin_ctx_key_initialized);
pthread_setspecific(plugin_ctx_key, ctx);
DEBUG("Created new plugin context.");
- return (ctx);
+ return ctx;
} /* int plugin_ctx_create */
void plugin_init_ctx(void) {
return ctx_init;
}
- return (*ctx);
+ return *ctx;
} /* plugin_ctx_t plugin_get_ctx */
plugin_ctx_t plugin_set_ctx(plugin_ctx_t ctx) {
old = *c;
*c = ctx;
- return (old);
+ return old;
} /* void plugin_set_ctx */
cdtime_t plugin_get_interval(void) {
return 0;
} /* int plugin_thread_create */
-
-/* vim: set sw=8 ts=8 noet fdm=marker : */
#include <pthread.h>
-#define PLUGIN_FLAGS_GLOBAL 0x0001
-
-#ifndef DATA_MAX_NAME_LEN
-#define DATA_MAX_NAME_LEN 128
-#endif
-
#define DS_TYPE_COUNTER 0
#define DS_TYPE_GAUGE 1
#define DS_TYPE_DERIVE 2
#define DS_TYPE_ABSOLUTE 3
#define DS_TYPE_TO_STRING(t) \
- (t == DS_TYPE_COUNTER) ? "counter" : (t == DS_TYPE_GAUGE) \
- ? "gauge" \
- : (t == DS_TYPE_DERIVE) \
- ? "derive" \
- : (t == DS_TYPE_ABSOLUTE) \
- ? "absolute" \
- : "unknown"
+ (t == DS_TYPE_COUNTER) \
+ ? "counter" \
+ : (t == DS_TYPE_GAUGE) \
+ ? "gauge" \
+ : (t == DS_TYPE_DERIVE) \
+ ? "derive" \
+ : (t == DS_TYPE_ABSOLUTE) ? "absolute" : "unknown"
#ifndef LOG_ERR
#define LOG_ERR 3
*
* 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
* 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);
kstat_ctl_t *kc = NULL;
#endif /* HAVE_LIBKSTAT */
-char hostname_g[] = "example.com";
+char *hostname_g = "example.com";
+
+void plugin_set_dir(const char *dir) { /* nop */
+}
+
+int plugin_load(const char *name, _Bool global) { return ENOTSUP; }
+
+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;
}
+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;
}
+int plugin_register_data_set(const data_set_t *ds) { return ENOTSUP; }
+
int plugin_dispatch_values(value_list_t const *vl) { return ENOTSUP; }
int plugin_flush(const char *plugin, cdtime_t timeout, const char *identifier) {
printf("plugin_log (%i, \"%s\");\n", level, buffer);
}
-cdtime_t plugin_get_interval(void) { return TIME_T_TO_CDTIME_T(10); }
+void plugin_init_ctx(void) { /* nop */
+}
+
+plugin_ctx_t mock_context = {
+ .interval = TIME_T_TO_CDTIME_T_STATIC(10),
+};
+
+plugin_ctx_t plugin_get_ctx(void) { return mock_context; }
+
+plugin_ctx_t plugin_set_ctx(plugin_ctx_t ctx) {
+ plugin_ctx_t prev = mock_context;
+ mock_context = ctx;
+ return prev;
+}
+
+cdtime_t plugin_get_interval(void) { return mock_context.interval; }
-/* vim: set sw=2 sts=2 et : */
+/* TODO(octo): this function is actually from filter_chain.h, but in order not
+ * to tumble down that rabbit hole, we're declaring it here. A better solution
+ * would be to hard-code the top-level config keys in daemon/collectd.c to avoid
+ * having these references in daemon/configfile.c. */
+int fc_configure(const oconfig_item_t *ci) { return ENOTSUP; }
if (buf_len < 11) {
ERROR("parse_ds: (buf_len = %zu) < 11", buf_len);
- return (-1);
+ return -1;
}
if (buf[buf_len - 1] == ',') {
if (fields_num != 4) {
ERROR("parse_ds: (fields_num = %i) != 4", fields_num);
- return (-1);
+ return -1;
}
sstrncpy(dsrc->name, fields[0], sizeof(dsrc->name));
else {
ERROR("(fields[1] = %s) != (GAUGE || COUNTER || DERIVE || ABSOLUTE)",
fields[1]);
- return (-1);
+ return -1;
}
if (strcasecmp(fields[2], "U") == 0)
else
dsrc->max = atof(fields[3]);
- return (0);
+ return 0;
} /* int parse_ds */
static void parse_line(char *buf) {
FILE *fh;
if (file == NULL)
- return (-1);
+ return -1;
fh = fopen(file, "r");
if (fh == NULL) {
sstrerror(errno, errbuf, sizeof(errbuf)));
ERROR("Failed to open types database `%s': %s", file,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
parse_file(fh);
DEBUG("Done parsing `%s'", file);
- return (0);
+ return 0;
} /* int read_types_list */
-
-/*
- * vim: shiftwidth=2:softtabstop=2:tabstop=8
- */
int height_right;
if (n == NULL)
- return (0);
+ return 0;
height_left = (n->left == NULL) ? 0 : n->left->height;
height_right = (n->right == NULL) ? 0 : n->right->height;
- return (((height_left > height_right) ? height_left : height_right) + 1);
+ return ((height_left > height_right) ? height_left : height_right) + 1;
} /* int calc_height */
static c_avl_node_t *search(c_avl_tree_t *t, const void *key) {
while (n != NULL) {
cmp = t->compare(key, n->key);
if (cmp == 0)
- return (n);
+ return n;
else if (cmp < 0)
n = n->left;
else
n = n->right;
}
- return (NULL);
+ return NULL;
}
/* (x) (y)
x->height = calc_height(x);
y->height = calc_height(y);
- return (y);
+ return y;
} /* void rotate_right */
/*
x->height = calc_height(x);
y->height = calc_height(y);
- return (y);
+ return y;
} /* void rotate_left */
static c_avl_node_t *rotate_left_right(c_avl_tree_t *t, c_avl_node_t *x) {
rotate_left(t, x->left);
- return (rotate_right(t, x));
+ return rotate_right(t, x);
} /* void rotate_left_right */
static c_avl_node_t *rotate_right_left(c_avl_tree_t *t, c_avl_node_t *x) {
rotate_right(t, x->right);
- return (rotate_left(t, x));
+ return rotate_left(t, x);
} /* void rotate_right_left */
static void rebalance(c_avl_tree_t *t, c_avl_node_t *n) {
c_avl_node_t *r; /* return node */
if (n == NULL) {
- return (NULL);
+ return NULL;
}
/* If we can't descent any further, we have to backtrack to the first
* r->left != n => r->right = n => r->parent == NULL */
if ((r == NULL) || (r->left != n)) {
assert((r == NULL) || (r->parent == NULL));
- return (NULL);
+ return NULL;
} else {
assert(r->left == n);
- return (r);
+ return r;
}
} else {
r = n->right;
r = r->left;
}
- return (r);
+ return r;
} /* c_avl_node_t *c_avl_node_next */
static c_avl_node_t *c_avl_node_prev(c_avl_node_t *n) {
c_avl_node_t *r; /* return node */
if (n == NULL) {
- return (NULL);
+ return NULL;
}
/* If we can't descent any further, we have to backtrack to the first
* r->right != n => r->left = n => r->parent == NULL */
if ((r == NULL) || (r->right != n)) {
assert((r == NULL) || (r->parent == NULL));
- return (NULL);
+ return NULL;
} else {
assert(r->right == n);
- return (r);
+ return r;
}
} else {
r = n->left;
r = r->right;
}
- return (r);
+ return r;
} /* c_avl_node_t *c_avl_node_prev */
static int _remove(c_avl_tree_t *t, c_avl_node_t *n) {
assert(0);
}
- return (0);
+ return 0;
} /* void *_remove */
/*
c_avl_tree_t *t;
if (compare == NULL)
- return (NULL);
+ return NULL;
if ((t = malloc(sizeof(*t))) == NULL)
- return (NULL);
+ return NULL;
t->root = NULL;
t->compare = compare;
t->size = 0;
- return (t);
+ return t;
}
void c_avl_destroy(c_avl_tree_t *t) {
int cmp;
if ((new = malloc(sizeof(*new))) == NULL)
- return (-1);
+ return -1;
new->key = key;
new->value = value;
new->parent = NULL;
t->root = new;
t->size = 1;
- return (0);
+ return 0;
}
nptr = t->root;
cmp = t->compare(nptr->key, new->key);
if (cmp == 0) {
free_node(new);
- return (1);
+ return 1;
} else if (cmp < 0) {
/* nptr < new */
if (nptr->right == NULL) {
verify_tree(t->root);
++t->size;
- return (0);
+ return 0;
} /* int c_avl_insert */
int c_avl_remove(c_avl_tree_t *t, const void *key, void **rkey, void **rvalue) {
n = search(t, key);
if (n == NULL)
- return (-1);
+ return -1;
if (rkey != NULL)
*rkey = n->key;
status = _remove(t, n);
verify_tree(t->root);
--t->size;
- return (status);
+ return status;
} /* void *c_avl_remove */
int c_avl_get(c_avl_tree_t *t, const void *key, void **value) {
n = search(t, key);
if (n == NULL)
- return (-1);
+ return -1;
if (value != NULL)
*value = n->value;
- return (0);
+ return 0;
}
int c_avl_pick(c_avl_tree_t *t, void **key, void **value) {
c_avl_node_t *n;
c_avl_node_t *p;
+ assert(t != NULL);
+
if ((key == NULL) || (value == NULL))
- return (-1);
+ return -1;
if (t->root == NULL)
- return (-1);
+ return -1;
n = t->root;
while ((n->left != NULL) || (n->right != NULL)) {
--t->size;
rebalance(t, p);
- return (0);
+ return 0;
} /* int c_avl_pick */
c_avl_iterator_t *c_avl_get_iterator(c_avl_tree_t *t) {
c_avl_iterator_t *iter;
if (t == NULL)
- return (NULL);
+ return NULL;
iter = calloc(1, sizeof(*iter));
if (iter == NULL)
- return (NULL);
+ return NULL;
iter->tree = t;
- return (iter);
+ return iter;
} /* c_avl_iterator_t *c_avl_get_iterator */
int c_avl_iterator_next(c_avl_iterator_t *iter, void **key, void **value) {
c_avl_node_t *n;
if ((iter == NULL) || (key == NULL) || (value == NULL))
- return (-1);
+ return -1;
if (iter->node == NULL) {
for (n = iter->tree->root; n != NULL; n = n->left)
}
if (n == NULL)
- return (-1);
+ return -1;
iter->node = n;
*key = n->key;
*value = n->value;
- return (0);
+ return 0;
} /* int c_avl_iterator_next */
int c_avl_iterator_prev(c_avl_iterator_t *iter, void **key, void **value) {
c_avl_node_t *n;
if ((iter == NULL) || (key == NULL) || (value == NULL))
- return (-1);
+ return -1;
if (iter->node == NULL) {
for (n = iter->tree->root; n != NULL; n = n->left)
}
if (n == NULL)
- return (-1);
+ return -1;
iter->node = n;
*key = n->key;
*value = n->value;
- return (0);
+ return 0;
} /* int c_avl_iterator_prev */
void c_avl_iterator_destroy(c_avl_iterator_t *iter) { free(iter); }
int c_avl_size(c_avl_tree_t *t) {
if (t == NULL)
- return (0);
- return (t->size);
+ return 0;
+ return t->size;
}
assert(v1 != NULL);
compare_total_count++;
- return (strcmp(v0, v1));
+ return strcmp(v0, v1);
}
DEF_TEST(success) {
c_avl_destroy(t);
- return (0);
+ return 0;
}
int main(void) {
END_TEST;
}
-
-/* vim: set sw=2 sts=2 et : */
#if COLLECT_DEBUG
assert((a != NULL) && (b != NULL));
#endif
- return (strcmp(a->name, b->name));
+ return strcmp(a->name, b->name);
} /* int cache_compare */
static cache_entry_t *cache_alloc(size_t values_num) {
ce = calloc(1, sizeof(*ce));
if (ce == NULL) {
ERROR("utils_cache: cache_alloc: calloc failed.");
- return (NULL);
+ return NULL;
}
ce->values_num = values_num;
sfree(ce->values_raw);
sfree(ce);
ERROR("utils_cache: cache_alloc: calloc failed.");
- return (NULL);
+ return NULL;
}
ce->history = NULL;
ce->history_length = 0;
ce->meta = NULL;
- return (ce);
+ return ce;
} /* cache_entry_t *cache_alloc */
static void cache_free(cache_entry_t *ce) {
key_copy = strdup(key);
if (key_copy == NULL) {
ERROR("uc_insert: strdup failed.");
- return (-1);
+ return -1;
}
ce = cache_alloc(ds->ds_num);
if (ce == NULL) {
sfree(key_copy);
ERROR("uc_insert: cache_alloc (%zu) failed.", ds->ds_num);
- return (-1);
+ return -1;
}
sstrncpy(ce->name, key, sizeof(ce->name));
ds->ds[i].type);
sfree(key_copy);
cache_free(ce);
- return (-1);
+ return -1;
} /* switch (ds->ds[i].type) */
} /* for (i) */
if (c_avl_insert(cache_tree, key_copy, ce) != 0) {
sfree(key_copy);
ERROR("uc_insert: c_avl_insert failed.");
- return (-1);
+ return -1;
}
DEBUG("uc_insert: Added %s to the cache.", key);
- return (0);
+ return 0;
} /* int uc_insert */
int uc_init(void) {
cache_tree =
c_avl_create((int (*)(const void *, const void *))cache_compare);
- return (0);
+ return 0;
} /* int uc_init */
int uc_check_timeout(void) {
if (expired_num == 0) {
sfree(expired);
- return (0);
+ return 0;
}
/* Call the "missing" callback for each value. Do this before removing the
pthread_mutex_unlock(&cache_lock);
sfree(expired);
- return (0);
+ return 0;
} /* int uc_check_timeout */
int uc_update(const data_set_t *ds, const value_list_t *vl) {
if (FORMAT_VL(name, sizeof(name), vl) != 0) {
ERROR("uc_update: FORMAT_VL failed.");
- return (-1);
+ return -1;
}
pthread_mutex_lock(&cache_lock);
{
status = uc_insert(ds, vl, name);
pthread_mutex_unlock(&cache_lock);
- return (status);
+ return status;
}
assert(ce != NULL);
"last cache update = %.3f;",
name, CDTIME_T_TO_DOUBLE(vl->time),
CDTIME_T_TO_DOUBLE(ce->last_time));
- return (-1);
+ return -1;
}
for (size_t i = 0; i < ds->ds_num; i++) {
pthread_mutex_unlock(&cache_lock);
ERROR("uc_update: Don't know how to handle data source type %i.",
ds->ds[i].type);
- return (-1);
+ return -1;
} /* switch (ds->ds[i].type) */
DEBUG("uc_update: %s: ds[%zu] = %lf", name, i, ce->values_gauge[i]);
pthread_mutex_unlock(&cache_lock);
- return (0);
+ return 0;
} /* int uc_update */
int uc_get_rate_by_name(const char *name, gauge_t **ret_values,
*ret_values_num = ret_num;
}
- return (status);
+ return status;
} /* gauge_t *uc_get_rate_by_name */
gauge_t *uc_get_rate(const data_set_t *ds, const value_list_t *vl) {
if (FORMAT_VL(name, sizeof(name), vl) != 0) {
ERROR("utils_cache: uc_get_rate: FORMAT_VL failed.");
- return (NULL);
+ return NULL;
}
status = uc_get_rate_by_name(name, &ret, &ret_num);
if (status != 0)
- return (NULL);
+ return NULL;
/* This is important - the caller has no other way of knowing how many
* values are returned. */
"but uc_get_rate_by_name returned %zu.",
ds->type, ds->ds_num, ret_num);
sfree(ret);
+ return NULL;
+ }
+
+ return ret;
+} /* gauge_t *uc_get_rate */
+
+int uc_get_value_by_name(const char *name, value_t **ret_values,
+ size_t *ret_values_num) {
+ value_t *ret = NULL;
+ size_t ret_num = 0;
+ cache_entry_t *ce = NULL;
+ int status = 0;
+
+ pthread_mutex_lock(&cache_lock);
+
+ if (c_avl_get(cache_tree, name, (void *) &ce) == 0) {
+ assert(ce != NULL);
+
+ /* remove missing values from getval */
+ if (ce->state == STATE_MISSING) {
+ status = -1;
+ } else {
+ ret_num = ce->values_num;
+ ret = malloc(ret_num * sizeof(*ret));
+ if (ret == NULL) {
+ ERROR("utils_cache: uc_get_value_by_name: malloc failed.");
+ status = -1;
+ } else {
+ memcpy(ret, ce->values_raw, ret_num * sizeof(value_t));
+ }
+ }
+ }
+ else {
+ DEBUG("utils_cache: uc_get_value_by_name: No such value: %s", name);
+ status = -1;
+ }
+
+ pthread_mutex_unlock(&cache_lock);
+
+ if (status == 0) {
+ *ret_values = ret;
+ *ret_values_num = ret_num;
+ }
+
+ return (status);
+} /* int uc_get_value_by_name */
+
+value_t *uc_get_value(const data_set_t *ds, const value_list_t *vl) {
+ char name[6 * DATA_MAX_NAME_LEN];
+ value_t *ret = NULL;
+ size_t ret_num = 0;
+ int status;
+
+ if (FORMAT_VL(name, sizeof(name), vl) != 0) {
+ ERROR("utils_cache: uc_get_value: FORMAT_VL failed.");
+ return (NULL);
+ }
+
+ status = uc_get_value_by_name(name, &ret, &ret_num);
+ if (status != 0)
+ return (NULL);
+
+ /* This is important - the caller has no other way of knowing how many
+ * values are returned. */
+ if (ret_num != (size_t) ds->ds_num) {
+ ERROR("utils_cache: uc_get_value: ds[%s] has %zu values, "
+ "but uc_get_value_by_name returned %zu.", ds->type, ds->ds_num,
+ ret_num);
+ sfree(ret);
return (NULL);
}
return (ret);
-} /* gauge_t *uc_get_rate */
+} /* value_t *uc_get_value */
size_t uc_get_size(void) {
size_t size_arrays = 0;
size_arrays = (size_t)c_avl_size(cache_tree);
pthread_mutex_unlock(&cache_lock);
- return (size_arrays);
+ return size_arrays;
}
int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number) {
int status = 0;
if ((ret_names == NULL) || (ret_number == NULL))
- return (-1);
+ return -1;
pthread_mutex_lock(&cache_lock);
/* Handle the "no values" case here, to avoid the error message when
* calloc() returns NULL. */
pthread_mutex_unlock(&cache_lock);
- return (0);
+ return 0;
}
names = calloc(size_arrays, sizeof(*names));
sfree(names);
sfree(times);
pthread_mutex_unlock(&cache_lock);
- return (ENOMEM);
+ return ENOMEM;
}
iter = c_avl_get_iterator(cache_tree);
sfree(names);
sfree(times);
- return (-1);
+ return -1;
}
*ret_names = names;
sfree(times);
*ret_number = number;
- return (0);
+ return 0;
} /* int uc_get_names */
int uc_get_state(const data_set_t *ds, const value_list_t *vl) {
if (FORMAT_VL(name, sizeof(name), vl) != 0) {
ERROR("uc_get_state: FORMAT_VL failed.");
- return (STATE_ERROR);
+ return STATE_ERROR;
}
pthread_mutex_lock(&cache_lock);
pthread_mutex_unlock(&cache_lock);
- return (ret);
+ return ret;
} /* int uc_get_state */
int uc_set_state(const data_set_t *ds, const value_list_t *vl, int state) {
if (FORMAT_VL(name, sizeof(name), vl) != 0) {
ERROR("uc_set_state: FORMAT_VL failed.");
- return (STATE_ERROR);
+ return STATE_ERROR;
}
pthread_mutex_lock(&cache_lock);
pthread_mutex_unlock(&cache_lock);
- return (ret);
+ return ret;
} /* int uc_set_state */
int uc_get_history_by_name(const char *name, gauge_t *ret_history,
status = c_avl_get(cache_tree, name, (void *)&ce);
if (status != 0) {
pthread_mutex_unlock(&cache_lock);
- return (-ENOENT);
+ return -ENOENT;
}
if (((size_t)ce->values_num) != num_ds) {
pthread_mutex_unlock(&cache_lock);
- return (-EINVAL);
+ return -EINVAL;
}
/* Check if there are enough values available. If not, increase the buffer
realloc(ce->history, sizeof(*ce->history) * num_steps * ce->values_num);
if (tmp == NULL) {
pthread_mutex_unlock(&cache_lock);
- return (-ENOMEM);
+ return -ENOMEM;
}
for (size_t i = ce->history_length * ce->values_num;
pthread_mutex_unlock(&cache_lock);
- return (0);
+ return 0;
} /* int uc_get_history_by_name */
int uc_get_history(const data_set_t *ds, const value_list_t *vl,
if (FORMAT_VL(name, sizeof(name), vl) != 0) {
ERROR("utils_cache: uc_get_history: FORMAT_VL failed.");
- return (-1);
+ return -1;
}
- return (uc_get_history_by_name(name, ret_history, num_steps, num_ds));
+ return uc_get_history_by_name(name, ret_history, num_steps, num_ds);
} /* int uc_get_history */
int uc_get_hits(const data_set_t *ds, const value_list_t *vl) {
if (FORMAT_VL(name, sizeof(name), vl) != 0) {
ERROR("uc_get_hits: FORMAT_VL failed.");
- return (STATE_ERROR);
+ return STATE_ERROR;
}
pthread_mutex_lock(&cache_lock);
pthread_mutex_unlock(&cache_lock);
- return (ret);
+ return ret;
} /* int uc_get_hits */
int uc_set_hits(const data_set_t *ds, const value_list_t *vl, int hits) {
if (FORMAT_VL(name, sizeof(name), vl) != 0) {
ERROR("uc_set_hits: FORMAT_VL failed.");
- return (STATE_ERROR);
+ return STATE_ERROR;
}
pthread_mutex_lock(&cache_lock);
pthread_mutex_unlock(&cache_lock);
- return (ret);
+ return ret;
} /* int uc_set_hits */
int uc_inc_hits(const data_set_t *ds, const value_list_t *vl, int step) {
if (FORMAT_VL(name, sizeof(name), vl) != 0) {
ERROR("uc_inc_hits: FORMAT_VL failed.");
- return (STATE_ERROR);
+ return STATE_ERROR;
}
pthread_mutex_lock(&cache_lock);
pthread_mutex_unlock(&cache_lock);
- return (ret);
+ return ret;
} /* int uc_inc_hits */
/*
iter = (uc_iter_t *)calloc(1, sizeof(*iter));
if (iter == NULL)
- return (NULL);
+ return NULL;
pthread_mutex_lock(&cache_lock);
iter->iter = c_avl_get_iterator(cache_tree);
if (iter->iter == NULL) {
free(iter);
- return (NULL);
+ return NULL;
}
- return (iter);
+ return iter;
} /* uc_iter_t *uc_get_iterator */
int uc_iterator_next(uc_iter_t *iter, char **ret_name) {
int status;
if (iter == NULL)
- return (-1);
+ return -1;
while ((status = c_avl_iterator_next(iter->iter, (void *)&iter->name,
(void *)&iter->entry)) == 0) {
if (status != 0) {
iter->name = NULL;
iter->entry = NULL;
- return (-1);
+ return -1;
}
if (ret_name != NULL)
*ret_name = iter->name;
- return (0);
+ return 0;
} /* int uc_iterator_next */
void uc_iterator_destroy(uc_iter_t *iter) {
int uc_iterator_get_time(uc_iter_t *iter, cdtime_t *ret_time) {
if ((iter == NULL) || (iter->entry == NULL) || (ret_time == NULL))
- return (-1);
+ return -1;
*ret_time = iter->entry->last_time;
- return (0);
+ return 0;
} /* int uc_iterator_get_name */
int uc_iterator_get_values(uc_iter_t *iter, value_t **ret_values,
size_t *ret_num) {
if ((iter == NULL) || (iter->entry == NULL) || (ret_values == NULL) ||
(ret_num == NULL))
- return (-1);
+ return -1;
*ret_values =
calloc(iter->entry->values_num, sizeof(*iter->entry->values_raw));
if (*ret_values == NULL)
- return (-1);
+ return -1;
for (size_t i = 0; i < iter->entry->values_num; ++i)
*ret_values[i] = iter->entry->values_raw[i];
*ret_num = iter->entry->values_num;
- return (0);
+ return 0;
} /* int uc_iterator_get_values */
int uc_iterator_get_interval(uc_iter_t *iter, cdtime_t *ret_interval) {
if ((iter == NULL) || (iter->entry == NULL) || (ret_interval == NULL))
- return (-1);
+ return -1;
*ret_interval = iter->entry->interval;
- return (0);
+ return 0;
} /* int uc_iterator_get_name */
+int uc_iterator_get_meta(uc_iter_t *iter, meta_data_t **ret_meta) {
+ if ((iter == NULL) || (iter->entry == NULL) || (ret_meta == NULL))
+ return -1;
+
+ *ret_meta = meta_data_clone(iter->entry->meta);
+
+ return 0;
+} /* int uc_iterator_get_meta */
+
/*
* Meta data interface
*/
status = FORMAT_VL(name, sizeof(name), vl);
if (status != 0) {
ERROR("utils_cache: uc_get_meta: FORMAT_VL failed.");
- return (NULL);
+ return NULL;
}
pthread_mutex_lock(&cache_lock);
status = c_avl_get(cache_tree, name, (void *)&ce);
if (status != 0) {
pthread_mutex_unlock(&cache_lock);
- return (NULL);
+ return NULL;
}
assert(ce != NULL);
if (ce->meta == NULL)
pthread_mutex_unlock(&cache_lock);
- return (ce->meta);
+ return ce->meta;
} /* }}} meta_data_t *uc_get_meta */
/* Sorry about this preprocessor magic, but it really makes this file much
int status; \
meta = uc_get_meta(vl); \
if (meta == NULL) \
- return (-1); \
+ return -1; \
status = wrap_function(meta, key); \
pthread_mutex_unlock(&cache_lock); \
- return (status); \
+ return status; \
}
int uc_meta_data_exists(const value_list_t *vl,
const char *key) UC_WRAP(meta_data_exists)
int status; \
meta = uc_get_meta(vl); \
if (meta == NULL) \
- return (-1); \
+ return -1; \
status = wrap_function(meta, key, value); \
pthread_mutex_unlock(&cache_lock); \
- return (status); \
+ return status; \
}
int uc_meta_data_add_string(const value_list_t *vl, const char *key,
const char *value)
const char *key, _Bool *value)
UC_WRAP(meta_data_get_boolean)
#undef UC_WRAP
-
- /* vim: set sw=2 ts=8 sts=2 tw=78 : */
int uc_get_rate_by_name(const char *name, gauge_t **ret_values,
size_t *ret_values_num);
gauge_t *uc_get_rate(const data_set_t *ds, const value_list_t *vl);
+int uc_get_value_by_name(const char *name, value_t **ret_values, size_t *ret_values_num);
+value_t *uc_get_value(const data_set_t *ds, const value_list_t *vl);
size_t uc_get_size(void);
int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number);
size_t *ret_num);
/* Return the interval of the value at the current position. */
int uc_iterator_get_interval(uc_iter_t *iter, cdtime_t *ret_interval);
+/* Return the metadata for the value at the current position. */
+int uc_iterator_get_meta(uc_iter_t *iter, meta_data_t **ret_meta);
/*
* Meta data interface
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 */
gauge_t *uc_get_rate(__attribute__((unused)) data_set_t const *ds,
__attribute__((unused)) value_list_t const *vl) {
errno = ENOTSUP;
- return (NULL);
+ return NULL;
}
int uc_get_rate_by_name(const char *name, gauge_t **ret_values,
size_t *ret_values_num) {
- return (ENOTSUP);
+ return ENOTSUP;
}
int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number) {
- return (ENOTSUP);
+ return ENOTSUP;
}
plugin_log(level, "%s", message);
} /* c_release */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
} while (0)
#endif /* UTILS_COMPLAIN_H */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
c_heap_t *h;
if (compare == NULL)
- return (NULL);
+ return NULL;
h = calloc(1, sizeof(*h));
if (h == NULL)
- return (NULL);
+ return NULL;
pthread_mutex_init(&h->lock, /* attr = */ NULL);
h->compare = compare;
h->list_len = 0;
h->list_size = 0;
- return (h);
+ return h;
} /* c_heap_t *c_heap_create */
void c_heap_destroy(c_heap_t *h) {
size_t index;
if ((h == NULL) || (ptr == NULL))
- return (-EINVAL);
+ return -EINVAL;
pthread_mutex_lock(&h->lock);
tmp = realloc(h->list, (h->list_size + 16) * sizeof(*h->list));
if (tmp == NULL) {
pthread_mutex_unlock(&h->lock);
- return (-ENOMEM);
+ return -ENOMEM;
}
h->list = tmp;
reheap(h, /* parent of this node = */ (index - 1) / 2, DIR_UP);
pthread_mutex_unlock(&h->lock);
- return (0);
+ return 0;
} /* int c_heap_insert */
void *c_heap_get_root(c_heap_t *h) {
void *ret = NULL;
if (h == NULL)
- return (NULL);
+ return NULL;
pthread_mutex_lock(&h->lock);
if (h->list_len == 0) {
pthread_mutex_unlock(&h->lock);
- return (NULL);
+ return NULL;
} else if (h->list_len == 1) {
ret = h->list[0];
h->list[0] = NULL;
pthread_mutex_unlock(&h->lock);
- return (ret);
+ return ret;
} /* void *c_heap_get_root */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
void *c_heap_get_root(c_heap_t *h);
#endif /* UTILS_HEAP_H */
-/* vim: set sw=2 sts=2 et : */
}
c_heap_destroy(h);
- return (0);
+ return 0;
}
int main(void) {
END_TEST;
}
-
-/* vim: set sw=2 sts=2 et : */
+++ /dev/null
-/**
- * collectd - src/utils_ignorelist.c
- * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
- * Copyright (C) 2008 Florian Forster <octo at collectd.org>
- *
- * 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 <lubek at users.sourceforge.net>
- * Florian Forster <octo at collectd.org>
- **/
-/**
- * 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) */
+++ /dev/null
-/**
- * collectd - src/utils_ignorelist.h
- * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
- *
- * 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 <lubek at users.sourceforge.net>
- **/
-/**
- * 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 <regex.h>
-#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 */
ret = calloc(1, sizeof(*ret));
if (ret == NULL)
- return (NULL);
+ return NULL;
- return (ret);
+ return ret;
}
void llist_destroy(llist_t *l) {
e->next = NULL;
}
- return (e);
+ return e;
}
void llentry_destroy(llentry_t *e) { free(e); }
--(l->size);
}
-int llist_size(llist_t *l) { return (l ? l->size : 0); }
+int llist_size(llist_t *l) { return l ? l->size : 0; }
static int llist_strcmp(llentry_t *e, void *ud) {
if ((e == NULL) || (ud == NULL))
- return (-1);
- return (strcmp(e->key, (const char *)ud));
+ return -1;
+ return strcmp(e->key, (const char *)ud);
}
llentry_t *llist_search(llist_t *l, const char *key) {
- return (llist_search_custom(l, llist_strcmp, (void *)key));
+ return llist_search_custom(l, llist_strcmp, (void *)key);
}
llentry_t *llist_search_custom(llist_t *l, int (*compare)(llentry_t *, void *),
llentry_t *e;
if (l == NULL)
- return (NULL);
+ return NULL;
e = l->head;
while (e != NULL) {
e = next;
}
- return (e);
+ return e;
}
llentry_t *llist_head(llist_t *l) {
if (l == NULL)
- return (NULL);
- return (l->head);
+ return NULL;
+ return l->head;
}
llentry_t *llist_tail(llist_t *l) {
if (l == NULL)
- return (NULL);
- return (l->tail);
+ return NULL;
+ return l->tail;
}
have_seed = 1;
}
-double cdrand_d() {
+double cdrand_d(void) {
double r;
pthread_mutex_lock(&lock);
r = erand48(seed);
pthread_mutex_unlock(&lock);
- return (r);
+ return r;
}
-uint32_t cdrand_u() {
+uint32_t cdrand_u(void) {
long r;
pthread_mutex_lock(&lock);
r = (long)(0.5 + (cdrand_d() * range));
r += min;
- return (r);
+ return r;
}
*
* This function is thread- and reentrant-safe.
*/
-double cdrand_d();
+double cdrand_d(void);
/**
* cdrand_u returns a random uint32_t value uniformly distributed in the range
*
* This function is thread- and reentrant-safe.
*/
-uint32_t cdrand_u();
+uint32_t cdrand_u(void);
/**
* Returns a random long between min and max, inclusively.
if ((buf == NULL) || (string == NULL) || (needle == NULL) ||
(replacement == NULL))
- return (NULL);
+ return NULL;
needle_len = strlen(needle);
sstrncpy(buf, string, buflen);
i, string, needle, replacement);
}
- return (buf);
+ return buf;
} /* char *subst_string */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
const char *needle, const char *replacement);
#endif /* UTILS_SUBST_H */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
END_TEST;
}
-
-/* vim: set sw=2 sts=2 et : */
name[sizeof(name) - 1] = '\0';
if (c_avl_get(threshold_tree, name, (void *)&th) == 0)
- return (th);
+ return th;
else
- return (NULL);
+ return NULL;
} /* }}} threshold_t *threshold_get */
/*
if ((th = threshold_get(vl->host, vl->plugin, vl->plugin_instance, vl->type,
vl->type_instance)) != NULL)
- return (th);
+ return th;
else if ((th = threshold_get(vl->host, vl->plugin, vl->plugin_instance,
vl->type, NULL)) != NULL)
- return (th);
+ return th;
else if ((th = threshold_get(vl->host, vl->plugin, NULL, vl->type,
vl->type_instance)) != NULL)
- return (th);
+ return th;
else if ((th = threshold_get(vl->host, vl->plugin, NULL, vl->type, NULL)) !=
NULL)
- return (th);
+ return th;
else if ((th = threshold_get(vl->host, "", NULL, vl->type,
vl->type_instance)) != NULL)
- return (th);
+ return th;
else if ((th = threshold_get(vl->host, "", NULL, vl->type, NULL)) != NULL)
- return (th);
+ return th;
else if ((th = threshold_get("", vl->plugin, vl->plugin_instance, vl->type,
vl->type_instance)) != NULL)
- return (th);
+ return th;
else if ((th = threshold_get("", vl->plugin, vl->plugin_instance, vl->type,
NULL)) != NULL)
- return (th);
+ return th;
else if ((th = threshold_get("", vl->plugin, NULL, vl->type,
vl->type_instance)) != NULL)
- return (th);
+ return th;
else if ((th = threshold_get("", vl->plugin, NULL, vl->type, NULL)) != NULL)
- return (th);
+ return th;
else if ((th = threshold_get("", "", NULL, vl->type, vl->type_instance)) !=
NULL)
- return (th);
+ return th;
else if ((th = threshold_get("", "", NULL, vl->type, NULL)) != NULL)
- return (th);
+ return th;
- return (NULL);
+ return NULL;
} /* }}} threshold_t *threshold_search */
int ut_search_threshold(const value_list_t *vl, /* {{{ */
threshold_t *t;
if (vl == NULL)
- return (EINVAL);
+ return EINVAL;
/* Is this lock really necessary? */
pthread_mutex_lock(&threshold_lock);
t = threshold_search(vl);
if (t == NULL) {
pthread_mutex_unlock(&threshold_lock);
- return (ENOENT);
+ return ENOENT;
}
memcpy(ret_threshold, t, sizeof(*ret_threshold));
ret_threshold->next = NULL;
- return (0);
+ return 0;
} /* }}} int ut_search_threshold */
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 : */
size_left -= len;
if (print_nano) {
- if ((len = ssnprintf(pos, size_left, ".%09ld", nsec)) == 0)
+ if ((len = snprintf(pos, size_left, ".%09ld", nsec)) == 0)
return ENOMEM;
pos += len;
size_left -= len;
return format_rfc3339_local(buffer, buffer_size, t, 1);
} /* }}} int rfc3339nano */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
int rfc3339nano_local(char *buffer, size_t buffer_size, cdtime_t t);
#endif /* UTILS_TIME_H */
-/* vim: set sw=2 sts=2 et : */
END_TEST;
}
-
-/* vim: set sw=2 sts=2 et : */
{
char *name;
char *select_db;
+ char *plugin_name;
cdtime_t interval;
if (conn == NULL) {
sstrncpy(buffer, "connection is NULL", buffer_size);
- return (buffer);
+ return buffer;
}
msg = NULL;
status = dbi_conn_error(conn, &msg);
if ((status >= 0) && (msg != NULL))
- ssnprintf(buffer, buffer_size, "%s (status %i)", msg, status);
+ snprintf(buffer, buffer_size, "%s (status %i)", msg, status);
else
- ssnprintf(buffer, buffer_size, "dbi_conn_error failed with status %i",
- status);
+ snprintf(buffer, buffer_size, "dbi_conn_error failed with status %i",
+ status);
- return (buffer);
+ return buffer;
} /* }}} const char *cdbi_conn_error */
static int cdbi_result_get_field(dbi_result res, /* {{{ */
if (src_type == DBI_TYPE_ERROR) {
ERROR("dbi plugin: cdbi_result_get: "
"dbi_result_get_field_type_idx failed.");
- return (-1);
+ return -1;
}
if (src_type == DBI_TYPE_INTEGER) {
long long value;
value = dbi_result_get_longlong_idx(res, index);
- ssnprintf(buffer, buffer_size, "%lli", value);
+ snprintf(buffer, buffer_size, "%lli", value);
} else if (src_type == DBI_TYPE_DECIMAL) {
double value;
value = dbi_result_get_double_idx(res, index);
- ssnprintf(buffer, buffer_size, "%63.15g", value);
+ snprintf(buffer, buffer_size, "%63.15g", value);
} else if (src_type == DBI_TYPE_STRING) {
const char *value;
if (value == NULL)
sstrncpy(buffer, "", buffer_size);
else if (strcmp("ERROR", value) == 0)
- return (-1);
+ return -1;
else
sstrncpy(buffer, value, buffer_size);
}
ERROR("dbi plugin: Column `%s': Don't know how to handle "
"source type %hu.",
field_name, src_type);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cdbi_result_get_field */
static void cdbi_database_free(cdbi_database_t *db) /* {{{ */
sfree(db->name);
sfree(db->select_db);
+ sfree(db->plugin_name);
sfree(db->driver);
sfree(db->host);
(ci->values[1].type != OCONFIG_TYPE_NUMBER))) {
WARNING("dbi plugin: The `DriverOption' config option "
"needs exactly two arguments.");
- return (-1);
+ return -1;
}
option = realloc(db->driver_options,
sizeof(*option) * (db->driver_options_num + 1));
if (option == NULL) {
ERROR("dbi plugin: realloc failed");
- return (-1);
+ return -1;
}
db->driver_options = option;
option->key = strdup(ci->values[0].value.string);
if (option->key == NULL) {
ERROR("dbi plugin: strdup failed.");
- return (-1);
+ return -1;
}
if (ci->values[1].type == OCONFIG_TYPE_STRING) {
if (option->value.string == NULL) {
ERROR("dbi plugin: strdup failed.");
sfree(option->key);
- return (-1);
+ return -1;
}
} else {
assert(ci->values[1].type == OCONFIG_TYPE_NUMBER);
}
db->driver_options_num++;
- return (0);
+ return 0;
} /* }}} int cdbi_config_add_database_driver_option */
static int cdbi_config_add_database(oconfig_item_t *ci) /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("dbi plugin: The `Database' block "
"needs exactly one string argument.");
- return (-1);
+ return -1;
}
db = calloc(1, sizeof(*db));
if (db == NULL) {
ERROR("dbi plugin: calloc failed.");
- return (-1);
+ return -1;
}
status = cf_util_get_string(ci, &db->name);
if (status != 0) {
sfree(db);
- return (status);
+ return status;
}
/* Fill the `cdbi_database_t' structure.. */
status = cf_util_get_string(child, &db->host);
else if (strcasecmp("Interval", child->key) == 0)
status = cf_util_get_cdtime(child, &db->interval);
+ else if (strcasecmp("Plugin", child->key) == 0)
+ status = cf_util_get_string(child, &db->plugin_name);
else {
WARNING("dbi plugin: Option `%s' not allowed here.", child->key);
status = -1;
if (status != 0) {
cdbi_database_free(db);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cdbi_config_add_database */
static int cdbi_config(oconfig_item_t *ci) /* {{{ */
}
} /* for (ci->children) */
- return (0);
+ return 0;
} /* }}} int cdbi_config */
/* }}} End of configuration handling functions */
int status;
if (did_init != 0)
- return (0);
+ return 0;
if (queries_num == 0) {
ERROR("dbi plugin: No <Query> blocks have been found. Without them, "
"this plugin can't do anything useful, so we will return an error.");
- return (-1);
+ return -1;
}
if (databases_num == 0) {
ERROR("dbi plugin: No <Database> blocks have been found. Without them, "
"this plugin can't do anything useful, so we will return an error.");
- return (-1);
+ return -1;
}
status = dbi_initialize_r(/* driverdir = */ NULL, &dbi_instance);
if (status < 0) {
ERROR("dbi plugin: cdbi_init: dbi_initialize_r failed with status %i.",
status);
- return (-1);
+ return -1;
} else if (status == 0) {
ERROR("dbi plugin: `dbi_initialize_r' could not load any drivers. Please "
"install at least one `DBD' or check your installation.");
- return (-1);
+ return -1;
}
DEBUG("dbi plugin: cdbi_init: dbi_initialize_r reports %i driver%s.", status,
(status == 1) ? "" : "s");
- return (0);
+ return 0;
} /* }}} int cdbi_init */
static int cdbi_read_database_query(cdbi_database_t *db, /* {{{ */
udb_query_prepare_result(
q, prep_area, (db->host ? db->host : hostname_g),
- /* plugin = */ "dbi", db->name, column_names, column_num,
+ /* plugin = */ (db->plugin_name != NULL) ? db->plugin_name : "dbi",
+ db->name, column_names, column_num,
/* interval = */ (db->interval > 0) ? db->interval : 0);
/* 0 = error; 1 = success; */
if (db->connection != NULL) {
status = dbi_conn_ping(db->connection);
if (status != 0) /* connection is alive */
- return (0);
+ return 0;
dbi_conn_close(db->connection);
db->connection = NULL;
driver = dbi_driver_list_r(driver, dbi_instance)) {
INFO("dbi plugin: * %s", dbi_driver_get_name(driver));
}
- return (-1);
+ return -1;
}
connection = dbi_conn_open(driver);
if (connection == NULL) {
ERROR("dbi plugin: cdbi_connect_database: dbi_conn_open (%s) failed.",
db->driver);
- return (-1);
+ return -1;
}
/* Set all the driver options. Because this is a very very very generic
}
dbi_conn_close(connection);
- return (-1);
+ return -1;
}
} /* for (i = 0; i < db->driver_options_num; i++) */
"dbi_conn_connect failed: %s",
db->name, cdbi_strerror(connection, errbuf, sizeof(errbuf)));
dbi_conn_close(connection);
- return (-1);
+ return -1;
}
if (db->select_db != NULL) {
db->name, db->select_db,
cdbi_strerror(connection, errbuf, sizeof(errbuf)));
dbi_conn_close(connection);
- return (-1);
+ return -1;
}
}
db->connection = connection;
- return (0);
+ return 0;
} /* }}} int cdbi_connect_database */
static int cdbi_read_database(user_data_t *ud) /* {{{ */
status = cdbi_connect_database(db);
if (status != 0)
- return (status);
+ return status;
assert(db->connection != NULL);
db_version = dbi_conn_get_engine_version(db->connection);
if (success == 0) {
ERROR("dbi plugin: All queries failed for database `%s'.", db->name);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cdbi_read_database */
static int cdbi_shutdown(void) /* {{{ */
queries = NULL;
queries_num = 0;
- return (0);
+ return 0;
} /* }}} int cdbi_shutdown */
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
- */
if (il_fstype == NULL)
il_fstype = ignorelist_create(1);
- return (0);
+ return 0;
}
static int df_config(const char *key, const char *value) {
if (strcasecmp(key, "Device") == 0) {
if (ignorelist_add(il_device, value))
- return (1);
- return (0);
+ return 1;
+ return 0;
} else if (strcasecmp(key, "MountPoint") == 0) {
if (ignorelist_add(il_mountpoint, value))
- return (1);
- return (0);
+ return 1;
+ return 0;
} else if (strcasecmp(key, "FSType") == 0) {
if (ignorelist_add(il_fstype, value))
- return (1);
- return (0);
+ return 1;
+ return 0;
} else if (strcasecmp(key, "IgnoreSelected") == 0) {
if (IS_TRUE(value)) {
ignorelist_set_invert(il_device, 0);
ignorelist_set_invert(il_mountpoint, 1);
ignorelist_set_invert(il_fstype, 1);
}
- return (0);
+ return 0;
} else if (strcasecmp(key, "ReportByDevice") == 0) {
if (IS_TRUE(value))
by_device = 1;
- return (0);
+ return 0;
} else if (strcasecmp(key, "ReportInodes") == 0) {
if (IS_TRUE(value))
report_inodes = 1;
else
report_inodes = 0;
- return (0);
+ return 0;
} else if (strcasecmp(key, "ValuesAbsolute") == 0) {
if (IS_TRUE(value))
values_absolute = 1;
else
values_absolute = 0;
- return (0);
+ return 0;
} else if (strcasecmp(key, "ValuesPercentage") == 0) {
if (IS_TRUE(value))
values_percentage = 1;
else
values_percentage = 0;
- return (0);
+ return 0;
}
- return (-1);
+ return -1;
}
__attribute__((nonnull(2))) static void df_submit_one(char *plugin_instance,
mnt_list = NULL;
if (cu_mount_getlist(&mnt_list) == NULL) {
ERROR("df plugin: cu_mount_getlist failed.");
- return (-1);
+ return -1;
}
for (cu_mount_t *mnt_ptr = mnt_list; mnt_ptr != NULL;
df_submit_one(disk_name, "percent_bytes", "used",
(gauge_t)((float_t)(blk_used) / statbuf.f_blocks * 100));
} else
- return (-1);
+ return -1;
}
/* inode handling */
disk_name, "percent_inodes", "used",
(gauge_t)((float_t)(inode_used) / statbuf.f_files * 100));
} else
- return (-1);
+ return -1;
}
if (values_absolute) {
df_submit_one(disk_name, "df_inodes", "free", (gauge_t)inode_free);
cu_mount_freelist(mnt_list);
- return (0);
+ return 0;
} /* int df_read */
void module_register(void) {
#error "No applicable input method."
#endif
-#if HAVE_LIBUDEV
+#if HAVE_UDEV_H
#include <libudev.h>
static char *conf_udev_name_attr = NULL;
if (ignorelist == NULL)
ignorelist = ignorelist_create(/* invert = */ 1);
if (ignorelist == NULL)
- return (1);
+ return 1;
if (strcasecmp("Disk", key) == 0) {
ignorelist_add(ignorelist, 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;
}
if ((conf_udev_name_attr = strdup(value)) == NULL)
- return (1);
+ return 1;
#else
WARNING("disk plugin: The \"UdevNameAttr\" option is only supported "
"if collectd is built with libudev support");
#endif
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int disk_config */
static int disk_init(void) {
if (status != kIOReturnSuccess) {
ERROR("IOMasterPort failed: %s", mach_error_string(status));
io_master_port = MACH_PORT_NULL;
- return (-1);
+ return -1;
}
/* #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) {
ERROR("disk plugin: udev_new() failed!");
- return (-1);
+ return -1;
}
}
-#endif /* HAVE_LIBUDEV */
+#endif /* HAVE_UDEV_H */
/* #endif KERNEL_LINUX */
#elif KERNEL_FREEBSD
rv = geom_gettree(&geom_tree);
if (rv != 0) {
ERROR("geom_gettree() failed, returned %d", rv);
- return (-1);
+ return -1;
}
rv = geom_stats_open();
if (rv != 0) {
ERROR("geom_stats_open() failed, returned %d", rv);
- return (-1);
+ return -1;
}
/* #endif KERNEL_FREEBSD */
numdisk = 0;
if (kc == NULL)
- return (-1);
+ return -1;
for (numdisk = 0, ksp_chain = kc->kc_chain;
(numdisk < MAX_NUMDISK) && (ksp_chain != NULL);
}
#endif /* HAVE_LIBKSTAT */
- return (0);
+ return 0;
} /* int disk_init */
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);
+ return 0;
} /* int disk_shutdown */
static void disk_submit(const char *plugin_instance, const char *type,
double avg_time = ((double)delta_time) / ((double)delta_ops);
double avg_time_incr = interval * avg_time;
- return ((counter_t)(avg_time_incr + .5));
+ return (counter_t)(avg_time_incr + .5);
}
#endif
-#if HAVE_LIBUDEV
+#if HAVE_UDEV_H
/**
* Attempt to provide an rename disk instance from an assigned udev attribute.
*
kCFStringEncodingASCII);
if (key_obj == NULL) {
DEBUG("CFStringCreateWithCString (%s) failed.", key);
- return (-1LL);
+ return -1LL;
}
/* get => we don't need to release (== free) the object */
if (val_obj == NULL) {
DEBUG("CFDictionaryGetValue (%s) failed.", key);
- return (-1LL);
+ return -1LL;
}
if (!CFNumberGetValue(val_obj, kCFNumberSInt64Type, &val_int)) {
DEBUG("CFNumberGetValue (%s) failed.", key);
- return (-1LL);
+ return -1LL;
}
- return (val_int);
+ return val_int;
}
#endif /* HAVE_IOKIT_IOKITLIB_H */
io_master_port, IOServiceMatching(kIOBlockStorageDriverClass),
&disk_list) != kIOReturnSuccess) {
ERROR("disk plugin: IOServiceGetMatchingServices failed.");
- return (-1);
+ return -1;
}
while ((disk = IOIteratorNext(disk_list)) != 0) {
sstrncpy(disk_name, props_disk_name_bsd, sizeof(disk_name));
else {
ERROR("disk plugin: can't find bsd disk name.");
- ssnprintf(disk_name, sizeof(disk_name), "%i-%i", disk_major,
- disk_minor);
+ snprintf(disk_name, sizeof(disk_name), "%i-%i", disk_major, disk_minor);
}
} else
- ssnprintf(disk_name, sizeof(disk_name), "%i-%i", disk_major, disk_minor);
+ snprintf(disk_name, sizeof(disk_name), "%i-%i", disk_major, disk_minor);
DEBUG("disk plugin: disk_name = \"%s\"", disk_name);
snap = geom_stats_snapshot_get();
if (snap == NULL) {
ERROR("disk plugin: geom_stats_snapshot_get() failed.");
- return (-1);
+ return -1;
}
/* Check if we have dirty read from this snapshot */
if (geom_gettree(&geom_tree) != 0) {
ERROR("disk plugin: geom_gettree() failed");
geom_stats_snapshot_free(snap);
- return (-1);
+ return -1;
}
geom_id = geom_lookupid(&geom_tree, snap_iter->id);
}
fh = fopen("/proc/partitions", "r");
if (fh == NULL) {
ERROR("disk plugin: fopen (/proc/{diskstats,partitions}) failed.");
- return (-1);
+ return -1;
}
/* Kernel is 2.4.* */
output_name = disk_name;
-#if HAVE_LIBUDEV
+#if HAVE_UDEV_H
char *alt_name = NULL;
if (conf_udev_name_attr != NULL) {
alt_name =
#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
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
static kstat_io_t kio;
if (kc == NULL)
- return (-1);
+ return -1;
for (int i = 0; i < numdisk; i++) {
if (kstat_read(kc, ksp[i], &kio) == -1)
char name[DATA_MAX_NAME_LEN];
if ((ds = sg_get_disk_io_stats(&disks)) == NULL)
- return (0);
+ return 0;
for (int counter = 0; counter < disks; counter++) {
strncpy(name, ds->disk_name, sizeof(name));
char errbuf[1024];
WARNING("disk plugin: perfstat_disk: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
if (numdisk != pnumdisk || stat_disk == NULL) {
char errbuf[1024];
WARNING("disk plugin: perfstat_disk : %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
for (int i = 0; i < rnumdisk; i++) {
}
#endif /* defined(HAVE_PERFSTAT) */
- return (0);
+ return 0;
} /* int disk_read */
void module_register(void) {
if (entry->key == key)
break;
- return (entry);
+ return entry;
}
static counter_list_t *counter_list_create(counter_list_t **list,
entry = calloc(1, sizeof(*entry));
if (entry == NULL)
- return (NULL);
+ return NULL;
entry->key = key;
entry->value = value;
last->next = entry;
}
- return (entry);
+ return entry;
}
static void counter_list_add(counter_list_t **list, unsigned int key,
if (pcap_device != NULL)
free(pcap_device);
if ((pcap_device = strdup(value)) == NULL)
- return (1);
+ return 1;
} else if (strcasecmp(key, "IgnoreSource") == 0) {
if (value != NULL)
ignore_list_add_name(value);
else
select_numeric_qtype = 1;
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static void dns_child_callback(const rfc1035_header_t *dns) {
ERROR("dns plugin: Opening interface `%s' "
"failed: %s",
(pcap_device != NULL) ? pcap_device : "any", pcap_error);
- return (PCAP_ERROR);
+ return PCAP_ERROR;
}
status = pcap_compile(pcap_obj, &fp, "udp port 53", 1, 0);
if (status < 0) {
ERROR("dns plugin: pcap_compile failed: %s", pcap_statustostr(status));
- return (status);
+ return status;
}
status = pcap_setfilter(pcap_obj, &fp);
if (status < 0) {
ERROR("dns plugin: pcap_setfilter failed: %s", pcap_statustostr(status));
- return (status);
+ return status;
}
DEBUG("dns plugin: PCAP object created.");
status = PCAP_ERROR_IFACE_NOT_UP;
pcap_close(pcap_obj);
- return (status);
+ return status;
} /* int dns_run_pcap_loop */
static int dns_sleep_one_interval(void) /* {{{ */
if ((errno == EINTR) || (errno == EAGAIN))
continue;
- return (errno);
+ return errno;
}
- return (0);
+ return 0;
} /* }}} int dns_sleep_one_interval */
static void *dns_child_loop(__attribute__((unused)) void *dummy) /* {{{ */
ERROR("dns plugin: PCAP returned error %s.", pcap_statustostr(status));
listen_thread_init = 0;
- return (NULL);
+ return NULL;
} /* }}} void *dns_child_loop */
static int dns_init(void) {
pthread_mutex_unlock(&traffic_mutex);
if (listen_thread_init != 0)
- return (-1);
+ return -1;
status = plugin_thread_create(&listen_thread, NULL, dns_child_loop, (void *)0,
"dns listen");
char errbuf[1024];
ERROR("dns plugin: pthread_create failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
listen_thread_init = 1;
}
#endif
- return (0);
+ return 0;
} /* int dns_init */
static void submit_derive(const char *type, const char *type_instance,
submit_derive("dns_rcode", rcode_str(keys[i]), values[i]);
}
- return (0);
+ return 0;
} /* int dns_read */
void module_register(void) {
--- /dev/null
+/*
+ * collectd - src/dpdkevents.c
+ * MIT License
+ *
+ * Copyright(c) 2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Maryam Tahhan <maryam.tahhan@intel.com>
+ * Harry van Haaren <harry.van.haaren@intel.com>
+ * Serhiy Pshyk <serhiyx.pshyk@intel.com>
+ * Kim-Marie Jones <kim-marie.jones@intel.com>
+ * Krzysztof Matczak <krzysztofx@intel.com>
+ */
+
+#include "collectd.h"
+
+#include "common.h"
+#include "plugin.h"
+
+#include "semaphore.h"
+#include "sys/mman.h"
+#include "utils_dpdk.h"
+#include "utils_time.h"
+
+#include <rte_config.h>
+#include <rte_eal.h>
+#include <rte_ethdev.h>
+#include <rte_keepalive.h>
+
+#define DPDK_EVENTS_PLUGIN "dpdkevents"
+#define DPDK_EVENTS_NAME "dpdk_collectd_events"
+#define ETH_LINK_NA 0xFF
+
+#define INT64_BIT_SIZE 64
+#define KEEPALIVE_PLUGIN_INSTANCE "keepalive"
+#define RTE_KEEPALIVE_SHM_NAME "/dpdk_keepalive_shm_name"
+
+typedef struct dpdk_keepalive_shm_s {
+ sem_t core_died;
+ enum rte_keepalive_state core_state[RTE_KEEPALIVE_MAXCORES];
+ uint64_t core_last_seen_times[RTE_KEEPALIVE_MAXCORES];
+} dpdk_keepalive_shm_t;
+
+typedef struct dpdk_ka_monitor_s {
+ cdtime_t read_time;
+ int lcore_state;
+} dpdk_ka_monitor_t;
+
+typedef struct dpdk_link_status_config_s {
+ int enabled;
+ _Bool send_updated;
+ uint32_t enabled_port_mask;
+ char port_name[RTE_MAX_ETHPORTS][DATA_MAX_NAME_LEN];
+ _Bool notify;
+} dpdk_link_status_config_t;
+
+typedef struct dpdk_keep_alive_config_s {
+ int enabled;
+ _Bool send_updated;
+ uint128_t lcore_mask;
+ dpdk_keepalive_shm_t *shm;
+ char shm_name[DATA_MAX_NAME_LEN];
+ _Bool notify;
+ int fd;
+} 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;
+
+typedef enum {
+ DPDK_EVENTS_STATE_CFG_ERR = 1 << 0,
+ DPDK_EVENTS_STATE_KA_CFG_ERR = 1 << 1,
+ DPDK_EVENTS_STATE_LS_CFG_ERR = 1 << 2,
+
+} dpdk_events_cfg_status;
+
+#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 dpdk_events_cfg_status g_state;
+
+static int dpdk_event_keep_alive_shm_open(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_RDONLY, 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;
+ }
+
+ if (ec->config.keep_alive.fd != -1) {
+ struct stat stat_old, stat_new;
+
+ if (fstat(ec->config.keep_alive.fd, &stat_old) || fstat(fd, &stat_new)) {
+ ERROR(DPDK_EVENTS_PLUGIN ": failed to get information about a file");
+ close(fd);
+ return -1;
+ }
+
+ /* Check if inode number has changed. If yes, then create a new mapping */
+ if (stat_old.st_ino == stat_new.st_ino) {
+ close(fd);
+ return 0;
+ }
+
+ if (munmap(ec->config.keep_alive.shm, sizeof(dpdk_keepalive_shm_t)) != 0) {
+ ERROR(DPDK_EVENTS_PLUGIN ": munmap KA monitor failed");
+ close(fd);
+ return -1;
+ }
+
+ close(ec->config.keep_alive.fd);
+ ec->config.keep_alive.fd = -1;
+ }
+
+ ec->config.keep_alive.shm = (dpdk_keepalive_shm_t *)mmap(
+ 0, sizeof(*(ec->config.keep_alive.shm)), PROT_READ, MAP_SHARED, fd, 0);
+ if (ec->config.keep_alive.shm == MAP_FAILED) {
+ ERROR(DPDK_EVENTS_PLUGIN ": Failed to mmap KA SHM:%s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ close(fd);
+ return errno;
+ }
+ ec->config.keep_alive.fd = fd;
+
+ 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();
+
+ /* In configless mode when no <Plugin/> section is defined in config file
+ * both link_status and keep_alive should be enabled */
+
+ /* Link Status */
+ ec->config.link_status.enabled = 1;
+ 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 = 1;
+ ec->config.keep_alive.send_updated = 1;
+ ec->config.keep_alive.notify = 0;
+ /* by default enable 128 cores */
+ memset(&ec->config.keep_alive.lcore_mask, 1,
+ sizeof(ec->config.keep_alive.lcore_mask));
+ memset(&ec->config.keep_alive.shm_name, 0,
+ sizeof(ec->config.keep_alive.shm_name));
+ ec->config.keep_alive.shm = MAP_FAILED;
+ ec->config.keep_alive.fd = -1;
+}
+
+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) {
+ if (cf_util_get_int(child,
+ (int *)&ec->config.link_status.enabled_port_mask))
+ return -1;
+ DEBUG(DPDK_EVENTS_PLUGIN ": LinkStatus:Enabled Port Mask 0x%X",
+ ec->config.link_status.enabled_port_mask);
+ } else if (strcasecmp("SendEventsOnUpdate", child->key) == 0) {
+ if (cf_util_get_boolean(child, &ec->config.link_status.send_updated))
+ return -1;
+ DEBUG(DPDK_EVENTS_PLUGIN ": LinkStatus:SendEventsOnUpdate %d",
+ ec->config.link_status.send_updated);
+ } else if (strcasecmp("SendNotification", child->key) == 0) {
+ if (cf_util_get_boolean(child, &ec->config.link_status.notify))
+ return -1;
+
+ DEBUG(DPDK_EVENTS_PLUGIN ": LinkStatus:SendNotification %d",
+ ec->config.link_status.notify);
+ } else if (strcasecmp("PortName", child->key) != 0) {
+ ERROR(DPDK_EVENTS_PLUGIN ": unrecognized configuration option %s.",
+ child->key);
+ return -1;
+ }
+ }
+
+ 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++;
+
+ if (cf_util_get_string_buffer(
+ child, ec->config.link_status.port_name[port_num],
+ sizeof(ec->config.link_status.port_name[port_num]))) {
+ return -1;
+ }
+ 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) {
+ if (cf_util_get_boolean(child, &ec->config.keep_alive.send_updated))
+ return -1;
+
+ DEBUG(DPDK_EVENTS_PLUGIN ": KeepAlive:SendEventsOnUpdate %d",
+ ec->config.keep_alive.send_updated);
+ } else if (strcasecmp("LCoreMask", child->key) == 0) {
+ char lcore_mask[DATA_MAX_NAME_LEN];
+
+ if (cf_util_get_string_buffer(child, lcore_mask, sizeof(lcore_mask)))
+ return -1;
+ 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) {
+ if (cf_util_get_string_buffer(child, ec->config.keep_alive.shm_name,
+ sizeof(ec->config.keep_alive.shm_name)))
+ return -1;
+
+ DEBUG(DPDK_EVENTS_PLUGIN ": KeepAlive:KeepAliveShmName %s",
+ ec->config.keep_alive.shm_name);
+ } else if (strcasecmp("SendNotification", child->key) == 0) {
+ if (cf_util_get_boolean(child, &ec->config.keep_alive.notify))
+ return -1;
+
+ DEBUG(DPDK_EVENTS_PLUGIN ": KeepAlive:SendNotification %d",
+ ec->config.keep_alive.notify);
+ } else {
+ ERROR(DPDK_EVENTS_PLUGIN ": unrecognized configuration option %s.",
+ child->key);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int dpdk_events_config(oconfig_item_t *ci) {
+ DPDK_EVENTS_TRACE();
+ int ret = dpdk_events_preinit();
+ if (ret) {
+ g_state |= DPDK_EVENTS_STATE_CFG_ERR;
+ return 0;
+ }
+
+ dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
+
+ /* Disabling link_status and keep_alive since <Plugin/> config section
+ * specifies if those should be enabled */
+ ec->config.keep_alive.enabled = ec->config.link_status.enabled = 0;
+ memset(&ec->config.keep_alive.lcore_mask, 0,
+ sizeof(ec->config.keep_alive.lcore_mask));
+
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp("EAL", child->key) == 0)
+ ret = dpdk_helper_eal_config_parse(g_hc, child);
+ else if (strcasecmp("Event", child->key) == 0) {
+ char event_type[DATA_MAX_NAME_LEN];
+
+ if (cf_util_get_string_buffer(child, event_type, sizeof(event_type)))
+ ret = -1;
+ else if (strcasecmp(event_type, "link_status") == 0) {
+ ret = dpdk_events_link_status_config(ec, child);
+ if (ret) {
+ g_state |= DPDK_EVENTS_STATE_LS_CFG_ERR;
+ continue;
+ }
+ } else if (strcasecmp(event_type, "keep_alive") == 0) {
+ ret = dpdk_events_keep_alive_config(ec, child);
+ if (ret) {
+ g_state |= DPDK_EVENTS_STATE_KA_CFG_ERR;
+ continue;
+ }
+ } else {
+ ERROR(DPDK_EVENTS_PLUGIN ": The selected event \"%s\" is unknown.",
+ event_type);
+ ret = -1;
+ }
+ } else {
+ ERROR(DPDK_EVENTS_PLUGIN ": unrecognized configuration option %s.",
+ child->key);
+ ret = -1;
+ }
+
+ if (ret != 0) {
+ g_state |= DPDK_EVENTS_STATE_CFG_ERR;
+ return 0;
+ }
+ }
+
+ if (g_state & DPDK_EVENTS_STATE_KA_CFG_ERR) {
+ ERROR(DPDK_EVENTS_PLUGIN
+ ": Invalid keep alive configuration. Event disabled.");
+ ec->config.keep_alive.enabled = 0;
+ }
+
+ if (g_state & DPDK_EVENTS_STATE_LS_CFG_ERR) {
+ ERROR(DPDK_EVENTS_PLUGIN
+ ": Invalid link status configuration. Event disabled.");
+ ec->config.link_status.enabled = 0;
+ }
+
+ 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");
+ g_state |= DPDK_EVENTS_STATE_CFG_ERR;
+ return 0;
+ }
+
+ return 0;
+}
+
+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.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) {
+ snprintf(dev_name, sizeof(dev_name), "%s",
+ ec->config.link_status.port_name[i]);
+ } else {
+ snprintf(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];
+ snprintf(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];
+ snprintf(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;
+ snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: ALIVE", i);
+ break;
+ case RTE_KA_STATE_MISSING:
+ snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: MISSING", i);
+ sev = NOTIF_WARNING;
+ break;
+ case RTE_KA_STATE_DEAD:
+ snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: DEAD", i);
+ sev = NOTIF_FAILURE;
+ break;
+ case RTE_KA_STATE_UNUSED:
+ snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: UNUSED", i);
+ sev = NOTIF_OKAY;
+ break;
+ case RTE_KA_STATE_GONE:
+ snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: GONE", i);
+ sev = NOTIF_FAILURE;
+ break;
+ case RTE_KA_STATE_DOZING:
+ snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: DOZING", i);
+ sev = NOTIF_OKAY;
+ break;
+ case RTE_KA_STATE_SLEEP:
+ snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: SLEEP", i);
+ sev = NOTIF_OKAY;
+ break;
+ default:
+ snprintf(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);
+ int ls_ret = -1, ka_ret = -1;
+
+ int cmd_res = 0;
+ if (ec->config.link_status.enabled) {
+ ls_ret = dpdk_helper_command(g_hc, DPDK_CMD_GET_EVENTS, &cmd_res,
+ ec->config.interval);
+ if (cmd_res == 0 && ls_ret == 0) {
+ dpdk_events_link_status_dispatch(g_hc);
+ }
+ }
+
+ if (ec->config.keep_alive.enabled) {
+ ka_ret = dpdk_event_keep_alive_shm_open();
+ if (ka_ret) {
+ ERROR(DPDK_EVENTS_PLUGIN
+ ": %s : error %d in dpdk_event_keep_alive_shm_open()",
+ __FUNCTION__, ka_ret);
+ } else
+ dpdk_events_keep_alive_dispatch(g_hc);
+ }
+
+ if (!((cmd_res || ls_ret) == 0 || ka_ret == 0)) {
+ ERROR(DPDK_EVENTS_PLUGIN ": Read failure for all enabled event types");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int dpdk_events_shutdown(void) {
+ DPDK_EVENTS_TRACE();
+
+ if (g_hc == NULL)
+ return 0;
+
+ dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
+ if (ec->config.keep_alive.enabled) {
+ if (ec->config.keep_alive.fd != -1) {
+ close(ec->config.keep_alive.fd);
+ ec->config.keep_alive.fd = -1;
+ }
+
+ if (ec->config.keep_alive.shm != MAP_FAILED) {
+ if (munmap(ec->config.keep_alive.shm, sizeof(dpdk_keepalive_shm_t))) {
+ ERROR(DPDK_EVENTS_PLUGIN ": munmap KA monitor failed");
+ return -1;
+ }
+ ec->config.keep_alive.shm = MAP_FAILED;
+ }
+ }
+
+ dpdk_helper_shutdown(g_hc);
+ g_hc = NULL;
+
+ return 0;
+}
+
+static int dpdk_events_init(void) {
+ DPDK_EVENTS_TRACE();
+
+ if (g_state & DPDK_EVENTS_STATE_CFG_ERR) {
+ dpdk_events_shutdown();
+ return -1;
+ }
+
+ int ret = dpdk_events_preinit();
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+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);
+}
-/*-
+/*
* collectd - src/dpdkstat.c
* MIT License
*
* Maryam Tahhan <maryam.tahhan@intel.com>
* Harry van Haaren <harry.van.haaren@intel.com>
* Taras Chornyi <tarasx.chornyi@intel.com>
+ * Serhiy Pshyk <serhiyx.pshyk@intel.com>
+ * Krzysztof Matczak <krzysztofx.matczak@intel.com>
*/
#include "collectd.h"
-#include "common.h" /* auxiliary functions */
-#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */
-#include "utils_time.h"
-
-#include <getopt.h>
-#include <poll.h>
-#include <semaphore.h>
-#include <sys/mman.h>
-#include <sys/queue.h>
+#include "common.h"
+#include "utils_dpdk.h"
-#include <rte_atomic.h>
-#include <rte_branch_prediction.h>
-#include <rte_common.h>
#include <rte_config.h>
-#include <rte_debug.h>
-#include <rte_debug.h>
-#include <rte_eal.h>
#include <rte_ethdev.h>
-#include <rte_launch.h>
-#include <rte_lcore.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_per_lcore.h>
-#include <rte_string_fns.h>
-#include <rte_tailq.h>
-#include <rte_version.h>
-
-#define DPDK_DEFAULT_RTE_CONFIG "/var/run/.rte_config"
-#define DPDK_MAX_ARGC 8
-#define DPDKSTAT_MAX_BUFFER_SIZE (4096 * 4)
-#define DPDK_SHM_NAME "dpdk_collectd_stats_shm"
-#define ERR_BUF_SIZE 1024
-#define REINIT_SHM 1
-#define RESET 1
-#define NO_RESET 0
+
+#define DPDK_STATS_PLUGIN "dpdkstat"
+#define DPDK_STATS_NAME "dpdk_collectd_stats"
+
+#define DPDK_STATS_TRACE() \
+ DEBUG("%s:%s:%d pid=%u", DPDK_STATS_PLUGIN, __FUNCTION__, __LINE__, getpid())
+
+struct dpdk_stats_config_s {
+ cdtime_t interval;
+ uint32_t enabled_port_mask;
+ char port_name[RTE_MAX_ETHPORTS][DATA_MAX_NAME_LEN];
+};
+typedef struct dpdk_stats_config_s dpdk_stats_config_t;
#define RTE_VERSION_16_07 RTE_VERSION_NUM(16, 7, 0, 16)
ctx->xstats = (struct rte_eth_xstat *)&ctx->raw_data[0]; \
ctx->xnames = \
(struct rte_eth_xstat_name *)&ctx \
- ->raw_data[ctx->num_xstats * sizeof(struct rte_eth_xstat)]; \
+ ->raw_data[ctx->stats_count * sizeof(struct rte_eth_xstat)]; \
} while (0)
#endif
-enum DPDK_HELPER_ACTION {
- DPDK_HELPER_ACTION_COUNT_STATS,
- DPDK_HELPER_ACTION_SEND_STATS,
-};
-
-enum DPDK_HELPER_STATUS {
- DPDK_HELPER_NOT_INITIALIZED = 0,
- DPDK_HELPER_WAITING_ON_PRIMARY,
- DPDK_HELPER_INITIALIZING_EAL,
- DPDK_HELPER_ALIVE_SENDING_STATS,
- DPDK_HELPER_GRACEFUL_QUIT,
-};
-
-struct dpdk_config_s {
- /* General DPDK params */
- char coremask[DATA_MAX_NAME_LEN];
- char memory_channels[DATA_MAX_NAME_LEN];
- char socket_memory[DATA_MAX_NAME_LEN];
- char process_type[DATA_MAX_NAME_LEN];
- char file_prefix[DATA_MAX_NAME_LEN];
- cdtime_t interval;
- uint32_t eal_initialized;
- uint32_t enabled_port_mask;
- char port_name[RTE_MAX_ETHPORTS][DATA_MAX_NAME_LEN];
- uint32_t eal_argc;
- /* Helper info */
- int collectd_reinit_shm;
- pid_t helper_pid;
- sem_t sema_helper_get_stats;
- sem_t sema_stats_in_shm;
- int helper_pipes[2];
- enum DPDK_HELPER_STATUS helper_status;
- enum DPDK_HELPER_ACTION helper_action;
- /* xstats info */
- uint32_t num_ports;
- uint32_t num_xstats;
+struct dpdk_stats_ctx_s {
+ dpdk_stats_config_t config;
+ uint32_t stats_count;
+ uint32_t ports_count;
cdtime_t port_read_time[RTE_MAX_ETHPORTS];
- uint32_t num_stats_in_port[RTE_MAX_ETHPORTS];
- struct rte_eth_link link_status[RTE_MAX_ETHPORTS];
+ uint32_t port_stats_count[RTE_MAX_ETHPORTS];
#if RTE_VERSION < RTE_VERSION_16_07
struct rte_eth_xstats *xstats;
#else
struct rte_eth_xstat *xstats;
struct rte_eth_xstat_name *xnames;
#endif
- char *raw_data;
- /* rte_eth_xstats from here on until the end of the SHM */
+ char raw_data[];
};
-typedef struct dpdk_config_s dpdk_config_t;
-
-static int g_configured;
-static dpdk_config_t *g_configuration;
-
-static void dpdk_config_init_default(void);
-static int dpdk_config(oconfig_item_t *ci);
-static int dpdk_helper_init_eal(void);
-static int dpdk_helper_run(void);
-static int dpdk_helper_spawn(enum DPDK_HELPER_ACTION action);
-static int dpdk_init(void);
-static int dpdk_read(user_data_t *ud);
-static int dpdk_shm_cleanup(void);
-static int dpdk_shm_init(size_t size);
-
-/* Write the default configuration to the g_configuration instances */
-static void dpdk_config_init_default(void) {
- g_configuration->interval = plugin_get_interval();
- if (g_configuration->interval == cf_get_default_interval())
- WARNING("dpdkstat: No time interval was configured, default value %" PRIu64
- " ms is set",
- CDTIME_T_TO_MS(g_configuration->interval));
- /* Default is all ports enabled */
- g_configuration->enabled_port_mask = ~0;
- g_configuration->eal_argc = DPDK_MAX_ARGC;
- g_configuration->eal_initialized = 0;
- ssnprintf(g_configuration->coremask, DATA_MAX_NAME_LEN, "%s", "0xf");
- ssnprintf(g_configuration->memory_channels, DATA_MAX_NAME_LEN, "%s", "1");
- ssnprintf(g_configuration->process_type, DATA_MAX_NAME_LEN, "%s",
- "secondary");
- ssnprintf(g_configuration->file_prefix, DATA_MAX_NAME_LEN, "%s",
- DPDK_DEFAULT_RTE_CONFIG);
-
- for (int i = 0; i < RTE_MAX_ETHPORTS; i++)
- g_configuration->port_name[i][0] = 0;
+typedef struct dpdk_stats_ctx_s dpdk_stats_ctx_t;
+
+typedef enum {
+ DPDK_STAT_STATE_OKAY = 0,
+ DPDK_STAT_STATE_CFG_ERR,
+} dpdk_stat_cfg_status;
+
+#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 dpdk_stat_cfg_status g_state = DPDK_STAT_STATE_OKAY;
+
+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;
+ }
+
+ 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) {
+ g_state = DPDK_STAT_STATE_CFG_ERR;
+ return 0;
}
- /* Set defaults for config, overwritten by loop if config item exists */
- dpdk_config_init_default();
+ 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)
+ ret = cf_util_get_int(child, (int *)&ctx->config.enabled_port_mask);
+ else if (strcasecmp("SharedMemObj", child->key) == 0) {
+ ret = cf_util_get_string_buffer(child, g_shm_name, sizeof(g_shm_name));
+ if (ret == 0)
+ ret = dpdk_stats_reinit_helper();
+ } else if (strcasecmp("EAL", child->key) == 0)
+ ret = dpdk_helper_eal_config_parse(g_hc, child);
+ else if (strcasecmp("PortName", child->key) != 0) {
+ ERROR(DPDK_STATS_PLUGIN ": unrecognized configuration option %s",
+ child->key);
+ ret = -1;
}
- } /* End for (int i = 0; i < ci->children_num; i++)*/
- g_configured = 1; /* Bypass configuration in dpdk_shm_init(). */
- return 0;
-}
+ if (ret != 0) {
+ g_state = DPDK_STAT_STATE_CFG_ERR;
+ return 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;
+ DEBUG(DPDK_STATS_PLUGIN ": Enabled Port Mask 0x%X",
+ ctx->config.enabled_port_mask);
+ DEBUG(DPDK_STATS_PLUGIN ": Shared memory object %s", g_shm_name);
- char errbuf[ERR_BUF_SIZE];
+ int port_num = 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;
- }
+ /* parse port names after EnabledPortMask was parsed */
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *child = ci->children + i;
- g_configuration->xstats = NULL;
+ if (strcasecmp("PortName", child->key) == 0) {
- return 0;
+ while (!(ctx->config.enabled_port_mask & (1 << port_num)))
+ 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;
-}
+ if (cf_util_get_string_buffer(child, ctx->config.port_name[port_num],
+ sizeof(ctx->config.port_name[port_num]))) {
+ g_state = DPDK_STAT_STATE_CFG_ERR;
+ return 0;
+ }
-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;
+ DEBUG(DPDK_STATS_PLUGIN ": Port %d Name: %s", port_num,
+ ctx->config.port_name[port_num]);
+
+ port_num++;
+ }
}
- /* 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_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;
- }
+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);
- /* If the XML config() function has been run, dont re-initialize defaults */
- if (!g_configured) {
- dpdk_config_init_default();
- }
+ /* get stats from DPDK */
+ for (uint8_t i = 0; i < ctx->ports_count; i++) {
+ if (!(ctx->config.enabled_port_mask & (1 << i)))
+ continue;
- return 0;
-}
+ ctx->port_read_time[i] = cdtime();
+ /* Store available stats array length for port */
+ len = ctx->port_stats_count[i];
-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)));
+ 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_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;
- }
+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;
- 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_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc);
+ ctx->ports_count = ports;
- 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;
+ 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;
}
- return 0;
+
+ DPDK_CHILD_LOG("%s:%s:%d stats_count=%d\n", DPDK_STATS_PLUGIN, __FUNCTION__,
+ __LINE__, stats_count);
+
+ 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.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) {
+ snprintf(dev_name, sizeof(dev_name), "%s", ctx->config.port_name[i]);
+ } else {
+ snprintf(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));
- }
+ dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(g_hc);
- } 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));
- }
+ size_t data_size = sizeof(dpdk_stats_ctx_t) +
+ (ctx->stats_count * DPDK_STATS_CTX_GET_XSTAT_SIZE);
- sstrncpy(vl.type_instance, counter_name, sizeof(vl.type_instance));
- plugin_dispatch_values(&vl);
- }
-}
+ DEBUG("%s:%d helper reinit (new_size=%zu)", __FUNCTION__, __LINE__,
+ data_size);
-static int dpdk_read(user_data_t *ud) {
- int ret = 0;
+ dpdk_stats_ctx_t tmp_ctx;
+ dpdk_eal_config_t tmp_eal;
- /*
- * 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();
- }
-
- /*
- * 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);
- return ret;
- }
+static int dpdk_stats_shutdown(void) {
+ DPDK_STATS_TRACE();
+
+ dpdk_helper_shutdown(g_hc);
+ g_hc = NULL;
+
return 0;
}
-static int dpdk_shutdown(void) {
+static int dpdk_stats_init(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;
+
+ if (g_state != DPDK_STAT_STATE_OKAY) {
+ dpdk_stats_shutdown();
+ return -1;
}
- err = dpdk_shm_cleanup();
- if (err) {
- ERROR("dpdkstat: error cleaning up SHM: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
- ret = -1;
+
+ ret = dpdk_stats_preinit();
+ if (ret != 0) {
+ return ret;
}
- return ret;
+ return 0;
}
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);
}
};
static size_t drbd_names_num = STATIC_ARRAY_SIZE(drbd_names);
-static int drbd_init(void) { return (0); }
+static int drbd_init(void) { return 0; }
static int drbd_submit_fields(long int resource, char **fields,
size_t fields_num) {
if (resource < 0) {
WARNING("drbd plugin: Unable to parse resource");
- return (EINVAL);
+ return EINVAL;
}
if (fields_num != drbd_names_num) {
WARNING("drbd plugin: Wrong number of fields for "
"r%ld statistics. Expected %zu, got %zu.",
resource, drbd_names_num, fields_num);
- return (EINVAL);
+ return EINVAL;
}
- ssnprintf(plugin_instance, sizeof(plugin_instance), "r%ld", resource);
+ snprintf(plugin_instance, sizeof(plugin_instance), "r%ld", resource);
for (size_t i = 0; i < drbd_names_num; i++) {
char *data;
continue;
data = strchr(fields[i], ':');
if (data == NULL)
- return (EINVAL);
+ return EINVAL;
(void)parse_value(++data, &values[i], DS_TYPE_DERIVE);
}
plugin_dispatch_values(&vl);
}
- return (0);
+ return 0;
} /* drbd_submit_fields */
static int drbd_read(void) {
fh = fopen(drbd_stats, "r");
if (fh == NULL) {
WARNING("drbd plugin: Unable to open %s", drbd_stats);
- return (EINVAL);
+ return EINVAL;
}
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
} /* while (fgets) */
fclose(fh);
- return (0);
+ return 0;
} /* void drbd_read */
void module_register(void) {
* Private functions
*/
static int email_config(const char *key, const char *value) {
- if (0 == strcasecmp(key, "SocketFile")) {
- if (NULL != sock_file)
+ if (strcasecmp(key, "SocketFile") == 0) {
+ if (sock_file != NULL)
free(sock_file);
sock_file = sstrdup(value);
- } else if (0 == strcasecmp(key, "SocketGroup")) {
- if (NULL != sock_group)
+ } else if (strcasecmp(key, "SocketGroup") == 0) {
+ if (sock_group != NULL)
free(sock_group);
sock_group = sstrdup(value);
- } else if (0 == strcasecmp(key, "SocketPerms")) {
+ } else if (strcasecmp(key, "SocketPerms") == 0) {
/* the user is responsible for providing reasonable values */
sock_perms = (int)strtol(value, NULL, 8);
- } else if (0 == strcasecmp(key, "MaxConns")) {
+ } else if (strcasecmp(key, "MaxConns") == 0) {
long int tmp = strtol(value, NULL, 0);
if (tmp < 1) {
/* Increment the value of the given name in the given list by incr. */
static void type_list_incr(type_list_t *list, char *name, int incr) {
- if (NULL == list->head) {
+ if (list->head == NULL) {
list->head = smalloc(sizeof(*list->head));
list->head->name = sstrdup(name);
type_t *ptr;
for (ptr = list->head; NULL != ptr; ptr = ptr->next) {
- if (0 == strcmp(name, ptr->name))
+ if (strcmp(name, ptr->name) == 0)
break;
}
- if (NULL == ptr) {
+ if (ptr == NULL) {
list->tail->next = smalloc(sizeof(*list->tail->next));
list->tail = list->tail->next;
pthread_mutex_lock(&conns_mutex);
- while (NULL == conns.head) {
+ while (conns.head == NULL) {
pthread_cond_wait(&conn_available, &conns_mutex);
}
connection = conns.head;
conns.head = conns.head->next;
- if (NULL == conns.head) {
+ if (conns.head == NULL) {
conns.tail = NULL;
}
int len = 0;
errno = 0;
- if (NULL == fgets(line, sizeof(line), this->socket)) {
- if (0 != errno) {
+ if (fgets(line, sizeof(line), this->socket) == NULL) {
+ if (errno != 0) {
char errbuf[1024];
log_err("collect: reading from socket (fd #%i) "
"failed: %s",
}
len = strlen(line);
- if (('\n' != line[len - 1]) && ('\r' != line[len - 1])) {
+ if ((line[len - 1] != '\n') && (line[len - 1] != '\r')) {
log_warn("collect: line too long (> %zu characters): "
"'%s' (truncated)",
sizeof(line) - 1, line);
- while (NULL != fgets(line, sizeof(line), this->socket))
- if (('\n' == line[len - 1]) || ('\r' == line[len - 1]))
+ while (fgets(line, sizeof(line), this->socket) != NULL)
+ if ((line[len - 1] == '\n') || (line[len - 1] == '\r'))
break;
continue;
}
log_debug("collect: line = '%s'", line);
- if (':' != line[1]) {
+ if (line[1] != ':') {
log_err("collect: syntax error in line '%s'", line);
continue;
}
- if ('e' == line[0]) { /* e:<type>:<bytes> */
+ if (line[0] == 'e') { /* e:<type>:<bytes> */
char *ptr = NULL;
char *type = strtok_r(line + 2, ":", &ptr);
char *tmp = strtok_r(NULL, ":", &ptr);
int bytes = 0;
- if (NULL == tmp) {
+ if (tmp == NULL) {
log_err("collect: syntax error in line '%s'", line);
continue;
}
type_list_incr(&list_size, type, /* increment = */ bytes);
pthread_mutex_unlock(&size_mutex);
}
- } else if ('s' == line[0]) { /* s:<value> */
+ } else if (line[0] == 's') { /* s:<value> */
pthread_mutex_lock(&score_mutex);
score = (score * (double)score_count + atof(line + 2)) /
(double)(score_count + 1);
++score_count;
pthread_mutex_unlock(&score_mutex);
- } else if ('c' == line[0]) { /* c:<type1>[,<type2>,...] */
+ } else if (line[0] == 'c') { /* c:<type1>[,<type2>,...] */
char *dummy = line + 2;
char *endptr = NULL;
char *type;
} /* while (1) */
pthread_exit((void *)0);
- return ((void *)0);
+ return (void *)0;
} /* static void *collect (void *) */
static void *open_connection(void __attribute__((unused)) * arg) {
/* create UNIX socket */
errno = 0;
- if (-1 == (connector_socket = socket(PF_UNIX, SOCK_STREAM, 0))) {
+ if ((connector_socket = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
char errbuf[1024];
disabled = 1;
log_err("socket() failed: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
sstrncpy(addr.sun_path, path, (size_t)(UNIX_PATH_MAX - 1));
errno = 0;
- if (-1 ==
- bind(connector_socket, (struct sockaddr *)&addr,
- offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path))) {
+ if (bind(connector_socket, (struct sockaddr *)&addr,
+ offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path)) == -1) {
char errbuf[1024];
disabled = 1;
close(connector_socket);
}
errno = 0;
- if (-1 == listen(connector_socket, 5)) {
+ if (listen(connector_socket, 5) == -1) {
char errbuf[1024];
disabled = 1;
close(connector_socket);
}
errno = 0;
- if (0 != chmod(path, sock_perms)) {
+ if (chmod(path, sock_perms) != 0) {
char errbuf[1024];
log_warn("chmod() failed: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
}
pthread_mutex_lock(&available_mutex);
- while (0 == available_collectors) {
+ while (available_collectors == 0) {
pthread_cond_wait(&collector_available, &available_mutex);
}
connection->socket = fdopen(remote, "r");
connection->next = NULL;
- if (NULL == connection->socket) {
+ if (connection->socket == NULL) {
close(remote);
sfree(connection);
continue;
pthread_mutex_lock(&conns_mutex);
- if (NULL == conns.head) {
+ if (conns.head == NULL) {
conns.head = connection;
conns.tail = connection;
} else {
}
pthread_exit((void *)0);
- return ((void *)0);
+ return (void *)0;
} /* static void *open_connection (void *) */
static int email_init(void) {
disabled = 1;
log_err("plugin_thread_create() failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int email_init */
static void type_list_free(type_list_t *t) {
type_list_free(&list_check);
type_list_free(&list_check_copy);
- unlink((NULL == sock_file) ? SOCK_PATH : sock_file);
+ unlink((sock_file == NULL) ? SOCK_PATH : sock_file);
sfree(sock_file);
sfree(sock_group);
- return (0);
+ return 0;
} /* static void email_shutdown (void) */
static void email_submit(const char *type, const char *type_instance,
static void copy_type_list(type_list_t *l1, type_list_t *l2) {
type_t *last = NULL;
- for (type_t *ptr1 = l1->head, *ptr2 = l2->head; NULL != ptr1;
+ for (type_t *ptr1 = l1->head, *ptr2 = l2->head; ptr1 != NULL;
ptr1 = ptr1->next, last = ptr2, ptr2 = ptr2->next) {
- if (NULL == ptr2) {
+ if (ptr2 == NULL) {
ptr2 = smalloc(sizeof(*ptr2));
ptr2->name = NULL;
ptr2->next = NULL;
- if (NULL == last) {
+ if (last == NULL) {
l2->head = ptr2;
} else {
last->next = ptr2;
l2->tail = ptr2;
}
- if (NULL == ptr2->name) {
+ if (ptr2->name == NULL) {
ptr2->name = sstrdup(ptr1->name);
}
int score_count_old;
if (disabled)
- return (-1);
+ return -1;
/* email count */
pthread_mutex_lock(&count_mutex);
pthread_mutex_unlock(&count_mutex);
- for (type_t *ptr = list_count_copy.head; NULL != ptr; ptr = ptr->next) {
+ for (type_t *ptr = list_count_copy.head; ptr != NULL; ptr = ptr->next) {
email_submit("email_count", ptr->name, ptr->value);
}
pthread_mutex_unlock(&size_mutex);
- for (type_t *ptr = list_size_copy.head; NULL != ptr; ptr = ptr->next) {
+ for (type_t *ptr = list_size_copy.head; ptr != NULL; ptr = ptr->next) {
email_submit("email_size", ptr->name, ptr->value);
}
pthread_mutex_unlock(&check_mutex);
- for (type_t *ptr = list_check_copy.head; NULL != ptr; ptr = ptr->next)
+ for (type_t *ptr = list_check_copy.head; ptr != NULL; ptr = ptr->next)
email_submit("spam_check", ptr->name, ptr->value);
- return (0);
+ return 0;
} /* int email_read */
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 : */
value_t v;
if (parse_value_file(ENTROPY_FILE, &v, DS_TYPE_GAUGE) != 0) {
ERROR("entropy plugin: Reading \"" ENTROPY_FILE "\" failed.");
- return (-1);
+ return -1;
}
entropy_submit(v);
- return (0);
+ return 0;
}
void module_register(void) {
tmp = realloc(interfaces, sizeof(*interfaces) * (interfaces_num + 1));
if (tmp == NULL)
- return (-1);
+ return -1;
interfaces = tmp;
interfaces[interfaces_num] = NULL;
status = cf_util_get_string(ci, interfaces + interfaces_num);
if (status != 0)
- return (status);
+ return status;
interfaces_num++;
INFO("ethstat plugin: Registered interface %s",
interfaces[interfaces_num - 1]);
- return (0);
+ return 0;
} /* }}} int ethstat_add_interface */
static int ethstat_add_map(const oconfig_item_t *ci) /* {{{ */
ERROR("ethstat plugin: The %s option requires "
"two or three string arguments.",
ci->key);
- return (-1);
+ return -1;
}
key = strdup(ci->values[0].value.string);
if (key == NULL) {
ERROR("ethstat plugin: strdup(3) failed.");
- return (ENOMEM);
+ return ENOMEM;
}
map = calloc(1, sizeof(*map));
if (map == NULL) {
sfree(key);
ERROR("ethstat plugin: calloc failed.");
- return (ENOMEM);
+ return ENOMEM;
}
sstrncpy(map->type, ci->values[1].value.string, sizeof(map->type));
sfree(map);
sfree(key);
ERROR("ethstat plugin: c_avl_create() failed.");
- return (-1);
+ return -1;
}
}
sfree(map);
sfree(key);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int ethstat_add_map */
static int ethstat_config(oconfig_item_t *ci) /* {{{ */
child->key);
}
- return (0);
+ return 0;
} /* }}} */
static void ethstat_submit_value(const char *device, const char *type_instance,
ERROR("ethstat plugin: Failed to get driver information "
"from %s: %s",
device, sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
n_stats = (size_t)drvinfo.n_stats;
if (n_stats < 1) {
close(fd);
ERROR("ethstat plugin: No stats available for %s", device);
- return (-1);
+ return -1;
}
strings_size = sizeof(struct ethtool_gstrings) + (n_stats * ETH_GSTRING_LEN);
sfree(strings);
sfree(stats);
ERROR("ethstat plugin: malloc failed.");
- return (-1);
+ return -1;
}
strings->cmd = ETHTOOL_GSTRINGS;
free(stats);
ERROR("ethstat plugin: Cannot get strings from %s: %s", device,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
stats->cmd = ETHTOOL_GSTATS;
free(stats);
ERROR("ethstat plugin: Reading statistics from %s failed: %s", device,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
for (size_t i = 0; i < n_stats; i++) {
sfree(strings);
sfree(stats);
- return (0);
+ return 0;
} /* }}} ethstat_read_interface */
static int ethstat_read(void) {
void *value = NULL;
if (value_map == NULL)
- return (0);
+ return 0;
while (c_avl_pick(value_map, &key, &value) == 0) {
sfree(key);
c_avl_destroy(value_map);
value_map = NULL;
- return (0);
+ return 0;
}
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 : */
if (ci->children_num != 0) {
WARNING("exec plugin: The config option `%s' may not be a block.", ci->key);
- return (-1);
+ return -1;
}
if (ci->values_num < 2) {
WARNING("exec plugin: The config option `%s' needs at least two "
"arguments.",
ci->key);
- return (-1);
+ return -1;
}
if ((ci->values[0].type != OCONFIG_TYPE_STRING) ||
(ci->values[1].type != OCONFIG_TYPE_STRING)) {
WARNING("exec plugin: The first two arguments to the `%s' option must "
"be string arguments.",
ci->key);
- return (-1);
+ return -1;
}
pl = calloc(1, sizeof(*pl));
if (pl == NULL) {
ERROR("exec plugin: calloc failed.");
- return (-1);
+ return -1;
}
if (strcasecmp("NotificationExec", ci->key) == 0)
if (pl->user == NULL) {
ERROR("exec plugin: strdup failed.");
sfree(pl);
- return (-1);
+ return -1;
}
pl->group = strchr(pl->user, ':');
ERROR("exec plugin: strdup failed.");
sfree(pl->user);
sfree(pl);
- return (-1);
+ return -1;
}
pl->argv = calloc(ci->values_num, sizeof(*pl->argv));
sfree(pl->exec);
sfree(pl->user);
sfree(pl);
- return (-1);
+ return -1;
}
{
sfree(pl->exec);
sfree(pl->user);
sfree(pl);
- return (-1);
+ return -1;
}
for (i = 1; i < (ci->values_num - 1); i++) {
pl->argv[i] = strdup(ci->values[i + 1].value.string);
} else {
if (ci->values[i + 1].type == OCONFIG_TYPE_NUMBER) {
- ssnprintf(buffer, sizeof(buffer), "%lf",
- ci->values[i + 1].value.number);
+ snprintf(buffer, sizeof(buffer), "%lf", ci->values[i + 1].value.number);
} else {
if (ci->values[i + 1].value.boolean)
sstrncpy(buffer, "true", sizeof(buffer));
sfree(pl->exec);
sfree(pl->user);
sfree(pl);
- return (-1);
+ return -1;
}
for (i = 0; pl->argv[i] != NULL; i++) {
pl->next = pl_head;
pl_head = pl;
- return (0);
+ return 0;
} /* int exec_config_exec }}} */
static int exec_config(oconfig_item_t *ci) /* {{{ */
}
} /* for (i) */
- return (0);
+ return 0;
} /* int exec_config }}} */
static void set_environment(void) /* {{{ */
char buffer[1024];
#ifdef HAVE_SETENV
- ssnprintf(buffer, sizeof(buffer), "%.3f",
- CDTIME_T_TO_DOUBLE(plugin_get_interval()));
+ snprintf(buffer, sizeof(buffer), "%.3f",
+ CDTIME_T_TO_DOUBLE(plugin_get_interval()));
setenv("COLLECTD_INTERVAL", buffer, /* overwrite = */ 1);
sstrncpy(buffer, hostname_g, sizeof(buffer));
setenv("COLLECTD_HOSTNAME", buffer, /* overwrite = */ 1);
#else
- ssnprintf(buffer, sizeof(buffer), "COLLECTD_INTERVAL=%.3f",
- CDTIME_T_TO_DOUBLE(plugin_get_interval()));
+ snprintf(buffer, sizeof(buffer), "COLLECTD_INTERVAL=%.3f",
+ CDTIME_T_TO_DOUBLE(plugin_get_interval()));
putenv(buffer);
- ssnprintf(buffer, sizeof(buffer), "COLLECTD_HOSTNAME=%s", hostname_g);
+ snprintf(buffer, sizeof(buffer), "COLLECTD_HOSTNAME=%s", hostname_g);
putenv(buffer);
#endif
} /* }}} void set_environment */
if (status != 0) {
ERROR("exec plugin: pipe failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
return 0;
struct passwd sp;
if (pl->pid != 0)
- return (-1);
+ return -1;
long int nambuf_size = sysconf(_SC_GETPW_R_SIZE_MAX);
if (nambuf_size <= 0)
/* The group configured in the configfile is set as effective group, because
* this way the forked process can (re-)gain the user's primary group. */
egid = -1;
- if (NULL != pl->group) {
- if ('\0' != *pl->group) {
+ if (pl->group != NULL) {
+ if (*pl->group != '\0') {
struct group *gr_ptr = NULL;
struct group gr;
char grbuf[grbuf_size];
status = getgrnam_r(pl->group, &gr, grbuf, sizeof(grbuf), &gr_ptr);
- if (0 != status) {
+ if (status != 0) {
ERROR("exec plugin: Failed to get group information "
"for group ``%s'': %s",
pl->group, sstrerror(status, errbuf, sizeof(errbuf)));
goto failed;
}
- if (NULL == gr_ptr) {
+ if (gr_ptr == NULL) {
ERROR("exec plugin: No such group: `%s'", pl->group);
goto failed;
}
else
close(fd_pipe_err[0]);
- return (pid);
+ return pid;
failed:
close_pipe(fd_pipe_in);
close_pipe(fd_pipe_out);
close_pipe(fd_pipe_err);
- return (-1);
+ return -1;
} /* int fork_child }}} */
static int parse_line(char *buffer) /* {{{ */
{
if (strncasecmp("PUTVAL", buffer, strlen("PUTVAL")) == 0)
- return (cmd_handle_putval(stdout, buffer));
+ return cmd_handle_putval(stdout, buffer);
else if (strncasecmp("PUTNOTIF", buffer, strlen("PUTNOTIF")) == 0)
- return (handle_putnotif(stdout, buffer));
+ return handle_putnotif(stdout, buffer);
else {
ERROR("exec plugin: Unable to parse command, ignoring line: \"%s\"",
buffer);
- return (-1);
+ return -1;
}
} /* int parse_line }}} */
close(fd_err);
pthread_exit((void *)0);
- return (NULL);
+ return NULL;
} /* void *exec_read_one }}} */
static void *exec_notification_one(void *arg) /* {{{ */
n->meta = NULL;
sfree(arg);
pthread_exit((void *)0);
- return (NULL);
+ return NULL;
} /* void *exec_notification_one }}} */
static int exec_init(void) /* {{{ */
}
#endif
- return (0);
+ return 0;
} /* int exec_init }}} */
static int exec_read(void) /* {{{ */
pthread_attr_destroy(&attr);
} /* for (pl) */
- return (0);
+ return 0;
} /* int exec_read }}} */
static int exec_notification(const notification_t *n, /* {{{ */
pthread_attr_destroy(&attr);
} /* for (pl) */
- return (0);
+ return 0;
} /* }}} int exec_notification */
static int exec_shutdown(void) /* {{{ */
} /* while (pl) */
pl_head = NULL;
- return (0);
+ return 0;
} /* int exec_shutdown }}} */
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
- */
ret = 0;
}
- return (ret);
+ return ret;
}
static void fhcount_submit(const char *type, const char *type_instance,
fp = fopen("/proc/sys/fs/file-nr", "r");
if (fp == NULL) {
ERROR("fhcount: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (EXIT_FAILURE);
+ return EXIT_FAILURE;
}
if (fgets(buffer, buffer_len, fp) == NULL) {
ERROR("fhcount: fgets: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
fclose(fp);
- return (EXIT_FAILURE);
+ return EXIT_FAILURE;
}
fclose(fp);
if (numfields != 3) {
ERROR("fhcount: Line doesn't contain 3 fields");
- return (EXIT_FAILURE);
+ return EXIT_FAILURE;
}
// Define the values
fhcount_submit("percent", "unused", (gauge_t)prc_unused);
}
- return (0);
+ return 0;
}
void module_register(void) {
#define FC_RECURSIVE 1
#define FC_HIDDEN 2
+#define FC_REGULAR 4
struct fc_directory_conf_s {
char *path;
+ char *plugin_name;
char *instance;
+ char *files_size_type;
+ char *files_num_type;
+ char *type_instance;
int options;
static fc_directory_conf_t **directories = NULL;
static size_t directories_num = 0;
+void fc_free_dir(fc_directory_conf_t *dir) {
+ sfree(dir->path);
+ sfree(dir->plugin_name);
+ sfree(dir->instance);
+ sfree(dir->files_size_type);
+ sfree(dir->files_num_type);
+ sfree(dir->type_instance);
+ sfree(dir->name);
+
+ sfree(dir);
+} /* void fc_free_dir */
+
static void fc_submit_dir(const fc_directory_conf_t *dir) {
value_list_t vl = VALUE_LIST_INIT;
- vl.values = &(value_t){.gauge = (gauge_t)dir->files_num};
- vl.values_len = 1;
- sstrncpy(vl.plugin, "filecount", sizeof(vl.plugin));
- sstrncpy(vl.plugin_instance, dir->instance, sizeof(vl.plugin_instance));
- sstrncpy(vl.type, "files", sizeof(vl.type));
+ sstrncpy(vl.plugin, dir->plugin_name, sizeof(vl.plugin));
+ if (dir->instance != NULL)
+ sstrncpy(vl.plugin_instance, dir->instance, sizeof(vl.plugin_instance));
+ if (dir->type_instance != NULL)
+ sstrncpy(vl.type_instance, dir->type_instance, sizeof(vl.type_instance));
- plugin_dispatch_values(&vl);
+ vl.values_len = 1;
- vl.values = &(value_t){.gauge = (gauge_t)dir->files_size};
- sstrncpy(vl.type, "bytes", sizeof(vl.type));
+ if (dir->files_num_type != NULL) {
+ vl.values = &(value_t){.gauge = (gauge_t)dir->files_num};
+ sstrncpy(vl.type, dir->files_num_type, sizeof(vl.type));
+ plugin_dispatch_values(&vl);
+ }
- plugin_dispatch_values(&vl);
+ if (dir->files_size_type != NULL) {
+ vl.values = &(value_t){.gauge = (gauge_t)dir->files_size};
+ sstrncpy(vl.type, dir->files_size_type, sizeof(vl.type));
+ plugin_dispatch_values(&vl);
+ }
} /* void fc_submit_dir */
/*
* Config:
* <Plugin filecount>
* <Directory /path/to/dir>
+ * Plugin "foo"
* Instance "foobar"
* Name "*.conf"
* MTime -3600
* Size "+10M"
+ * Recursive true
+ * IncludeHidden false
+ * FilesSizeType "bytes"
+ * FilesCountType "files"
+ * TypeInstance "instance"
* </Directory>
* </Plugin>
*
static int fc_config_set_instance(fc_directory_conf_t *dir, const char *str) {
char buffer[1024];
char *ptr;
- char *copy;
sstrncpy(buffer, str, sizeof(buffer));
for (ptr = buffer; *ptr != 0; ptr++)
for (ptr = buffer; *ptr == '_'; ptr++)
/* do nothing */;
- if (*ptr == 0)
- return (-1);
-
- copy = strdup(ptr);
+ char *copy = strdup(ptr);
if (copy == NULL)
- return (-1);
+ return -1;
sfree(dir->instance);
dir->instance = copy;
- return (0);
+ return 0;
} /* int fc_config_set_instance */
static int fc_config_add_dir_instance(fc_directory_conf_t *dir,
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("filecount plugin: The `Instance' config option needs exactly "
"one string argument.");
- return (-1);
+ return -1;
}
- return (fc_config_set_instance(dir, ci->values[0].value.string));
+ return fc_config_set_instance(dir, ci->values[0].value.string);
} /* int fc_config_add_dir_instance */
static int fc_config_add_dir_name(fc_directory_conf_t *dir,
oconfig_item_t *ci) {
- char *temp;
-
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("filecount plugin: The `Name' config option needs exactly one "
"string argument.");
- return (-1);
+ return -1;
}
- temp = strdup(ci->values[0].value.string);
+ char *temp = strdup(ci->values[0].value.string);
if (temp == NULL) {
ERROR("filecount plugin: strdup failed.");
- return (-1);
+ return -1;
}
sfree(dir->name);
dir->name = temp;
- return (0);
+ return 0;
} /* int fc_config_add_dir_name */
static int fc_config_add_dir_mtime(fc_directory_conf_t *dir,
oconfig_item_t *ci) {
- char *endptr;
- double temp;
-
if ((ci->values_num != 1) || ((ci->values[0].type != OCONFIG_TYPE_STRING) &&
(ci->values[0].type != OCONFIG_TYPE_NUMBER))) {
WARNING("filecount plugin: The `MTime' config option needs exactly one "
"string or numeric argument.");
- return (-1);
+ return -1;
}
if (ci->values[0].type == OCONFIG_TYPE_NUMBER) {
dir->mtime = (int64_t)ci->values[0].value.number;
- return (0);
+ return 0;
}
errno = 0;
- endptr = NULL;
- temp = strtod(ci->values[0].value.string, &endptr);
+ char *endptr = NULL;
+ double temp = strtod(ci->values[0].value.string, &endptr);
if ((errno != 0) || (endptr == NULL) ||
(endptr == ci->values[0].value.string)) {
WARNING("filecount plugin: Converting `%s' to a number failed.",
ci->values[0].value.string);
- return (-1);
+ return -1;
}
switch (*endptr) {
default:
WARNING("filecount plugin: Invalid suffix for `MTime': `%c'", *endptr);
- return (-1);
+ return -1;
} /* switch (*endptr) */
dir->mtime = (int64_t)temp;
- return (0);
+ return 0;
} /* int fc_config_add_dir_mtime */
static int fc_config_add_dir_size(fc_directory_conf_t *dir,
oconfig_item_t *ci) {
- char *endptr;
- double temp;
-
if ((ci->values_num != 1) || ((ci->values[0].type != OCONFIG_TYPE_STRING) &&
(ci->values[0].type != OCONFIG_TYPE_NUMBER))) {
WARNING("filecount plugin: The `Size' config option needs exactly one "
"string or numeric argument.");
- return (-1);
+ return -1;
}
if (ci->values[0].type == OCONFIG_TYPE_NUMBER) {
dir->size = (int64_t)ci->values[0].value.number;
- return (0);
+ return 0;
}
errno = 0;
- endptr = NULL;
- temp = strtod(ci->values[0].value.string, &endptr);
+ char *endptr = NULL;
+ double temp = strtod(ci->values[0].value.string, &endptr);
if ((errno != 0) || (endptr == NULL) ||
(endptr == ci->values[0].value.string)) {
WARNING("filecount plugin: Converting `%s' to a number failed.",
ci->values[0].value.string);
- return (-1);
+ return -1;
}
switch (*endptr) {
default:
WARNING("filecount plugin: Invalid suffix for `Size': `%c'", *endptr);
- return (-1);
+ return -1;
} /* switch (*endptr) */
dir->size = (int64_t)temp;
- return (0);
+ return 0;
} /* int fc_config_add_dir_size */
static int fc_config_add_dir_option(fc_directory_conf_t *dir,
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) {
WARNING("filecount plugin: The `Recursive' config options needs exactly "
"one boolean argument.");
- return (-1);
+ return -1;
}
if (ci->values[0].value.boolean)
else
dir->options &= ~bit;
- return (0);
+ return 0;
} /* int fc_config_add_dir_option */
static int fc_config_add_dir(oconfig_item_t *ci) {
- fc_directory_conf_t *dir;
- int status;
-
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("filecount plugin: `Directory' needs exactly one string "
"argument.");
- return (-1);
+ return -1;
}
/* Initialize `dir' */
- dir = calloc(1, sizeof(*dir));
+ fc_directory_conf_t *dir = calloc(1, sizeof(*dir));
if (dir == NULL) {
ERROR("filecount plugin: calloc failed.");
- return (-1);
+ return -1;
}
dir->path = strdup(ci->values[0].value.string);
if (dir->path == NULL) {
ERROR("filecount plugin: strdup failed.");
- sfree(dir);
- return (-1);
+ fc_free_dir(dir);
+ return -1;
}
- fc_config_set_instance(dir, dir->path);
-
- dir->options = FC_RECURSIVE;
+ dir->options = FC_RECURSIVE | FC_REGULAR;
dir->name = NULL;
+ dir->plugin_name = strdup("filecount");
+ dir->instance = NULL;
+ dir->type_instance = NULL;
dir->mtime = 0;
dir->size = 0;
- status = 0;
+ dir->files_size_type = strdup("bytes");
+ dir->files_num_type = strdup("files");
+
+ if (dir->plugin_name == NULL || dir->files_size_type == NULL ||
+ dir->files_num_type == NULL) {
+ ERROR("filecount plugin: strdup failed.");
+ fc_free_dir(dir);
+ return -1;
+ }
+
+ int status = 0;
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *option = ci->children + i;
- if (strcasecmp("Instance", option->key) == 0)
+ if (strcasecmp("Plugin", option->key) == 0)
+ status = cf_util_get_string(option, &dir->plugin_name);
+ else if (strcasecmp("Instance", option->key) == 0)
status = fc_config_add_dir_instance(dir, option);
else if (strcasecmp("Name", option->key) == 0)
status = fc_config_add_dir_name(dir, option);
status = fc_config_add_dir_option(dir, option, FC_RECURSIVE);
else if (strcasecmp("IncludeHidden", option->key) == 0)
status = fc_config_add_dir_option(dir, option, FC_HIDDEN);
+ else if (strcasecmp("RegularOnly", option->key) == 0)
+ status = fc_config_add_dir_option(dir, option, FC_REGULAR);
+ else if (strcasecmp("FilesSizeType", option->key) == 0)
+ status = cf_util_get_string(option, &dir->files_size_type);
+ else if (strcasecmp("FilesCountType", option->key) == 0)
+ status = cf_util_get_string(option, &dir->files_num_type);
+ else if (strcasecmp("TypeInstance", option->key) == 0)
+ status = cf_util_get_string(option, &dir->type_instance);
else {
WARNING("filecount plugin: fc_config_add_dir: "
"Option `%s' not allowed here.",
break;
} /* for (ci->children) */
- if (status == 0) {
- fc_directory_conf_t **temp;
+ if (status != 0) {
+ fc_free_dir(dir);
+ return -1;
+ }
- temp = realloc(directories, sizeof(*directories) * (directories_num + 1));
- if (temp == NULL) {
- ERROR("filecount plugin: realloc failed.");
- status = -1;
- } else {
- directories = temp;
- directories[directories_num] = dir;
- directories_num++;
+ /* Set default plugin instance */
+ if (dir->instance == NULL) {
+ fc_config_set_instance(dir, dir->path);
+ if (dir->instance == NULL || strlen(dir->instance) == 0) {
+ ERROR("filecount plugin: failed to build plugin instance name.");
+ fc_free_dir(dir);
+ return -1;
}
}
- if (status != 0) {
- sfree(dir->name);
+ /* Handle disabled types */
+ if (strlen(dir->instance) == 0)
sfree(dir->instance);
- sfree(dir->path);
- sfree(dir);
- return (-1);
+
+ if (strlen(dir->files_size_type) == 0)
+ sfree(dir->files_size_type);
+
+ if (strlen(dir->files_num_type) == 0)
+ sfree(dir->files_num_type);
+
+ if (dir->files_size_type == NULL && dir->files_num_type == NULL) {
+ WARNING("filecount plugin: Both `FilesSizeType' and `FilesCountType ' "
+ "are disabled for '%s'. There's no types to report.",
+ dir->path);
+ fc_free_dir(dir);
+ return -1;
}
- return (0);
+ /* Ready to add it to list */
+ fc_directory_conf_t **temp =
+ realloc(directories, sizeof(*directories) * (directories_num + 1));
+ if (temp == NULL) {
+ ERROR("filecount plugin: realloc failed.");
+ fc_free_dir(dir);
+ return -1;
+ }
+
+ directories = temp;
+ directories[directories_num] = dir;
+ directories_num++;
+
+ return 0;
} /* int fc_config_add_dir */
static int fc_config(oconfig_item_t *ci) {
}
} /* for (ci->children) */
- return (0);
+ return 0;
} /* int fc_config */
static int fc_init(void) {
if (directories_num < 1) {
WARNING("filecount plugin: No directories have been configured.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int fc_init */
static int fc_read_dir_callback(const char *dirname, const char *filename,
fc_directory_conf_t *dir = user_data;
char abs_path[PATH_MAX];
struct stat statbuf;
- int status;
if (dir == NULL)
- return (-1);
+ return -1;
- ssnprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, filename);
+ snprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, filename);
- status = lstat(abs_path, &statbuf);
+ int status = lstat(abs_path, &statbuf);
if (status != 0) {
ERROR("filecount plugin: stat (%s) failed.", abs_path);
- return (-1);
+ return -1;
}
if (S_ISDIR(statbuf.st_mode) && (dir->options & FC_RECURSIVE)) {
status = walk_directory(
abs_path, fc_read_dir_callback, dir,
/* include hidden = */ (dir->options & FC_HIDDEN) ? 1 : 0);
- return (status);
- } else if (!S_ISREG(statbuf.st_mode)) {
- return (0);
+ return status;
+ } else if ((dir->options & FC_REGULAR) && !S_ISREG(statbuf.st_mode)) {
+ return 0;
}
if (dir->name != NULL) {
status = fnmatch(dir->name, filename, /* flags = */ 0);
if (status != 0)
- return (0);
+ return 0;
+ }
+
+ if (!S_ISREG(statbuf.st_mode)) {
+ dir->files_num++;
+ return 0;
}
if (dir->mtime != 0) {
if (((dir->mtime < 0) && (statbuf.st_mtime < mtime)) ||
((dir->mtime > 0) && (statbuf.st_mtime > mtime)))
- return (0);
+ return 0;
}
if (dir->size != 0) {
if (((dir->size < 0) && (statbuf.st_size > size)) ||
((dir->size > 0) && (statbuf.st_size < size)))
- return (0);
+ return 0;
}
dir->files_num++;
dir->files_size += (uint64_t)statbuf.st_size;
- return (0);
+ return 0;
} /* int fc_read_dir_callback */
static int fc_read_dir(fc_directory_conf_t *dir) {
- int status;
-
dir->files_num = 0;
dir->files_size = 0;
if (dir->mtime != 0)
dir->now = time(NULL);
- status =
+ int status =
walk_directory(dir->path, fc_read_dir_callback, dir,
/* include hidden */ (dir->options & FC_HIDDEN) ? 1 : 0);
if (status != 0) {
WARNING("filecount plugin: walk_directory (%s) failed.", dir->path);
- return (-1);
+ return -1;
}
fc_submit_dir(dir);
- return (0);
+ return 0;
} /* int fc_read_dir */
static int fc_read(void) {
for (size_t i = 0; i < directories_num; i++)
fc_read_dir(directories[i]);
- return (0);
+ return 0;
} /* int fc_read */
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 :
- */
} else {
printf("cant open file\n");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
void module_register(void) {
plugin_register_read("fscache", fscache_read);
} /* void module_register */
-
-/* vim: set sw=4 sts=4 et : */
}
if (i >= map_len)
- return (NULL);
+ return NULL;
/* Look up the DS type and ds_index. */
if (map[i].ds_type < 0) /* {{{ */
ds = plugin_get_ds(map[i].type);
if (ds == NULL) {
WARNING("gmond plugin: Type not defined: %s", map[i].type);
- return (NULL);
+ return NULL;
}
if ((map[i].ds_name == NULL) && (ds->ds_num != 1)) {
WARNING("gmond plugin: No data source name defined for metric %s, "
"but type %s has more than one data source.",
map[i].ganglia_name, map[i].type);
- return (NULL);
+ return NULL;
}
if (map[i].ds_name == NULL) {
WARNING("gmond plugin: There is no data source "
"named `%s' in type `%s'.",
map[i].ds_name, ds->type);
- return (NULL);
+ return NULL;
}
map[i].ds_index = j;
}
map[i].ds_type = ds->ds[map[i].ds_index].type;
} /* }}} if ((map[i].ds_type < 0) || (map[i].ds_index < 0)) */
- return (map + i);
+ return map + i;
} /* }}} metric_map_t *metric_lookup */
static int create_sockets(socket_entry_t **ret_sockets, /* {{{ */
int status;
if (*ret_sockets != NULL)
- return (EINVAL);
+ return EINVAL;
struct addrinfo ai_hints = {.ai_family = AF_UNSPEC,
.ai_flags = AI_ADDRCONFIG | AI_PASSIVE,
(service == NULL) ? "(null)" : service,
(ai_return == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
: gai_strerror(ai_return));
- return (-1);
+ return -1;
}
for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
if (sockets_num == 0) {
sfree(sockets);
- return (-1);
+ return -1;
}
*ret_sockets = sockets;
*ret_sockets_num = sockets_num;
- return (0);
+ return 0;
} /* }}} int create_sockets */
static int request_meta_data(const char *host, const char *name) /* {{{ */
(msg.Ganglia_metadata_msg_u.grequest.metric_id.name == NULL)) {
sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.host);
sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.name);
- return (-1);
+ return -1;
}
xdrmem_create(&xdr, buffer, sizeof(buffer), XDR_ENCODE);
if (!xdr_Ganglia_metadata_msg(&xdr, &msg)) {
sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.host);
sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.name);
- return (-1);
+ return -1;
}
buffer_size = xdr_getpos(&xdr);
sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.host);
sfree(msg.Ganglia_metadata_msg_u.grequest.metric_id.name);
- return (0);
+ return 0;
} /* }}} int request_meta_data */
static staging_entry_t *staging_entry_get(const char *host, /* {{{ */
int status;
if (staging_tree == NULL)
- return (NULL);
+ return NULL;
- ssnprintf(key, sizeof(key), "%s/%s/%s", host, type,
- (type_instance != NULL) ? type_instance : "");
+ snprintf(key, sizeof(key), "%s/%s/%s", host, type,
+ (type_instance != NULL) ? type_instance : "");
se = NULL;
status = c_avl_get(staging_tree, key, (void *)&se);
if (status == 0)
- return (se);
+ return se;
/* insert new entry */
se = calloc(1, sizeof(*se));
if (se == NULL)
- return (NULL);
+ return NULL;
sstrncpy(se->key, key, sizeof(se->key));
se->flags = 0;
se->vl.values = (value_t *)calloc(values_len, sizeof(*se->vl.values));
if (se->vl.values == NULL) {
sfree(se);
- return (NULL);
+ return NULL;
}
se->vl.values_len = values_len;
ERROR("gmond plugin: c_avl_insert failed.");
sfree(se->vl.values);
sfree(se);
- return (NULL);
+ return NULL;
}
- return (se);
+ return se;
} /* }}} staging_entry_t *staging_entry_get */
static int staging_entry_update(const char *host, const char *name, /* {{{ */
ds = plugin_get_ds(type);
if (ds == NULL) {
ERROR("gmond plugin: Looking up type %s failed.", type);
- return (-1);
+ return -1;
}
if (ds->ds_num <= ds_index) {
ERROR("gmond plugin: Invalid index %zu: %s has only %zu data source(s).",
ds_index, ds->type, ds->ds_num);
- return (-1);
+ return -1;
}
pthread_mutex_lock(&staging_lock);
if (se == NULL) {
pthread_mutex_unlock(&staging_lock);
ERROR("gmond plugin: staging_entry_get failed.");
- return (-1);
+ return -1;
}
if (se->vl.values_len != ds->ds_num) {
pthread_mutex_unlock(&staging_lock);
- return (-1);
+ return -1;
}
if (ds_type == DS_TYPE_COUNTER)
/* Check if all data sources have been set. If not, return here. */
if (se->flags != ((0x01 << se->vl.values_len) - 1)) {
pthread_mutex_unlock(&staging_lock);
- return (0);
+ return 0;
}
/* Check if the interval of this metric is known. If not, request meta data
pthread_mutex_unlock(&staging_lock);
request_meta_data(host, name);
- return (0);
+ return 0;
}
plugin_dispatch_values(&se->vl);
se->flags = 0;
pthread_mutex_unlock(&staging_lock);
- return (0);
+ return 0;
} /* }}} int staging_entry_update */
static int mc_handle_value_msg(Ganglia_value_msg *msg) /* {{{ */
}
default:
DEBUG("gmond plugin: Value type not handled: %i", msg->id);
- return (-1);
+ return -1;
} /* }}} switch (msg->id) */
assert(host != NULL);
else
assert(23 == 42);
- return (staging_entry_update(host, name, map->type, map->type_instance,
- map->ds_index, map->ds_type, val_copy));
+ return staging_entry_update(host, name, map->type, map->type_instance,
+ map->ds_index, map->ds_type, val_copy);
}
DEBUG("gmond plugin: Cannot find a translation for %s.", name);
- return (-1);
+ return -1;
} /* }}} int mc_handle_value_msg */
static int mc_handle_metadata_msg(Ganglia_metadata_msg *msg) /* {{{ */
msg_meta = msg->Ganglia_metadata_msg_u.gfull;
if (msg_meta.metric.tmax == 0)
- return (-1);
+ return -1;
map = metric_lookup(msg_meta.metric_id.name);
if (map == NULL) {
DEBUG("gmond plugin: Not handling meta data %s.",
msg_meta.metric_id.name);
- return (0);
+ return 0;
}
ds = plugin_get_ds(map->type);
if (ds == NULL) {
WARNING("gmond plugin: Could not find data set %s.", map->type);
- return (-1);
+ return -1;
}
DEBUG("gmond plugin: Received meta data for %s/%s.",
if (se == NULL) {
ERROR("gmond plugin: staging_entry_get failed.");
- return (-1);
+ return -1;
}
break;
}
- default: { return (-1); }
+ default: { return -1; }
}
- return (0);
+ return 0;
} /* }}} int mc_handle_metadata_msg */
static int mc_handle_metric(void *buffer, size_t buffer_size) /* {{{ */
default:
DEBUG("gmond plugin: Unknown format: %i", format);
- return (-1);
+ return -1;
} /* switch (format) */
- return (0);
+ return 0;
} /* }}} int mc_handle_metric */
static int mc_handle_socket(struct pollfd *p) /* {{{ */
if ((p->revents & (POLLIN | POLLPRI)) == 0) {
p->revents = 0;
- return (-1);
+ return -1;
}
buffer_size = recv(p->fd, buffer, sizeof(buffer), /* flags = */ 0);
ERROR("gmond plugin: recv failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
p->revents = 0;
- return (-1);
+ return -1;
}
mc_handle_metric(buffer, (size_t)buffer_size);
- return (0);
+ return 0;
} /* }}} int mc_handle_socket */
static void *mc_receive_thread(void *arg) /* {{{ */
/* listen = */ 1);
if (status != 0) {
ERROR("gmond plugin: create_sockets failed.");
- return ((void *)-1);
+ return (void *)-1;
}
mc_receive_sockets = (struct pollfd *)calloc(mc_receive_sockets_num,
free(mc_receive_socket_entries);
mc_receive_socket_entries = NULL;
mc_receive_sockets_num = 0;
- return ((void *)-1);
+ return (void *)-1;
}
for (size_t i = 0; i < mc_receive_sockets_num; i++) {
} /* while (mc_receive_thread_loop != 0) */
free(mc_receive_socket_entries);
- return ((void *)0);
+ return (void *)0;
} /* }}} void *mc_receive_thread */
static int mc_receive_thread_start(void) /* {{{ */
int status;
if (mc_receive_thread_running != 0)
- return (-1);
+ return -1;
mc_receive_thread_loop = 1;
if (status != 0) {
ERROR("gmond plugin: Starting receive thread failed.");
mc_receive_thread_loop = 0;
- return (-1);
+ return -1;
}
mc_receive_thread_running = 1;
- return (0);
+ return 0;
} /* }}} int start_receive_thread */
static int mc_receive_thread_stop(void) /* {{{ */
{
if (mc_receive_thread_running == 0)
- return (-1);
+ return -1;
mc_receive_thread_loop = 0;
mc_receive_thread_running = 0;
- return (0);
+ return 0;
} /* }}} int mc_receive_thread_stop */
/*
WARNING("gmond plugin: The `%s' option needs "
"exactly one string argument.",
ci->key);
- return (-1);
+ return -1;
}
tmp = strdup(ci->values[0].value.string);
if (tmp == NULL) {
ERROR("gmond plugin: strdup failed.");
- return (-1);
+ return -1;
}
sfree(*str);
*str = tmp;
- return (0);
+ return 0;
} /* }}} int gmond_config_set_string */
static int gmond_config_add_metric(oconfig_item_t *ci) /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("gmond plugin: `Metric' blocks need "
"exactly one string argument.");
- return (-1);
+ return -1;
}
map = realloc(metric_map, (metric_map_len + 1) * sizeof(*metric_map));
if (map == NULL) {
ERROR("gmond plugin: realloc failed.");
- return (-1);
+ return -1;
}
metric_map = map;
map = metric_map + metric_map_len;
map->ganglia_name = strdup(ci->values[0].value.string);
if (map->ganglia_name == NULL) {
ERROR("gmond plugin: strdup failed.");
- return (-1);
+ return -1;
}
for (int i = 0; i < ci->children_num; i++) {
ERROR("gmond plugin: No type is set for metric %s.", map->ganglia_name);
sfree(map->ganglia_name);
sfree(map->type_instance);
- return (-1);
+ return -1;
}
metric_map_len++;
- return (0);
+ return 0;
} /* }}} int gmond_config_add_metric */
static int gmond_config_set_address(oconfig_item_t *ci, /* {{{ */
WARNING("gmond plugin: The `%s' config option needs "
"one or two string arguments.",
ci->key);
- return (-1);
+ return -1;
}
if ((ci->values[0].type != OCONFIG_TYPE_STRING) ||
((ci->values_num == 2) && (ci->values[1].type != OCONFIG_TYPE_STRING))) {
WARNING("gmond plugin: The `%s' config option needs "
"one or two string arguments.",
ci->key);
- return (-1);
+ return -1;
}
addr = strdup(ci->values[0].value.string);
ERROR("gmond plugin: strdup failed.");
sfree(addr);
sfree(port);
- return (-1);
+ return -1;
}
sfree(*ret_addr);
*ret_addr = addr;
*ret_port = port;
- return (0);
+ return 0;
} /* }}} int gmond_config_set_address */
static int gmond_config(oconfig_item_t *ci) /* {{{ */
}
}
- return (0);
+ return 0;
} /* }}} int gmond_config */
static int gmond_init(void) /* {{{ */
staging_tree = c_avl_create((int (*)(const void *, const void *))strcmp);
if (staging_tree == NULL) {
ERROR("gmond plugin: c_avl_create failed.");
- return (-1);
+ return -1;
}
mc_receive_thread_start();
- return (0);
+ return 0;
} /* }}} int gmond_init */
static int gmond_shutdown(void) /* {{{ */
mc_send_sockets_num = 0;
pthread_mutex_unlock(&mc_send_sockets_lock);
- return (0);
+ return 0;
} /* }}} int gmond_shutdown */
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 : */
cgps_submit("satellites", data_copy.sats_used, "used");
cgps_submit("satellites", data_copy.sats_visible, "visible");
- return (0);
+ return 0;
}
/**
cgps_config_data.timeout = CGPS_DEFAULT_TIMEOUT;
}
- return (0);
+ return 0;
}
/**
plugin_thread_create(&cgps_thread_id, NULL, cgps_thread, NULL, "gps");
if (status != 0) {
ERROR("gps plugin: pthread_create() failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
/**
sfree(cgps_config_data.port);
sfree(cgps_config_data.host);
- return (0);
+ return 0;
}
/**
* Florian octo Forster <octo at collectd.org>
**/
-#include <grpc++/grpc++.h>
#include <google/protobuf/util/time_util.h>
+#include <grpc++/grpc++.h>
#include <fstream>
#include <iostream>
using google::protobuf::util::TimeUtil;
+typedef google::protobuf::Map<grpc::string, collectd::types::MetadataValue> grpcMetadata;
+
/*
* private types
*/
struct Listener {
- grpc::string addr;
- grpc::string port;
+ grpc::string addr;
+ grpc::string port;
- grpc::SslServerCredentialsOptions *ssl;
+ grpc::SslServerCredentialsOptions *ssl;
};
static std::vector<Listener> listeners;
static grpc::string default_addr("0.0.0.0:50051");
* 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_meta_data(meta_data_t *meta,
+ grpcMetadata *mutable_meta_data) {
+ char **meta_data_keys = nullptr;
+ int meta_data_keys_len = meta_data_toc(meta, &meta_data_keys);
+ if (meta_data_keys_len < 0) {
+ return grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("error getting metadata keys"));
+ }
+
+ for (int i = 0; i < meta_data_keys_len; i++) {
+ char *key = meta_data_keys[i];
+ int md_type = meta_data_type(meta, key);
+
+ collectd::types::MetadataValue md_value;
+ md_value.Clear();
+
+ switch (md_type) {
+ case MD_TYPE_STRING:
+ char *md_string;
+ if (meta_data_get_string(meta, key, &md_string) != 0 || md_string == nullptr) {
+ strarray_free(meta_data_keys, meta_data_keys_len);
+ return grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("missing metadata"));
+ }
+ md_value.set_string_value(md_string);
+ free(md_string);
+ break;
+ case MD_TYPE_SIGNED_INT:
+ int64_t int64_value;
+ if (meta_data_get_signed_int(meta, key, &int64_value) != 0) {
+ strarray_free(meta_data_keys, meta_data_keys_len);
+ return grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("missing metadata"));
+ }
+ md_value.set_int64_value(int64_value);
+ break;
+ case MD_TYPE_UNSIGNED_INT:
+ uint64_t uint64_value;
+ if (meta_data_get_unsigned_int(meta, key, &uint64_value) != 0) {
+ strarray_free(meta_data_keys, meta_data_keys_len);
+ return grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("missing metadata"));
+ }
+ md_value.set_uint64_value(uint64_value);
+ break;
+ case MD_TYPE_DOUBLE:
+ double double_value;
+ if (meta_data_get_double(meta, key, &double_value) != 0) {
+ strarray_free(meta_data_keys, meta_data_keys_len);
+ return grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("missing metadata"));
+ }
+ md_value.set_double_value(double_value);
+ break;
+ case MD_TYPE_BOOLEAN:
+ bool bool_value;
+ if (meta_data_get_boolean(meta, key, &bool_value) != 0) {
+ strarray_free(meta_data_keys, meta_data_keys_len);
+ return grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("missing metadata"));
+ }
+ md_value.set_bool_value(bool_value);
+ break;
+ default:
+ strarray_free(meta_data_keys, meta_data_keys_len);
+ ERROR("grpc: invalid metadata type (%d)", md_type);
+ return grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("unknown metadata type"));
+ }
+
+ (*mutable_meta_data)[grpc::string(key)] = md_value;
+
+ strarray_free(meta_data_keys, meta_data_keys_len);
+ }
+
+ return grpc::Status::OK;
+}
+
+static grpc::Status unmarshal_meta_data(const grpcMetadata &rpc_metadata,
+ meta_data_t **md_out) {
+ *md_out = meta_data_create();
+ if (*md_out == nullptr) {
+ return grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED,
+ grpc::string("failed to metadata list"));
+ }
+ for (auto kv: rpc_metadata) {
+ auto k = kv.first.c_str();
+ auto v = kv.second;
+
+ // The meta_data collection individually allocates copies of the keys and
+ // string values for each entry, so it's safe for us to pass a reference
+ // to our short-lived strings.
+
+ switch (v.value_case()) {
+ case collectd::types::MetadataValue::ValueCase::kStringValue:
+ meta_data_add_string(*md_out, k, v.string_value().c_str());
+ break;
+ case collectd::types::MetadataValue::ValueCase::kInt64Value:
+ meta_data_add_signed_int(*md_out, k, v.int64_value());
+ break;
+ case collectd::types::MetadataValue::ValueCase::kUint64Value:
+ meta_data_add_unsigned_int(*md_out, k, v.uint64_value());
+ break;
+ case collectd::types::MetadataValue::ValueCase::kDoubleValue:
+ meta_data_add_double(*md_out, k, v.double_value());
+ break;
+ case collectd::types::MetadataValue::ValueCase::kBoolValue:
+ meta_data_add_boolean(*md_out, k, v.bool_value());
+ break;
+ default:
+ meta_data_destroy(*md_out);
+ return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
+ grpc::string("Metadata of unknown type"));
+ }
+ }
+ 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));
+
+ msg->clear_meta_data();
+ if (vl->meta != nullptr) {
+ grpc::Status status = marshal_meta_data(vl->meta, msg->mutable_meta_data());
+ if (!status.ok()) {
+ return status;
+ }
+ }
+
+ for (size_t i = 0; i < vl->values_len; ++i) {
+ auto v = msg->add_values();
+ int value_type = ds->ds[i].type;
+ switch (value_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:
+ ERROR("grpc: invalid value type (%d)", value_type);
+ 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;
+
+ status = unmarshal_meta_data(msg.meta_data(), &vl->meta);
+ 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 {
+ meta_data_destroy(vl->meta);
+ free(values);
+ }
+
+ return status;
} /* unmarshal_value_list() */
/*
*/
class CollectdImpl : public collectd::Collectd::Service {
public:
- grpc::Status QueryValues(grpc::ServerContext *ctx, QueryValuesRequest const *req, grpc::ServerWriter<QueryValuesResponse> *writer) override {
- value_list_t match;
- auto status = unmarshal_ident(req->identifier(), &match, false);
- if (!status.ok()) {
- return status;
- }
-
- std::queue<value_list_t> value_lists;
- status = this->queryValuesRead(&match, &value_lists);
- if (status.ok()) {
- status = this->queryValuesWrite(ctx, writer, &value_lists);
- }
-
- while (!value_lists.empty()) {
- auto vl = value_lists.front();
- value_lists.pop();
- sfree(vl.values);
- }
-
- return status;
- }
-
- grpc::Status PutValues(grpc::ServerContext *ctx,
- grpc::ServerReader<PutValuesRequest> *reader,
- PutValuesResponse *res) override {
- PutValuesRequest req;
-
- while (reader->Read(&req)) {
- value_list_t vl = {0};
- auto status = unmarshal_value_list(req.value_list(), &vl);
- if (!status.ok())
- return status;
-
- if (plugin_dispatch_values(&vl))
- return grpc::Status(grpc::StatusCode::INTERNAL,
- grpc::string("failed to enqueue values for writing"));
- }
-
- res->Clear();
- return grpc::Status::OK;
- }
+ grpc::Status
+ QueryValues(grpc::ServerContext *ctx, QueryValuesRequest const *req,
+ grpc::ServerWriter<QueryValuesResponse> *writer) override {
+ value_list_t match;
+ auto status = unmarshal_ident(req->identifier(), &match, false);
+ if (!status.ok()) {
+ return status;
+ }
+
+ std::queue<value_list_t> value_lists;
+ status = this->queryValuesRead(&match, &value_lists);
+ if (status.ok()) {
+ status = this->queryValuesWrite(ctx, writer, &value_lists);
+ }
+
+ while (!value_lists.empty()) {
+ auto vl = value_lists.front();
+ value_lists.pop();
+ sfree(vl.values);
+ meta_data_destroy(vl.meta);
+ }
+
+ return status;
+ }
+
+ grpc::Status PutValues(grpc::ServerContext *ctx,
+ grpc::ServerReader<PutValuesRequest> *reader,
+ PutValuesResponse *res) override {
+ PutValuesRequest req;
+
+ while (reader->Read(&req)) {
+ value_list_t vl = {0};
+ auto status = unmarshal_value_list(req.value_list(), &vl);
+ if (!status.ok())
+ return status;
+
+ if (plugin_dispatch_values(&vl))
+ return grpc::Status(
+ grpc::StatusCode::INTERNAL,
+ grpc::string("failed to enqueue values for writing"));
+ }
+
+ res->Clear();
+ return grpc::Status::OK;
+ }
private:
- grpc::Status queryValuesRead(value_list_t const *match, std::queue<value_list_t> *value_lists) {
- uc_iter_t *iter;
- if ((iter = uc_get_iterator()) == NULL) {
- return grpc::Status(grpc::StatusCode::INTERNAL,
- grpc::string("failed to query values: cannot create iterator"));
- }
-
- grpc::Status status = grpc::Status::OK;
- char *name = NULL;
- while (uc_iterator_next(iter, &name) == 0) {
- value_list_t vl;
- if (parse_identifier_vl(name, &vl) != 0) {
- status = grpc::Status(grpc::StatusCode::INTERNAL,
- grpc::string("failed to parse identifier"));
- break;
- }
-
- if (!ident_matches(&vl, match))
- continue;
-
- if (uc_iterator_get_time(iter, &vl.time) < 0) {
- status = grpc::Status(grpc::StatusCode::INTERNAL,
- grpc::string("failed to retrieve value timestamp"));
- break;
- }
- if (uc_iterator_get_interval(iter, &vl.interval) < 0) {
- status = grpc::Status(grpc::StatusCode::INTERNAL,
- grpc::string("failed to retrieve value interval"));
- break;
- }
- if (uc_iterator_get_values(iter, &vl.values, &vl.values_len) < 0) {
- status = grpc::Status(grpc::StatusCode::INTERNAL,
- grpc::string("failed to retrieve values"));
- break;
- }
-
- value_lists->push(vl);
- } // while (uc_iterator_next(iter, &name) == 0)
-
- uc_iterator_destroy(iter);
- return status;
- }
-
- grpc::Status queryValuesWrite(grpc::ServerContext *ctx,
- grpc::ServerWriter<QueryValuesResponse> *writer,
- std::queue<value_list_t> *value_lists) {
- while (!value_lists->empty()) {
- auto vl = value_lists->front();
- QueryValuesResponse res;
- res.Clear();
-
- auto status = marshal_value_list(&vl, res.mutable_value_list());
- if (!status.ok()) {
- return status;
- }
-
- if (!writer->Write(res)) {
- return grpc::Status::CANCELLED;
- }
-
- value_lists->pop();
- sfree(vl.values);
- }
-
- return grpc::Status::OK;
- }
+ grpc::Status queryValuesRead(value_list_t const *match,
+ std::queue<value_list_t> *value_lists) {
+ uc_iter_t *iter;
+ if ((iter = uc_get_iterator()) == NULL) {
+ return grpc::Status(
+ grpc::StatusCode::INTERNAL,
+ grpc::string("failed to query values: cannot create iterator"));
+ }
+
+ grpc::Status status = grpc::Status::OK;
+ char *name = NULL;
+ while (uc_iterator_next(iter, &name) == 0) {
+ value_list_t vl;
+ if (parse_identifier_vl(name, &vl) != 0) {
+ status = grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to parse identifier"));
+ break;
+ }
+
+ if (!ident_matches(&vl, match))
+ continue;
+ if (uc_iterator_get_time(iter, &vl.time) < 0) {
+ status =
+ grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to retrieve value timestamp"));
+ break;
+ }
+ if (uc_iterator_get_interval(iter, &vl.interval) < 0) {
+ status =
+ grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to retrieve value interval"));
+ break;
+ }
+ if (uc_iterator_get_values(iter, &vl.values, &vl.values_len) < 0) {
+ status = grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to retrieve values"));
+ break;
+ }
+ if (uc_iterator_get_meta(iter, &vl.meta) < 0) {
+ status = grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to retrieve value metadata"));
+ }
+
+ value_lists->push(vl);
+ } // while (uc_iterator_next(iter, &name) == 0)
+
+ uc_iterator_destroy(iter);
+ return status;
+ }
+
+ grpc::Status queryValuesWrite(grpc::ServerContext *ctx,
+ grpc::ServerWriter<QueryValuesResponse> *writer,
+ std::queue<value_list_t> *value_lists) {
+ while (!value_lists->empty()) {
+ auto vl = value_lists->front();
+ QueryValuesResponse res;
+ res.Clear();
+
+ auto status = marshal_value_list(&vl, res.mutable_value_list());
+ if (!status.ok()) {
+ return status;
+ }
+
+ if (!writer->Write(res)) {
+ return grpc::Status::CANCELLED;
+ }
+
+ value_lists->pop();
+ sfree(vl.values);
+ }
+
+ return grpc::Status::OK;
+ }
};
/*
* gRPC server implementation
*/
-class CollectdServer final
-{
+class CollectdServer final {
public:
- void Start()
- {
- auto auth = grpc::InsecureServerCredentials();
-
- grpc::ServerBuilder builder;
-
- if (listeners.empty()) {
- builder.AddListeningPort(default_addr, auth);
- INFO("grpc: Listening on %s", default_addr.c_str());
- }
- else {
- for (auto l : listeners) {
- grpc::string addr = l.addr + ":" + l.port;
-
- auto use_ssl = grpc::string("");
- auto a = auth;
- if (l.ssl != nullptr) {
- use_ssl = grpc::string(" (SSL enabled)");
- a = grpc::SslServerCredentials(*l.ssl);
- }
-
- builder.AddListeningPort(addr, a);
- INFO("grpc: Listening on %s%s", addr.c_str(), use_ssl.c_str());
- }
- }
-
- builder.RegisterService(&collectd_service_);
-
- server_ = builder.BuildAndStart();
- } /* Start() */
-
- void Shutdown()
- {
- server_->Shutdown();
- } /* Shutdown() */
+ void Start() {
+ auto auth = grpc::InsecureServerCredentials();
+
+ grpc::ServerBuilder builder;
+
+ if (listeners.empty()) {
+ builder.AddListeningPort(default_addr, auth);
+ INFO("grpc: Listening on %s", default_addr.c_str());
+ } else {
+ for (auto l : listeners) {
+ grpc::string addr = l.addr + ":" + l.port;
+
+ auto use_ssl = grpc::string("");
+ auto a = auth;
+ if (l.ssl != nullptr) {
+ use_ssl = grpc::string(" (SSL enabled)");
+ a = grpc::SslServerCredentials(*l.ssl);
+ }
+
+ builder.AddListeningPort(addr, a);
+ INFO("grpc: Listening on %s%s", addr.c_str(), use_ssl.c_str());
+ }
+ }
+
+ builder.RegisterService(&collectd_service_);
+
+ server_ = builder.BuildAndStart();
+ } /* Start() */
+
+ void Shutdown() { server_->Shutdown(); } /* Shutdown() */
private:
- CollectdImpl collectd_service_;
+ CollectdImpl collectd_service_;
- std::unique_ptr<grpc::Server> server_;
+ std::unique_ptr<grpc::Server> server_;
}; /* class CollectdServer */
-class CollectdClient final
-{
+class CollectdClient final {
public:
- CollectdClient(std::shared_ptr<grpc::ChannelInterface> channel) : stub_(Collectd::NewStub(channel)) {
- }
-
- int PutValues(value_list_t const *vl) {
- grpc::ClientContext ctx;
-
- PutValuesRequest req;
- auto status = marshal_value_list(vl, req.mutable_value_list());
- if (!status.ok()) {
- ERROR("grpc: Marshalling value_list_t failed.");
- return -1;
- }
-
- PutValuesResponse res;
- auto stream = stub_->PutValues(&ctx, &res);
- if (!stream->Write(req)) {
- NOTICE("grpc: Broken stream.");
- /* intentionally not returning. */
- }
-
- stream->WritesDone();
- status = stream->Finish();
- if (!status.ok()) {
- ERROR ("grpc: Error while closing stream.");
- return -1;
- }
-
- return 0;
- } /* int PutValues */
+ CollectdClient(std::shared_ptr<grpc::ChannelInterface> channel)
+ : stub_(Collectd::NewStub(channel)) {}
+
+ int PutValues(value_list_t const *vl) {
+ grpc::ClientContext ctx;
+
+ PutValuesRequest req;
+ auto status = marshal_value_list(vl, req.mutable_value_list());
+ if (!status.ok()) {
+ ERROR("grpc: Marshalling value_list_t failed.");
+ return -1;
+ }
+
+ PutValuesResponse res;
+ auto stream = stub_->PutValues(&ctx, &res);
+ if (!stream->Write(req)) {
+ NOTICE("grpc: Broken stream.");
+ /* intentionally not returning. */
+ }
+
+ stream->WritesDone();
+ status = stream->Finish();
+ if (!status.ok()) {
+ ERROR("grpc: Error while closing stream.");
+ return -1;
+ }
+
+ return 0;
+ } /* int PutValues */
private:
- std::unique_ptr<Collectd::Stub> stub_;
+ std::unique_ptr<Collectd::Stub> stub_;
};
static CollectdServer *server = nullptr;
* 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;
+}
+
+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);
+}
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
+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" */
ERROR("hddtemp plugin: getaddrinfo (%s, %s): %s", host, port,
(ai_return == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
: gai_strerror(ai_return));
- return (NULL);
+ return NULL;
}
fd = -1;
if (fd < 0) {
ERROR("hddtemp plugin: Could not connect to daemon.");
- return (NULL);
+ return NULL;
}
/* receive data from the hddtemp daemon */
close(fd);
free(buffer);
ERROR("hddtemp plugin: Allocation failed.");
- return (NULL);
+ return NULL;
}
buffer = new_buffer;
}
sstrerror(errno, errbuf, sizeof(errbuf)));
close(fd);
free(buffer);
- return (NULL);
+ return NULL;
}
buffer_fill += status;
}
buffer);
close(fd);
free(buffer);
- return (NULL);
+ return NULL;
}
assert(buffer_fill < buffer_size);
buffer[buffer_fill] = '\0';
close(fd);
- return (buffer);
+ return buffer;
}
static int hddtemp_config(const char *key, const char *value) {
} else if (strcasecmp(key, "Port") == 0) {
int port = (int)(atof(value));
if ((port > 0) && (port <= 65535))
- ssnprintf(hddtemp_port, sizeof(hddtemp_port), "%i", port);
+ snprintf(hddtemp_port, sizeof(hddtemp_port), "%i", port);
else
sstrncpy(hddtemp_port, value, sizeof(hddtemp_port));
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static void hddtemp_submit(char *type_instance, double value) {
/* get data from daemon */
buf = hddtemp_query_daemon();
if (buf == NULL)
- return (-1);
+ return -1;
/* NB: strtok_r will eat up "||" and leading "|"'s */
ptr = buf;
}
free(buf);
- return (0);
+ return 0;
} /* int hddtemp_read */
/* module_register
child->key);
}
- return (0);
+ return 0;
}
static void submit_hp(const struct entry_info *info) {
sstrncpy(vl.plugin, g_plugin_name, sizeof(vl.plugin));
if (info->node) {
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%zuKb",
- info->node, info->page_size_kb);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%zuKb",
+ info->node, info->page_size_kb);
} else {
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%zuKb",
- info->page_size_kb);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%zuKb",
+ info->page_size_kb);
}
/* ensure all metrics have the same timestamp */
struct entry_info *info = e_info;
double value;
- ssnprintf(path2, sizeof(path2), "%s/%s", path, entry);
+ snprintf(path2, sizeof(path2), "%s/%s", path, entry);
FILE *fh = fopen(path2, "rt");
if (fh == NULL) {
}
/* /sys/devices/system/node/node?/hugepages/ */
- ssnprintf(path2, sizeof(path2), "%s/%s", path, result->d_name);
+ snprintf(path2, sizeof(path2), "%s/%s", path, result->d_name);
walk_directory(path2, read_hugepage_entry,
&(struct entry_info){
continue;
}
- ssnprintf(path, sizeof(path), sys_node_hugepages, result->d_name);
+ snprintf(path, sizeof(path), sys_node_hugepages, result->d_name);
read_syshugepages(path, result->d_name);
errno = 0;
}
--- /dev/null
+/**
+ * collectd - src/intel_pmu.c
+ *
+ * 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:
+ * Serhiy Pshyk <serhiyx.pshyk@intel.com>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+
+#include <jevents.h>
+#include <jsession.h>
+
+#define PMU_PLUGIN "intel_pmu"
+
+#define HW_CACHE_READ_ACCESS \
+ (((PERF_COUNT_HW_CACHE_OP_READ) << 8) | \
+ ((PERF_COUNT_HW_CACHE_RESULT_ACCESS) << 16))
+
+#define HW_CACHE_WRITE_ACCESS \
+ (((PERF_COUNT_HW_CACHE_OP_WRITE) << 8) | \
+ ((PERF_COUNT_HW_CACHE_RESULT_ACCESS) << 16))
+
+#define HW_CACHE_PREFETCH_ACCESS \
+ (((PERF_COUNT_HW_CACHE_OP_PREFETCH) << 8) | \
+ ((PERF_COUNT_HW_CACHE_RESULT_ACCESS) << 16))
+
+#define HW_CACHE_READ_MISS \
+ (((PERF_COUNT_HW_CACHE_OP_READ) << 8) | \
+ ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))
+
+#define HW_CACHE_WRITE_MISS \
+ (((PERF_COUNT_HW_CACHE_OP_WRITE) << 8) | \
+ ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))
+
+#define HW_CACHE_PREFETCH_MISS \
+ (((PERF_COUNT_HW_CACHE_OP_PREFETCH) << 8) | \
+ ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))
+
+struct event_info {
+ char *name;
+ uint64_t config;
+};
+typedef struct event_info event_info_t;
+
+struct intel_pmu_ctx_s {
+ _Bool hw_cache_events;
+ _Bool kernel_pmu_events;
+ _Bool sw_events;
+ char event_list_fn[PATH_MAX];
+ char **hw_events;
+ size_t hw_events_count;
+ struct eventlist *event_list;
+};
+typedef struct intel_pmu_ctx_s intel_pmu_ctx_t;
+
+event_info_t g_kernel_pmu_events[] = {
+ {.name = "cpu-cycles", .config = PERF_COUNT_HW_CPU_CYCLES},
+ {.name = "instructions", .config = PERF_COUNT_HW_INSTRUCTIONS},
+ {.name = "cache-references", .config = PERF_COUNT_HW_CACHE_REFERENCES},
+ {.name = "cache-misses", .config = PERF_COUNT_HW_CACHE_MISSES},
+ {.name = "branches", .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS},
+ {.name = "branch-misses", .config = PERF_COUNT_HW_BRANCH_MISSES},
+ {.name = "bus-cycles", .config = PERF_COUNT_HW_BUS_CYCLES},
+};
+
+event_info_t g_hw_cache_events[] = {
+
+ {.name = "L1-dcache-loads",
+ .config = (PERF_COUNT_HW_CACHE_L1D | HW_CACHE_READ_ACCESS)},
+ {.name = "L1-dcache-load-misses",
+ .config = (PERF_COUNT_HW_CACHE_L1D | HW_CACHE_READ_MISS)},
+ {.name = "L1-dcache-stores",
+ .config = (PERF_COUNT_HW_CACHE_L1D | HW_CACHE_WRITE_ACCESS)},
+ {.name = "L1-dcache-store-misses",
+ .config = (PERF_COUNT_HW_CACHE_L1D | HW_CACHE_WRITE_MISS)},
+ {.name = "L1-dcache-prefetches",
+ .config = (PERF_COUNT_HW_CACHE_L1D | HW_CACHE_PREFETCH_ACCESS)},
+ {.name = "L1-dcache-prefetch-misses",
+ .config = (PERF_COUNT_HW_CACHE_L1D | HW_CACHE_PREFETCH_MISS)},
+
+ {.name = "L1-icache-loads",
+ .config = (PERF_COUNT_HW_CACHE_L1I | HW_CACHE_READ_ACCESS)},
+ {.name = "L1-icache-load-misses",
+ .config = (PERF_COUNT_HW_CACHE_L1I | HW_CACHE_READ_MISS)},
+ {.name = "L1-icache-prefetches",
+ .config = (PERF_COUNT_HW_CACHE_L1I | HW_CACHE_PREFETCH_ACCESS)},
+ {.name = "L1-icache-prefetch-misses",
+ .config = (PERF_COUNT_HW_CACHE_L1I | HW_CACHE_PREFETCH_MISS)},
+
+ {.name = "LLC-loads",
+ .config = (PERF_COUNT_HW_CACHE_LL | HW_CACHE_READ_ACCESS)},
+ {.name = "LLC-load-misses",
+ .config = (PERF_COUNT_HW_CACHE_LL | HW_CACHE_READ_MISS)},
+ {.name = "LLC-stores",
+ .config = (PERF_COUNT_HW_CACHE_LL | HW_CACHE_WRITE_ACCESS)},
+ {.name = "LLC-store-misses",
+ .config = (PERF_COUNT_HW_CACHE_LL | HW_CACHE_WRITE_MISS)},
+ {.name = "LLC-prefetches",
+ .config = (PERF_COUNT_HW_CACHE_LL | HW_CACHE_PREFETCH_ACCESS)},
+ {.name = "LLC-prefetch-misses",
+ .config = (PERF_COUNT_HW_CACHE_LL | HW_CACHE_PREFETCH_MISS)},
+
+ {.name = "dTLB-loads",
+ .config = (PERF_COUNT_HW_CACHE_DTLB | HW_CACHE_READ_ACCESS)},
+ {.name = "dTLB-load-misses",
+ .config = (PERF_COUNT_HW_CACHE_DTLB | HW_CACHE_READ_MISS)},
+ {.name = "dTLB-stores",
+ .config = (PERF_COUNT_HW_CACHE_DTLB | HW_CACHE_WRITE_ACCESS)},
+ {.name = "dTLB-store-misses",
+ .config = (PERF_COUNT_HW_CACHE_DTLB | HW_CACHE_WRITE_MISS)},
+ {.name = "dTLB-prefetches",
+ .config = (PERF_COUNT_HW_CACHE_DTLB | HW_CACHE_PREFETCH_ACCESS)},
+ {.name = "dTLB-prefetch-misses",
+ .config = (PERF_COUNT_HW_CACHE_DTLB | HW_CACHE_PREFETCH_MISS)},
+
+ {.name = "iTLB-loads",
+ .config = (PERF_COUNT_HW_CACHE_ITLB | HW_CACHE_READ_ACCESS)},
+ {.name = "iTLB-load-misses",
+ .config = (PERF_COUNT_HW_CACHE_ITLB | HW_CACHE_READ_MISS)},
+
+ {.name = "branch-loads",
+ .config = (PERF_COUNT_HW_CACHE_BPU | HW_CACHE_READ_ACCESS)},
+ {.name = "branch-load-misses",
+ .config = (PERF_COUNT_HW_CACHE_BPU | HW_CACHE_READ_MISS)},
+};
+
+event_info_t g_sw_events[] = {
+ {.name = "cpu-clock", .config = PERF_COUNT_SW_CPU_CLOCK},
+
+ {.name = "task-clock", .config = PERF_COUNT_SW_TASK_CLOCK},
+
+ {.name = "context-switches", .config = PERF_COUNT_SW_CONTEXT_SWITCHES},
+
+ {.name = "cpu-migrations", .config = PERF_COUNT_SW_CPU_MIGRATIONS},
+
+ {.name = "page-faults", .config = PERF_COUNT_SW_PAGE_FAULTS},
+
+ {.name = "minor-faults", .config = PERF_COUNT_SW_PAGE_FAULTS_MIN},
+
+ {.name = "major-faults", .config = PERF_COUNT_SW_PAGE_FAULTS_MAJ},
+
+ {.name = "alignment-faults", .config = PERF_COUNT_SW_ALIGNMENT_FAULTS},
+
+ {.name = "emulation-faults", .config = PERF_COUNT_SW_EMULATION_FAULTS},
+};
+
+static intel_pmu_ctx_t g_ctx;
+
+#if COLLECT_DEBUG
+static void pmu_dump_events() {
+
+ DEBUG(PMU_PLUGIN ": Events:");
+
+ struct event *e;
+
+ for (e = g_ctx.event_list->eventlist; e; e = e->next) {
+ DEBUG(PMU_PLUGIN ": event : %s", e->event);
+ DEBUG(PMU_PLUGIN ": group_lead: %d", e->group_leader);
+ DEBUG(PMU_PLUGIN ": end_group : %d", e->end_group);
+ DEBUG(PMU_PLUGIN ": type : %#x", e->attr.type);
+ DEBUG(PMU_PLUGIN ": config : %#x", (unsigned)e->attr.config);
+ DEBUG(PMU_PLUGIN ": size : %d", e->attr.size);
+ }
+}
+
+static void pmu_dump_config(void) {
+
+ DEBUG(PMU_PLUGIN ": Config:");
+ DEBUG(PMU_PLUGIN ": hw_cache_events : %d", g_ctx.hw_cache_events);
+ DEBUG(PMU_PLUGIN ": kernel_pmu_events : %d", g_ctx.kernel_pmu_events);
+ DEBUG(PMU_PLUGIN ": software_events : %d", g_ctx.sw_events);
+
+ for (size_t i = 0; i < g_ctx.hw_events_count; i++) {
+ DEBUG(PMU_PLUGIN ": hardware_events[%zu]: %s", i, g_ctx.hw_events[i]);
+ }
+}
+
+#endif /* COLLECT_DEBUG */
+
+static int pmu_config_hw_events(oconfig_item_t *ci) {
+
+ if (strcasecmp("HardwareEvents", ci->key) != 0) {
+ return -EINVAL;
+ }
+
+ g_ctx.hw_events = calloc(ci->values_num, sizeof(char *));
+ if (g_ctx.hw_events == NULL) {
+ ERROR(PMU_PLUGIN ": Failed to allocate hw events.");
+ return -ENOMEM;
+ }
+
+ for (int i = 0; i < ci->values_num; i++) {
+ if (ci->values[i].type != OCONFIG_TYPE_STRING) {
+ WARNING(PMU_PLUGIN ": The %s option requires string arguments.", ci->key);
+ continue;
+ }
+
+ g_ctx.hw_events[g_ctx.hw_events_count] = strdup(ci->values[i].value.string);
+ if (g_ctx.hw_events[g_ctx.hw_events_count] == NULL) {
+ ERROR(PMU_PLUGIN ": Failed to allocate hw events entry.");
+ return -ENOMEM;
+ }
+
+ g_ctx.hw_events_count++;
+ }
+
+ return 0;
+}
+
+static int pmu_config(oconfig_item_t *ci) {
+
+ DEBUG(PMU_PLUGIN ": %s:%d", __FUNCTION__, __LINE__);
+
+ for (int i = 0; i < ci->children_num; i++) {
+ int ret = 0;
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp("ReportHardwareCacheEvents", child->key) == 0) {
+ ret = cf_util_get_boolean(child, &g_ctx.hw_cache_events);
+ } else if (strcasecmp("ReportKernelPMUEvents", child->key) == 0) {
+ ret = cf_util_get_boolean(child, &g_ctx.kernel_pmu_events);
+ } else if (strcasecmp("EventList", child->key) == 0) {
+ ret = cf_util_get_string_buffer(child, g_ctx.event_list_fn,
+ sizeof(g_ctx.event_list_fn));
+ } else if (strcasecmp("HardwareEvents", child->key) == 0) {
+ ret = pmu_config_hw_events(child);
+ } else if (strcasecmp("ReportSoftwareEvents", child->key) == 0) {
+ ret = cf_util_get_boolean(child, &g_ctx.sw_events);
+ } else {
+ ERROR(PMU_PLUGIN ": Unknown configuration parameter \"%s\".", child->key);
+ ret = -1;
+ }
+
+ if (ret != 0) {
+ DEBUG(PMU_PLUGIN ": %s:%d ret=%d", __FUNCTION__, __LINE__, ret);
+ return ret;
+ }
+ }
+
+#if COLLECT_DEBUG
+ pmu_dump_config();
+#endif
+
+ return 0;
+}
+
+static void pmu_submit_counter(int cpu, char *event, counter_t value,
+ meta_data_t *meta) {
+ value_list_t vl = VALUE_LIST_INIT;
+
+ vl.values = &(value_t){.counter = value};
+ vl.values_len = 1;
+
+ sstrncpy(vl.plugin, PMU_PLUGIN, sizeof(vl.plugin));
+ if (cpu == -1) {
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "all");
+ } else {
+ vl.meta = meta;
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%d", cpu);
+ }
+ sstrncpy(vl.type, "counter", sizeof(vl.type));
+ sstrncpy(vl.type_instance, event, sizeof(vl.type_instance));
+
+ plugin_dispatch_values(&vl);
+}
+
+meta_data_t *pmu_meta_data_create(const struct efd *efd) {
+ meta_data_t *meta = NULL;
+
+ /* create meta data only if value was scaled */
+ if (efd->val[1] == efd->val[2] || !efd->val[2]) {
+ return NULL;
+ }
+
+ meta = meta_data_create();
+ if (meta == NULL) {
+ ERROR(PMU_PLUGIN ": meta_data_create failed.");
+ return NULL;
+ }
+
+ meta_data_add_unsigned_int(meta, "intel_pmu:raw_count", efd->val[0]);
+ meta_data_add_unsigned_int(meta, "intel_pmu:time_enabled", efd->val[1]);
+ meta_data_add_unsigned_int(meta, "intel_pmu:time_running", efd->val[2]);
+
+ return meta;
+}
+
+static void pmu_dispatch_data(void) {
+
+ struct event *e;
+
+ for (e = g_ctx.event_list->eventlist; e; e = e->next) {
+ uint64_t all_value = 0;
+ int event_enabled = 0;
+ for (int i = 0; i < g_ctx.event_list->num_cpus; i++) {
+
+ if (e->efd[i].fd < 0)
+ continue;
+
+ event_enabled++;
+
+ /* If there are more events than counters, the kernel uses time
+ * multiplexing. With multiplexing, at the end of the run,
+ * the counter is scaled basing on total time enabled vs time running.
+ * final_count = raw_count * time_enabled/time_running
+ */
+ uint64_t value = event_scaled_value(e, i);
+ all_value += value;
+
+ /* get meta data with information about scaling */
+ meta_data_t *meta = pmu_meta_data_create(&e->efd[i]);
+
+ /* dispatch per CPU value */
+ pmu_submit_counter(i, e->event, value, meta);
+
+ meta_data_destroy(meta);
+ }
+
+ if (event_enabled > 0) {
+ DEBUG(PMU_PLUGIN ": %-20s %'10lu", e->event, all_value);
+ /* dispatch all CPU value */
+ pmu_submit_counter(-1, e->event, all_value, NULL);
+ }
+ }
+}
+
+static int pmu_read(__attribute__((unused)) user_data_t *ud) {
+ int ret;
+
+ DEBUG(PMU_PLUGIN ": %s:%d", __FUNCTION__, __LINE__);
+
+ ret = read_all_events(g_ctx.event_list);
+ if (ret != 0) {
+ ERROR(PMU_PLUGIN ": Failed to read values of all events.");
+ return ret;
+ }
+
+ pmu_dispatch_data();
+
+ return 0;
+}
+
+static int pmu_add_events(struct eventlist *el, uint32_t type,
+ event_info_t *events, size_t count) {
+
+ for (size_t i = 0; i < count; i++) {
+ /* Allocate memory for event struct that contains array of efd structs
+ for all cores */
+ struct event *e =
+ calloc(sizeof(struct event) + sizeof(struct efd) * el->num_cpus, 1);
+ if (e == NULL) {
+ ERROR(PMU_PLUGIN ": Failed to allocate event structure");
+ return -ENOMEM;
+ }
+
+ e->attr.type = type;
+ e->attr.config = events[i].config;
+ e->attr.size = PERF_ATTR_SIZE_VER0;
+ if (!el->eventlist)
+ el->eventlist = e;
+ if (el->eventlist_last)
+ el->eventlist_last->next = e;
+ el->eventlist_last = e;
+ e->event = strdup(events[i].name);
+ }
+
+ return 0;
+}
+
+static int pmu_add_hw_events(struct eventlist *el, char **e, size_t count) {
+
+ for (size_t i = 0; i < count; i++) {
+
+ size_t group_events_count = 0;
+
+ char *events = strdup(e[i]);
+ if (!events)
+ return -1;
+
+ char *s, *tmp;
+ for (s = strtok_r(events, ",", &tmp); s; s = strtok_r(NULL, ",", &tmp)) {
+
+ /* Multiple events parsed in one entry */
+ if (group_events_count == 1) {
+ /* Mark previously added event as group leader */
+ el->eventlist_last->group_leader = 1;
+ }
+
+ /* Allocate memory for event struct that contains array of efd structs
+ for all cores */
+ struct event *e =
+ calloc(sizeof(struct event) + sizeof(struct efd) * el->num_cpus, 1);
+ if (e == NULL) {
+ free(events);
+ return -ENOMEM;
+ }
+
+ if (resolve_event(s, &e->attr) == 0) {
+ e->next = NULL;
+ if (!el->eventlist)
+ el->eventlist = e;
+ if (el->eventlist_last)
+ el->eventlist_last->next = e;
+ el->eventlist_last = e;
+ e->event = strdup(s);
+ } else {
+ DEBUG(PMU_PLUGIN ": Cannot resolve %s", s);
+ sfree(e);
+ }
+
+ group_events_count++;
+ }
+
+ /* Multiple events parsed in one entry */
+ if (group_events_count > 1) {
+ /* Mark last added event as group end */
+ el->eventlist_last->end_group = 1;
+ }
+
+ free(events);
+ }
+
+ return 0;
+}
+
+static void pmu_free_events(struct eventlist *el) {
+
+ if (el == NULL)
+ return;
+
+ struct event *e = el->eventlist;
+
+ while (e) {
+ struct event *next = e->next;
+ sfree(e);
+ e = next;
+ }
+
+ el->eventlist = NULL;
+}
+
+static int pmu_setup_events(struct eventlist *el, bool measure_all,
+ int measure_pid) {
+ struct event *e, *leader = NULL;
+ int ret = -1;
+
+ for (e = el->eventlist; e; e = e->next) {
+
+ for (int i = 0; i < el->num_cpus; i++) {
+ if (setup_event(e, i, leader, measure_all, measure_pid) < 0) {
+ WARNING(PMU_PLUGIN ": perf event '%s' is not available (cpu=%d).",
+ e->event, i);
+ } else {
+ /* success if at least one event was set */
+ ret = 0;
+ }
+ }
+
+ if (e->group_leader)
+ leader = e;
+ if (e->end_group)
+ leader = NULL;
+ }
+
+ return ret;
+}
+
+static int pmu_init(void) {
+ int ret;
+
+ DEBUG(PMU_PLUGIN ": %s:%d", __FUNCTION__, __LINE__);
+
+ g_ctx.event_list = alloc_eventlist();
+ if (g_ctx.event_list == NULL) {
+ ERROR(PMU_PLUGIN ": Failed to allocate event list.");
+ return -ENOMEM;
+ }
+
+ if (g_ctx.hw_cache_events) {
+ ret =
+ pmu_add_events(g_ctx.event_list, PERF_TYPE_HW_CACHE, g_hw_cache_events,
+ STATIC_ARRAY_SIZE(g_hw_cache_events));
+ if (ret != 0) {
+ ERROR(PMU_PLUGIN ": Failed to add hw cache events.");
+ goto init_error;
+ }
+ }
+
+ if (g_ctx.kernel_pmu_events) {
+ ret = pmu_add_events(g_ctx.event_list, PERF_TYPE_HARDWARE,
+ g_kernel_pmu_events,
+ STATIC_ARRAY_SIZE(g_kernel_pmu_events));
+ if (ret != 0) {
+ ERROR(PMU_PLUGIN ": Failed to add kernel PMU events.");
+ goto init_error;
+ }
+ }
+
+ /* parse events names if config option is present and is not empty */
+ if (g_ctx.hw_events_count) {
+
+ ret = read_events(g_ctx.event_list_fn);
+ if (ret != 0) {
+ ERROR(PMU_PLUGIN ": Failed to read event list file '%s'.",
+ g_ctx.event_list_fn);
+ return ret;
+ }
+
+ ret = pmu_add_hw_events(g_ctx.event_list, g_ctx.hw_events,
+ g_ctx.hw_events_count);
+ if (ret != 0) {
+ ERROR(PMU_PLUGIN ": Failed to add hardware events.");
+ goto init_error;
+ }
+ }
+
+ if (g_ctx.sw_events) {
+ ret = pmu_add_events(g_ctx.event_list, PERF_TYPE_SOFTWARE, g_sw_events,
+ STATIC_ARRAY_SIZE(g_sw_events));
+ if (ret != 0) {
+ ERROR(PMU_PLUGIN ": Failed to add software events.");
+ goto init_error;
+ }
+ }
+
+#if COLLECT_DEBUG
+ pmu_dump_events();
+#endif
+
+ if (g_ctx.event_list->eventlist != NULL) {
+ /* measure all processes */
+ ret = pmu_setup_events(g_ctx.event_list, true, -1);
+ if (ret != 0) {
+ ERROR(PMU_PLUGIN ": Failed to setup perf events for the event list.");
+ goto init_error;
+ }
+ } else {
+ WARNING(PMU_PLUGIN
+ ": Events list is empty. No events were setup for monitoring.");
+ }
+
+ return 0;
+
+init_error:
+
+ pmu_free_events(g_ctx.event_list);
+ sfree(g_ctx.event_list);
+ for (size_t i = 0; i < g_ctx.hw_events_count; i++) {
+ sfree(g_ctx.hw_events[i]);
+ }
+ sfree(g_ctx.hw_events);
+ g_ctx.hw_events_count = 0;
+
+ return ret;
+}
+
+static int pmu_shutdown(void) {
+
+ DEBUG(PMU_PLUGIN ": %s:%d", __FUNCTION__, __LINE__);
+
+ pmu_free_events(g_ctx.event_list);
+ sfree(g_ctx.event_list);
+ for (size_t i = 0; i < g_ctx.hw_events_count; i++) {
+ sfree(g_ctx.hw_events[i]);
+ }
+ sfree(g_ctx.hw_events);
+ g_ctx.hw_events_count = 0;
+
+ return 0;
+}
+
+void module_register(void) {
+ plugin_register_init(PMU_PLUGIN, pmu_init);
+ plugin_register_complex_config(PMU_PLUGIN, pmu_config);
+ plugin_register_complex_read(NULL, PMU_PLUGIN, pmu_read, 0, NULL);
+ plugin_register_shutdown(PMU_PLUGIN, pmu_shutdown);
+}
if (!(*s != '\0' && *endptr == '\0')) {
DEBUG(RDT_PLUGIN ": Error converting '%s' to unsigned number.", s);
- return (-EINVAL);
+ return -EINVAL;
}
- return (0);
+ return 0;
}
/*
*p = '\0';
ret = strtouint64(token, &start);
if (ret < 0)
- return (0);
+ return 0;
ret = strtouint64(p + 1, &end);
if (ret < 0)
- return (0);
+ return 0;
if (start > end) {
- return (0);
+ return 0;
}
for (n = start; n <= end; n++) {
if (!(isdup(nums, index, n))) {
ret = strtouint64(token, &val);
if (ret < 0)
- return (0);
+ return 0;
if (!(isdup(nums, index, val))) {
nums[index] = val;
cg->cores = calloc(num_cores, sizeof(unsigned));
if (cg->cores == NULL) {
ERROR(RDT_PLUGIN ": Error allocating core group table");
- return (-ENOMEM);
+ return -ENOMEM;
}
cg->num_cores = num_cores;
cg->desc = strdup(desc);
if (cg->desc == NULL) {
ERROR(RDT_PLUGIN ": Error allocating core group description");
sfree(cg->cores);
- return (-ENOMEM);
+ return -ENOMEM;
}
for (size_t i = 0; i < num_cores; i++)
* `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);
if (n == 0) {
ERROR(RDT_PLUGIN ": Error parsing core group (%s)",
item->values[j].value.string);
- 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);
- }
+ return -EINVAL;
}
/* set core group info */
char desc[DATA_MAX_NAME_LEN];
uint64_t core = i;
- ssnprintf(desc, sizeof(desc), "%d", g_rdt->pqos_cpu->cores[i].lcore);
+ snprintf(desc, sizeof(desc), "%d", g_rdt->pqos_cpu->cores[i].lcore);
/* set core group info */
ret = cgroup_set(&g_rdt->cgroups[i], desc, &core, 1);
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;
if (item == NULL) {
DEBUG(RDT_PLUGIN ": cgroups_config: Invalid argument.");
- return (-EINVAL);
+ return -EINVAL;
}
DEBUG(RDT_PLUGIN ": Core groups [%d]:", item->values_num);
for (int j = 0; j < item->values_num; j++) {
if (item->values[j].type != OCONFIG_TYPE_STRING) {
ERROR(RDT_PLUGIN ": given core group value is not a string [idx=%d]", j);
- return (-EINVAL);
+ return -EINVAL;
}
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);
+ 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) {
if (found != 0) {
rdt_free_cgroups();
ERROR(RDT_PLUGIN ": Cannot monitor same cores in different groups.");
- return (-EINVAL);
+ return -EINVAL;
}
}
if (g_rdt->pgroups[i] == NULL) {
rdt_free_cgroups();
ERROR(RDT_PLUGIN ": Failed to allocate memory for monitoring data.");
- return (-ENOMEM);
+ return -ENOMEM;
}
}
- return (0);
+ 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) {
if (g_rdt != NULL) {
/* already initialized if config callback was called before init callback */
- return (0);
+ return 0;
}
g_rdt = calloc(1, sizeof(*g_rdt));
if (g_rdt == NULL) {
ERROR(RDT_PLUGIN ": Failed to allocate memory for rdt context.");
- return (-ENOMEM);
+ 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;
goto rdt_preinit_error2;
}
- return (0);
+ /* Reset pqos monitoring groups registers */
+ pqos_mon_reset();
+
+ return 0;
rdt_preinit_error2:
pqos_fini();
sfree(g_rdt);
- return (-1);
+ return -1;
}
static int rdt_config(oconfig_item_t *ci) {
reports a failure in configuration and
aborts
*/
- return (0);
+ return (0);
}
#if COLLECT_DEBUG
}
}
- return (0);
+ return 0;
}
static void rdt_submit_derive(char *cgroup, char *type, char *type_instance,
if (g_rdt == NULL) {
ERROR(RDT_PLUGIN ": rdt_read: plugin not initialized.");
- return (-EINVAL);
+ return -EINVAL;
}
ret = pqos_mon_poll(&g_rdt->pgroups[0], (unsigned)g_rdt->num_groups);
if (ret != PQOS_RETVAL_OK) {
ERROR(RDT_PLUGIN ": Failed to poll monitoring data.");
- return (-1);
+ return -1;
}
#if COLLECT_DEBUG
}
}
- return (0);
+ return 0;
}
static int rdt_init(void) {
int ret;
- if(g_state == CONFIGURATION_ERROR)
- return (-1);
+ if (g_state == CONFIGURATION_ERROR)
+ return -1;
ret = rdt_preinit();
if (ret != 0)
cg->desc, ret);
}
- return (0);
+ return 0;
}
static int rdt_shutdown(void) {
DEBUG(RDT_PLUGIN ": rdt_shutdown.");
if (g_rdt == NULL)
- return (0);
+ return 0;
/* Stop monitoring */
for (int i = 0; i < g_rdt->num_groups; i++) {
rdt_free_cgroups();
sfree(g_rdt);
- return (0);
+ return 0;
}
void module_register(void) {
"Solaris.");
#endif /* HAVE_LIBKSTAT */
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
#if HAVE_LIBKSTAT
numif = 0;
if (kc == NULL)
- return (-1);
+ return -1;
for (numif = 0, ksp_chain = kc->kc_chain;
(numif < MAX_NUMIF) && (ksp_chain != NULL);
ksp[numif++] = ksp_chain;
}
- return (0);
+ return 0;
} /* int interface_init */
#endif /* HAVE_LIBKSTAT */
struct IFA_DATA *if_data;
if (getifaddrs(&if_list) != 0)
- return (-1);
+ return -1;
for (struct ifaddrs *if_ptr = if_list; if_ptr != NULL;
if_ptr = if_ptr->ifa_next) {
char errbuf[1024];
WARNING("interface plugin: fopen: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
while (fgets(buffer, 1024, fh) != NULL) {
char iname[DATA_MAX_NAME_LEN];
if (kc == NULL)
- return (-1);
+ return -1;
for (int i = 0; i < numif; i++) {
if (kstat_read(kc, ksp[i], NULL) == -1)
continue;
if (unique_name)
- ssnprintf(iname, sizeof(iname), "%s_%d_%s", ksp[i]->ks_module,
- ksp[i]->ks_instance, ksp[i]->ks_name);
+ snprintf(iname, sizeof(iname), "%s_%d_%s", ksp[i]->ks_module,
+ ksp[i]->ks_instance, ksp[i]->ks_name);
else
sstrncpy(iname, ksp[i]->ks_name, sizeof(iname));
char errbuf[1024];
WARNING("interface plugin: perfstat_netinterface: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
if (pnif != nif || ifstat == NULL) {
char errbuf[1024];
WARNING("interface plugin: perfstat_netinterface (interfaces=%d): %s", nif,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
for (int i = 0; i < ifs; i++) {
}
#endif /* HAVE_PERFSTAT */
- return (0);
+ return 0;
} /* int interface_read */
void module_register(void) {
ERROR("ipc plugin: semctl(2) failed: %s. "
"Maybe the kernel is not configured for semaphores?",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
ipc_submit_g("sem", "count", "arrays", seminfo.semusz);
ipc_submit_g("sem", "count", "total", seminfo.semaem);
- return (0);
+ return 0;
} /* }}} int ipc_read_sem */
static int ipc_read_shm(void) /* {{{ */
ERROR("ipc plugin: shmctl(2) failed: %s. "
"Maybe the kernel is not configured for shared memory?",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
ipc_submit_g("shm", "segments", NULL, shm_info.used_ids);
ipc_submit_g("shm", "bytes", "total", shm_info.shm_tot * pagesize_g);
ipc_submit_g("shm", "bytes", "rss", shm_info.shm_rss * pagesize_g);
ipc_submit_g("shm", "bytes", "swapped", shm_info.shm_swp * pagesize_g);
- return (0);
+ return 0;
}
/* }}} int ipc_read_shm */
if (msgctl(0, MSG_INFO, (struct msqid_ds *)(void *)&msginfo) < 0) {
ERROR("Kernel is not configured for message queues");
- return (-1);
+ return -1;
}
ipc_submit_g("msg", "count", "queues", msginfo.msgmni);
ipc_submit_g("msg", "count", "headers", msginfo.msgmap);
ipc_submit_g("msg", "count", "space", msginfo.msgtql);
- return (0);
+ return 0;
}
/* }}} int ipc_read_msg */
static int ipc_init(void) /* {{{ */
{
pagesize_g = sysconf(_SC_PAGESIZE);
- return (0);
+ return 0;
}
/* }}} */
/* #endif KERNEL_LINUX */
char errbuf[1024];
WARNING("ipc plugin: get_ipc_info: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (NULL);
+ return NULL;
}
}
if (size % stsize) {
ERROR("ipc plugin: ipc_get_info: missmatch struct size and buffer size");
- return (NULL);
+ return NULL;
}
*nmemb = size / stsize;
buff = malloc(size);
if (buff == NULL) {
ERROR("ipc plugin: ipc_get_info malloc failed.");
- return (NULL);
+ return NULL;
}
if (get_ipc_info(cid, cmd, version, buff, &size) < 0) {
WARNING("ipc plugin: get_ipc_info: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
free(buff);
- return (NULL);
+ return NULL;
}
return buff;
ipc_submit_g("sem", "count", "arrays", sem_nsems);
ipc_submit_g("sem", "count", "total", sems);
- return (0);
+ return 0;
} /* }}} int ipc_read_sem */
static int ipc_read_shm(void) /* {{{ */
ipc_submit_g("shm", "segments", NULL, shm_segments);
ipc_submit_g("shm", "bytes", "total", shm_bytes);
- return (0);
+ return 0;
}
/* }}} int ipc_read_shm */
ipc_submit_g("msg", "count", "headers", msg_qnum);
ipc_submit_g("msg", "count", "space", msg_used_space);
- return (0);
+ return 0;
}
/* }}} */
#endif /* KERNEL_AIX */
x |= ipc_read_sem();
x |= ipc_read_msg();
- return (x);
+ return x;
}
/* }}} */
plugin_register_read("ipc", ipc_read);
}
/* }}} */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
* Florian octo Forster <octo at collectd.org>
* Peter Holik <peter at holik.at>
* Bruno Prémont <bonbons at linux-vserver.org>
+ * Pavel Rochnyak <pavel2000 ngs.ru>
**/
#include "collectd.h"
#include "plugin.h"
#include "utils_ignorelist.h"
+#include <OpenIPMI/ipmi_auth.h>
#include <OpenIPMI/ipmi_conn.h>
#include <OpenIPMI/ipmi_err.h>
+#include <OpenIPMI/ipmi_lan.h>
#include <OpenIPMI/ipmi_posix.h>
#include <OpenIPMI/ipmi_smi.h>
#include <OpenIPMI/ipmiif.h>
+#define ERR_BUF_SIZE 1024
+
/*
* Private data types
*/
struct c_ipmi_sensor_list_s;
typedef struct c_ipmi_sensor_list_s c_ipmi_sensor_list_t;
+struct c_ipmi_instance_s {
+ char *name;
+ ignorelist_t *ignorelist;
+ _Bool notify_add;
+ _Bool notify_remove;
+ _Bool notify_notpresent;
+ _Bool notify_conn;
+ _Bool sel_enabled;
+ _Bool sel_clear_event;
+
+ char *host;
+ char *connaddr;
+ char *username;
+ char *password;
+ unsigned int authtype;
+
+ _Bool connected;
+ ipmi_con_t *connection;
+ pthread_mutex_t sensor_list_lock;
+ c_ipmi_sensor_list_t *sensor_list;
+
+ _Bool active;
+ pthread_t thread_id;
+ int init_in_progress;
+
+ struct c_ipmi_instance_s *next;
+};
+typedef struct c_ipmi_instance_s c_ipmi_instance_t;
+
struct c_ipmi_sensor_list_s {
ipmi_sensor_id_t sensor_id;
char sensor_name[DATA_MAX_NAME_LEN];
char sensor_type[DATA_MAX_NAME_LEN];
+ char type_instance[DATA_MAX_NAME_LEN];
int sensor_not_present;
c_ipmi_sensor_list_t *next;
+ c_ipmi_instance_t *instance;
+ unsigned int use;
};
+struct c_ipmi_db_type_map_s {
+ enum ipmi_unit_type_e type;
+ const char *type_name;
+};
+typedef struct c_ipmi_db_type_map_s c_ipmi_db_type_map_t;
+
/*
* Module global variables
*/
-static pthread_mutex_t sensor_list_lock = PTHREAD_MUTEX_INITIALIZER;
-static c_ipmi_sensor_list_t *sensor_list = NULL;
-
-static int c_ipmi_init_in_progress = 0;
-static int c_ipmi_active = 0;
-static pthread_t thread_id = (pthread_t)0;
-
-static const char *config_keys[] = {"Sensor", "IgnoreSelected",
- "NotifySensorAdd", "NotifySensorRemove",
- "NotifySensorNotPresent"};
-static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
-
-static ignorelist_t *ignorelist = NULL;
-
-static int c_ipmi_nofiy_add = 0;
-static int c_ipmi_nofiy_remove = 0;
-static int c_ipmi_nofiy_notpresent = 0;
+static os_handler_t *os_handler = NULL;
+static c_ipmi_instance_t *instances = NULL;
/*
* Misc private functions
*/
-static void c_ipmi_error(const char *func, int status) {
- char errbuf[4096] = {0};
+static void c_ipmi_error(c_ipmi_instance_t *st, const char *func, int status) {
+ char errbuf[ERR_BUF_SIZE] = {0};
- if (IPMI_IS_OS_ERR(status)) {
- sstrerror(IPMI_GET_OS_ERR(status), errbuf, sizeof(errbuf));
- } else if (IPMI_IS_IPMI_ERR(status)) {
- ipmi_get_error_string(IPMI_GET_IPMI_ERR(status), errbuf, sizeof(errbuf));
+ if (IPMI_IS_OS_ERR(status) || IPMI_IS_RMCPP_ERR(status) ||
+ IPMI_IS_IPMI_ERR(status)) {
+ ipmi_get_error_string(status, errbuf, sizeof(errbuf));
}
if (errbuf[0] == 0) {
- ssnprintf(errbuf, sizeof(errbuf), "Unknown error %#x", status);
+ snprintf(errbuf, sizeof(errbuf), "Unknown error %#x", status);
}
errbuf[sizeof(errbuf) - 1] = 0;
- ERROR("ipmi plugin: %s failed: %s", func, errbuf);
+ ERROR("ipmi plugin: %s failed for `%s`: %s", func, st->name, errbuf);
} /* void c_ipmi_error */
+static void c_ipmi_log(os_handler_t *handler, const char *format,
+ enum ipmi_log_type_e log_type, va_list ap) {
+ char msg[ERR_BUF_SIZE];
+
+ vsnprintf(msg, sizeof(msg), format, ap);
+
+ switch (log_type) {
+ case IPMI_LOG_INFO:
+ INFO("ipmi plugin: %s", msg);
+ break;
+ case IPMI_LOG_WARNING:
+ NOTICE("ipmi plugin: %s", msg);
+ break;
+ case IPMI_LOG_SEVERE:
+ WARNING("ipmi plugin: %s", msg);
+ break;
+ case IPMI_LOG_FATAL:
+ ERROR("ipmi plugin: %s", msg);
+ break;
+ case IPMI_LOG_ERR_INFO:
+ ERROR("ipmi plugin: %s", msg);
+ break;
+#if COLLECT_DEBUG
+ case IPMI_LOG_DEBUG_START:
+ case IPMI_LOG_DEBUG:
+ DEBUG("ipmi plugin: %s", msg);
+ break;
+ case IPMI_LOG_DEBUG_CONT:
+ case IPMI_LOG_DEBUG_END:
+ DEBUG("%s", msg);
+ break;
+#else
+ case IPMI_LOG_DEBUG_START:
+ case IPMI_LOG_DEBUG:
+ case IPMI_LOG_DEBUG_CONT:
+ case IPMI_LOG_DEBUG_END:
+ break;
+#endif
+ }
+} /* void c_ipmi_log */
+
+static notification_t c_ipmi_notification_init(c_ipmi_instance_t const *st,
+ int severity) {
+ notification_t n = {severity, cdtime(), "", "", "ipmi", "", "", "", NULL};
+
+ sstrncpy(n.host, (st->host != NULL) ? st->host : hostname_g, sizeof(n.host));
+ return n;
+} /* notification_t c_ipmi_notification_init */
+
/*
* Sensor handlers
*/
/* Prototype for sensor_list_remove, so sensor_read_handler can call it. */
-static int sensor_list_remove(ipmi_sensor_t *sensor);
+static int sensor_list_remove(c_ipmi_instance_t *st, ipmi_sensor_t *sensor);
static void sensor_read_handler(ipmi_sensor_t *sensor, int err,
enum ipmi_value_present_e value_present,
unsigned int __attribute__((unused)) raw_value,
- double value,
- ipmi_states_t __attribute__((unused)) * states,
+ double value, ipmi_states_t *states,
void *user_data) {
value_list_t vl = VALUE_LIST_INIT;
- c_ipmi_sensor_list_t *list_item = (c_ipmi_sensor_list_t *)user_data;
+ c_ipmi_sensor_list_t *list_item = user_data;
+ c_ipmi_instance_t *st = list_item->instance;
+
+ list_item->use--;
if (err != 0) {
- if ((err & 0xff) == IPMI_NOT_PRESENT_CC) {
+ if (IPMI_IS_IPMI_ERR(err) &&
+ IPMI_GET_IPMI_ERR(err) == IPMI_NOT_PRESENT_CC) {
if (list_item->sensor_not_present == 0) {
list_item->sensor_not_present = 1;
- INFO("ipmi plugin: sensor_read_handler: sensor %s "
+ INFO("ipmi plugin: sensor_read_handler: sensor `%s` of `%s` "
"not present.",
- list_item->sensor_name);
+ list_item->sensor_name, st->name);
- if (c_ipmi_nofiy_notpresent) {
- notification_t n = {
- NOTIF_WARNING, cdtime(), "", "", "ipmi", "", "", "", NULL};
+ if (st->notify_notpresent) {
+ notification_t n = c_ipmi_notification_init(st, NOTIF_WARNING);
- sstrncpy(n.host, hostname_g, sizeof(n.host));
- sstrncpy(n.type_instance, list_item->sensor_name,
+ sstrncpy(n.type_instance, list_item->type_instance,
sizeof(n.type_instance));
sstrncpy(n.type, list_item->sensor_type, sizeof(n.type));
- ssnprintf(n.message, sizeof(n.message), "sensor %s not present",
- list_item->sensor_name);
+ snprintf(n.message, sizeof(n.message), "sensor %s not present",
+ list_item->sensor_name);
plugin_dispatch_notification(&n);
}
} else if (IPMI_IS_IPMI_ERR(err) &&
IPMI_GET_IPMI_ERR(err) ==
IPMI_NOT_SUPPORTED_IN_PRESENT_STATE_CC) {
- INFO("ipmi plugin: sensor_read_handler: Sensor %s not ready",
- list_item->sensor_name);
+ INFO("ipmi plugin: sensor_read_handler: Sensor `%s` of `%s` not ready.",
+ list_item->sensor_name, st->name);
+ } else if (IPMI_IS_IPMI_ERR(err) &&
+ IPMI_GET_IPMI_ERR(err) == IPMI_TIMEOUT_CC) {
+ INFO("ipmi plugin: sensor_read_handler: Sensor `%s` of `%s` timed out.",
+ list_item->sensor_name, st->name);
} else {
+ char errbuf[ERR_BUF_SIZE] = {0};
+ ipmi_get_error_string(err, errbuf, sizeof(errbuf) - 1);
+
if (IPMI_IS_IPMI_ERR(err))
- INFO("ipmi plugin: sensor_read_handler: Removing sensor %s, "
- "because it failed with IPMI error %#x.",
- list_item->sensor_name, IPMI_GET_IPMI_ERR(err));
+ INFO("ipmi plugin: sensor_read_handler: Sensor `%s` of `%s` failed: "
+ "%s.",
+ list_item->sensor_name, st->name, errbuf);
else if (IPMI_IS_OS_ERR(err))
- INFO("ipmi plugin: sensor_read_handler: Removing sensor %s, "
- "because it failed with OS error %#x.",
- list_item->sensor_name, IPMI_GET_OS_ERR(err));
+ INFO("ipmi plugin: sensor_read_handler: Sensor `%s` of `%s` failed: "
+ "%s (%#x).",
+ list_item->sensor_name, st->name, errbuf, IPMI_GET_OS_ERR(err));
else if (IPMI_IS_RMCPP_ERR(err))
- INFO("ipmi plugin: sensor_read_handler: Removing sensor %s, "
- "because it failed with RMCPP error %#x.",
- list_item->sensor_name, IPMI_GET_RMCPP_ERR(err));
+ INFO("ipmi plugin: sensor_read_handler: Sensor `%s` of `%s` failed: "
+ "%s.",
+ list_item->sensor_name, st->name, errbuf);
else if (IPMI_IS_SOL_ERR(err))
- INFO("ipmi plugin: sensor_read_handler: Removing sensor %s, "
- "because it failed with RMCPP error %#x.",
- list_item->sensor_name, IPMI_GET_SOL_ERR(err));
+ INFO("ipmi plugin: sensor_read_handler: Sensor `%s` of `%s` failed: "
+ "%s (%#x).",
+ list_item->sensor_name, st->name, errbuf, IPMI_GET_SOL_ERR(err));
else
- INFO("ipmi plugin: sensor_read_handler: Removing sensor %s, "
- "because it failed with error %#x. of class %#x",
- list_item->sensor_name, err & 0xff, err & 0xffffff00);
- sensor_list_remove(sensor);
+ INFO("ipmi plugin: sensor_read_handler: Sensor `%s` of `%s` failed "
+ "with error %#x. of class %#x",
+ list_item->sensor_name, st->name, err & 0xff, err & 0xffffff00);
}
return;
} else if (list_item->sensor_not_present == 1) {
list_item->sensor_not_present = 0;
- INFO("ipmi plugin: sensor_read_handler: sensor %s present.",
- list_item->sensor_name);
+ INFO("ipmi plugin: sensor_read_handler: sensor `%s` of `%s` present.",
+ list_item->sensor_name, st->name);
- if (c_ipmi_nofiy_notpresent) {
- notification_t n = {NOTIF_OKAY, cdtime(), "", "", "ipmi",
- "", "", "", NULL};
+ if (st->notify_notpresent) {
+ notification_t n = c_ipmi_notification_init(st, NOTIF_OKAY);
- sstrncpy(n.host, hostname_g, sizeof(n.host));
- sstrncpy(n.type_instance, list_item->sensor_name,
+ sstrncpy(n.type_instance, list_item->type_instance,
sizeof(n.type_instance));
sstrncpy(n.type, list_item->sensor_type, sizeof(n.type));
- ssnprintf(n.message, sizeof(n.message), "sensor %s present",
- list_item->sensor_name);
+ snprintf(n.message, sizeof(n.message), "sensor %s present",
+ list_item->sensor_name);
plugin_dispatch_notification(&n);
}
}
if (value_present != IPMI_BOTH_VALUES_PRESENT) {
- INFO("ipmi plugin: sensor_read_handler: Removing sensor %s, "
+ INFO("ipmi plugin: sensor_read_handler: Removing sensor `%s` of `%s`, "
"because it provides %s. If you need this sensor, "
"please file a bug report.",
- list_item->sensor_name,
+ list_item->sensor_name, st->name,
(value_present == IPMI_RAW_VALUE_PRESENT) ? "only the raw value"
: "no value");
- sensor_list_remove(sensor);
+ sensor_list_remove(st, sensor);
+ return;
+ }
+
+ if (!ipmi_is_sensor_scanning_enabled(states)) {
+ DEBUG("ipmi plugin: sensor_read_handler: Skipping sensor `%s` of `%s`, "
+ "it is in 'scanning disabled' state.",
+ list_item->sensor_name, st->name);
+ return;
+ }
+
+ if (ipmi_is_initial_update_in_progress(states)) {
+ DEBUG("ipmi plugin: sensor_read_handler: Skipping sensor `%s` of `%s`, "
+ "it is in 'initial update in progress' state.",
+ list_item->sensor_name, st->name);
return;
}
vl.values = &(value_t){.gauge = value};
vl.values_len = 1;
+ if (st->host != NULL)
+ sstrncpy(vl.host, st->host, sizeof(vl.host));
sstrncpy(vl.plugin, "ipmi", sizeof(vl.plugin));
sstrncpy(vl.type, list_item->sensor_type, sizeof(vl.type));
- sstrncpy(vl.type_instance, list_item->sensor_name, sizeof(vl.type_instance));
+ sstrncpy(vl.type_instance, list_item->type_instance,
+ sizeof(vl.type_instance));
plugin_dispatch_values(&vl);
} /* void sensor_read_handler */
-static int sensor_list_add(ipmi_sensor_t *sensor) {
+static void sensor_get_name(ipmi_sensor_t *sensor, char *buffer, int buf_len) {
+ char temp[DATA_MAX_NAME_LEN] = {0};
+ ipmi_entity_t *ent = ipmi_sensor_get_entity(sensor);
+ const char *entity_id_string = ipmi_entity_get_entity_id_string(ent);
+ char sensor_name[DATA_MAX_NAME_LEN] = "";
+ char *sensor_name_ptr;
+
+ if ((buffer == NULL) || (buf_len == 0))
+ return;
+
+ ipmi_sensor_get_name(sensor, temp, sizeof(temp));
+ temp[sizeof(temp) - 1] = 0;
+
+ if (entity_id_string != NULL && strlen(temp))
+ snprintf(sensor_name, sizeof(sensor_name), "%s %s", temp, entity_id_string);
+ else if (entity_id_string != NULL)
+ sstrncpy(sensor_name, entity_id_string, sizeof(sensor_name));
+ else
+ sstrncpy(sensor_name, temp, sizeof(sensor_name));
+
+ if (strlen(temp)) {
+ sstrncpy(temp, sensor_name, sizeof(temp));
+ sensor_name_ptr = strstr(temp, ").");
+ if (sensor_name_ptr != NULL) {
+ /* If name is something like "foo (123).bar",
+ * change that to "bar (123)".
+ * Both, sensor_name_ptr and sensor_id_ptr point to memory within the
+ * `temp' array, which holds a copy of the current `sensor_name'. */
+ char *sensor_id_ptr;
+
+ /* `sensor_name_ptr' points to ").bar". */
+ sensor_name_ptr[1] = 0;
+ /* `temp' holds "foo (123)\0bar\0". */
+ sensor_name_ptr += 2;
+ /* `sensor_name_ptr' now points to "bar". */
+
+ sensor_id_ptr = strstr(temp, "(");
+ if (sensor_id_ptr != NULL) {
+ /* `sensor_id_ptr' now points to "(123)". */
+ snprintf(sensor_name, sizeof(sensor_name), "%s %s", sensor_name_ptr,
+ sensor_id_ptr);
+ }
+ /* else: don't touch sensor_name. */
+ }
+ }
+ sstrncpy(buffer, sensor_name, buf_len);
+}
+
+static const char *sensor_unit_to_type(ipmi_sensor_t *sensor) {
+ static const c_ipmi_db_type_map_t ipmi_db_type_map[] = {
+ {IPMI_UNIT_TYPE_WATTS, "power"}, {IPMI_UNIT_TYPE_CFM, "flow"}};
+
+ /* check the modifier and rate of the sensor value */
+ if ((ipmi_sensor_get_modifier_unit_use(sensor) != IPMI_MODIFIER_UNIT_NONE) ||
+ (ipmi_sensor_get_rate_unit(sensor) != IPMI_RATE_UNIT_NONE))
+ return NULL;
+
+ /* find the db type by using sensor base unit type */
+ enum ipmi_unit_type_e ipmi_type = ipmi_sensor_get_base_unit(sensor);
+ for (int i = 0; i < STATIC_ARRAY_SIZE(ipmi_db_type_map); i++)
+ if (ipmi_db_type_map[i].type == ipmi_type)
+ return ipmi_db_type_map[i].type_name;
+
+ return NULL;
+} /* const char* sensor_unit_to_type */
+
+static int sensor_list_add(c_ipmi_instance_t *st, ipmi_sensor_t *sensor) {
ipmi_sensor_id_t sensor_id;
c_ipmi_sensor_list_t *list_item;
c_ipmi_sensor_list_t *list_prev;
char buffer[DATA_MAX_NAME_LEN] = {0};
- const char *entity_id_string;
- char sensor_name[DATA_MAX_NAME_LEN];
- char *sensor_name_ptr;
+ char *sensor_name_ptr = buffer;
int sensor_type;
const char *type;
- ipmi_entity_t *ent = ipmi_sensor_get_entity(sensor);
sensor_id = ipmi_sensor_convert_to_id(sensor);
+ sensor_get_name(sensor, buffer, sizeof(buffer));
+
+ DEBUG("ipmi plugin: sensor_list_add: Found sensor `%s` of `%s`,"
+ " Type: %#x"
+ " Event reading type: %#x"
+ " Direction: %#x"
+ " Event support: %#x",
+ sensor_name_ptr, st->name, ipmi_sensor_get_sensor_type(sensor),
+ ipmi_sensor_get_event_reading_type(sensor),
+ ipmi_sensor_get_sensor_direction(sensor),
+ ipmi_sensor_get_event_support(sensor));
+
+ /* Both `ignorelist' and `sensor_name_ptr' may be NULL. */
+ if (ignorelist_match(st->ignorelist, sensor_name_ptr) != 0)
+ return 0;
- ipmi_sensor_get_name(sensor, buffer, sizeof(buffer));
- buffer[sizeof(buffer) - 1] = 0;
+ /* FIXME: Use rate unit or base unit to scale the value */
- entity_id_string = ipmi_entity_get_entity_id_string(ent);
+ sensor_type = ipmi_sensor_get_sensor_type(sensor);
- if (entity_id_string == NULL)
- sstrncpy(sensor_name, buffer, sizeof(sensor_name));
- else
- ssnprintf(sensor_name, sizeof(sensor_name), "%s %s", buffer,
- entity_id_string);
-
- sstrncpy(buffer, sensor_name, sizeof(buffer));
- sensor_name_ptr = strstr(buffer, ").");
- if (sensor_name_ptr != NULL) {
- /* If name is something like "foo (123).bar",
- * change that to "bar (123)".
- * Both, sensor_name_ptr and sensor_id_ptr point to memory within the
- * `buffer' array, which holds a copy of the current `sensor_name'. */
- char *sensor_id_ptr;
-
- /* `sensor_name_ptr' points to ").bar". */
- sensor_name_ptr[1] = 0;
- /* `buffer' holds "foo (123)\0bar\0". */
- sensor_name_ptr += 2;
- /* `sensor_name_ptr' now points to "bar". */
-
- sensor_id_ptr = strstr(buffer, "(");
- if (sensor_id_ptr != NULL) {
- /* `sensor_id_ptr' now points to "(123)". */
- ssnprintf(sensor_name, sizeof(sensor_name), "%s %s", sensor_name_ptr,
- sensor_id_ptr);
- }
- /* else: don't touch sensor_name. */
+ /*
+ * ipmitool/lib/ipmi_sdr.c sdr_sensor_has_analog_reading() has a notice
+ * about 'Threshold sensors' and 'analog readings'. Discrete sensor may
+ * have analog data, but discrete sensors support is not implemented
+ * in Collectd yet.
+ *
+ * ipmi_sensor_id_get_reading() supports only 'Threshold' sensors.
+ * See lib/sensor.c:4842, stand_ipmi_sensor_get_reading() for details.
+ */
+ if (!ipmi_sensor_get_is_readable(sensor)) {
+ INFO("ipmi plugin: sensor_list_add: Ignore sensor `%s` of `%s`, "
+ "because it isn't readable! Its type: (%#x, %s). ",
+ sensor_name_ptr, st->name, sensor_type,
+ ipmi_sensor_get_sensor_type_string(sensor));
+ return -1;
}
- sensor_name_ptr = sensor_name;
-
- /* Both `ignorelist' and `plugin_instance' may be NULL. */
- if (ignorelist_match(ignorelist, sensor_name_ptr) != 0)
- return (0);
- /* FIXME: Use rate unit or base unit to scale the value */
+ if (ipmi_sensor_get_event_reading_type(sensor) !=
+ IPMI_EVENT_READING_TYPE_THRESHOLD) {
+ INFO("ipmi plugin: sensor_list_add: Ignore sensor `%s` of `%s`, "
+ "because it is discrete (%#x)! Its type: (%#x, %s). ",
+ sensor_name_ptr, st->name, sensor_type,
+ ipmi_sensor_get_event_reading_type(sensor),
+ ipmi_sensor_get_sensor_type_string(sensor));
+ return -1;
+ }
- sensor_type = ipmi_sensor_get_sensor_type(sensor);
switch (sensor_type) {
case IPMI_SENSOR_TYPE_TEMPERATURE:
type = "temperature";
type = "fanspeed";
break;
+ case IPMI_SENSOR_TYPE_MEMORY:
+ type = "memory";
+ break;
+
default: {
- const char *sensor_type_str;
+ /* try to get collectd DB type based on sensor base unit type */
+ if ((type = sensor_unit_to_type(sensor)) != NULL)
+ break;
- sensor_type_str = ipmi_sensor_get_sensor_type_string(sensor);
- INFO("ipmi plugin: sensor_list_add: Ignore sensor %s, "
- "because I don't know how to handle its type (%#x, %s). "
- "If you need this sensor, please file a bug report.",
- sensor_name_ptr, sensor_type, sensor_type_str);
- return (-1);
+ INFO("ipmi plugin: sensor_list_add: Ignore sensor `%s` of `%s`, "
+ "because I don't know how to handle its units (%#x, %#x, %#x). "
+ "Sensor type: (%#x, %s). If you need this sensor, please file "
+ "a bug report at http://collectd.org/.",
+ sensor_name_ptr, st->name, ipmi_sensor_get_base_unit(sensor),
+ ipmi_sensor_get_modifier_unit(sensor),
+ ipmi_sensor_get_rate_unit(sensor), sensor_type,
+ ipmi_sensor_get_sensor_type_string(sensor));
+ return -1;
}
} /* switch (sensor_type) */
- pthread_mutex_lock(&sensor_list_lock);
+ pthread_mutex_lock(&st->sensor_list_lock);
list_prev = NULL;
- for (list_item = sensor_list; list_item != NULL;
+ for (list_item = st->sensor_list; list_item != NULL;
list_item = list_item->next) {
if (ipmi_cmp_sensor_id(sensor_id, list_item->sensor_id) == 0)
break;
} /* for (list_item) */
if (list_item != NULL) {
- pthread_mutex_unlock(&sensor_list_lock);
- return (0);
+ pthread_mutex_unlock(&st->sensor_list_lock);
+ return 0;
}
list_item = (c_ipmi_sensor_list_t *)calloc(1, sizeof(c_ipmi_sensor_list_t));
if (list_item == NULL) {
- pthread_mutex_unlock(&sensor_list_lock);
- return (-1);
+ pthread_mutex_unlock(&st->sensor_list_lock);
+ return -1;
}
+ list_item->instance = st;
list_item->sensor_id = ipmi_sensor_convert_to_id(sensor);
if (list_prev != NULL)
list_prev->next = list_item;
else
- sensor_list = list_item;
+ st->sensor_list = list_item;
+
+ /* if sensor provides the percentage value, use "percent" collectd type
+ and add the `percent` to the type instance of the reported value */
+ if (ipmi_sensor_get_percentage(sensor)) {
+ snprintf(list_item->type_instance, sizeof(list_item->type_instance),
+ "percent-%s", sensor_name_ptr);
+ type = "percent";
+ } else {
+ /* use type instance as a name of the sensor */
+ sstrncpy(list_item->type_instance, sensor_name_ptr,
+ sizeof(list_item->type_instance));
+ }
sstrncpy(list_item->sensor_name, sensor_name_ptr,
sizeof(list_item->sensor_name));
sstrncpy(list_item->sensor_type, type, sizeof(list_item->sensor_type));
- pthread_mutex_unlock(&sensor_list_lock);
+ pthread_mutex_unlock(&st->sensor_list_lock);
- if (c_ipmi_nofiy_add && (c_ipmi_init_in_progress == 0)) {
- notification_t n = {NOTIF_OKAY, cdtime(), "", "", "ipmi", "", "", "", NULL};
+ if (st->notify_add && (st->init_in_progress == 0)) {
+ notification_t n = c_ipmi_notification_init(st, NOTIF_OKAY);
- sstrncpy(n.host, hostname_g, sizeof(n.host));
- sstrncpy(n.type_instance, list_item->sensor_name, sizeof(n.type_instance));
+ sstrncpy(n.type_instance, list_item->type_instance,
+ sizeof(n.type_instance));
sstrncpy(n.type, list_item->sensor_type, sizeof(n.type));
- ssnprintf(n.message, sizeof(n.message), "sensor %s added",
- list_item->sensor_name);
+ snprintf(n.message, sizeof(n.message), "sensor %s added",
+ list_item->sensor_name);
plugin_dispatch_notification(&n);
}
- return (0);
+ return 0;
} /* int sensor_list_add */
-static int sensor_list_remove(ipmi_sensor_t *sensor) {
+static int sensor_list_remove(c_ipmi_instance_t *st, ipmi_sensor_t *sensor) {
ipmi_sensor_id_t sensor_id;
c_ipmi_sensor_list_t *list_item;
c_ipmi_sensor_list_t *list_prev;
sensor_id = ipmi_sensor_convert_to_id(sensor);
- pthread_mutex_lock(&sensor_list_lock);
+ pthread_mutex_lock(&st->sensor_list_lock);
list_prev = NULL;
- for (list_item = sensor_list; list_item != NULL;
+ for (list_item = st->sensor_list; list_item != NULL;
list_item = list_item->next) {
if (ipmi_cmp_sensor_id(sensor_id, list_item->sensor_id) == 0)
break;
} /* for (list_item) */
if (list_item == NULL) {
- pthread_mutex_unlock(&sensor_list_lock);
- return (-1);
+ pthread_mutex_unlock(&st->sensor_list_lock);
+ return -1;
}
if (list_prev == NULL)
- sensor_list = list_item->next;
+ st->sensor_list = list_item->next;
else
list_prev->next = list_item->next;
list_prev = NULL;
list_item->next = NULL;
- pthread_mutex_unlock(&sensor_list_lock);
+ pthread_mutex_unlock(&st->sensor_list_lock);
- if (c_ipmi_nofiy_remove && c_ipmi_active) {
- notification_t n = {NOTIF_WARNING, cdtime(), "", "", "ipmi", "", "", "",
- NULL};
+ if (st->notify_remove && st->active) {
+ notification_t n = c_ipmi_notification_init(st, NOTIF_WARNING);
- sstrncpy(n.host, hostname_g, sizeof(n.host));
- sstrncpy(n.type_instance, list_item->sensor_name, sizeof(n.type_instance));
+ sstrncpy(n.type_instance, list_item->type_instance,
+ sizeof(n.type_instance));
sstrncpy(n.type, list_item->sensor_type, sizeof(n.type));
- ssnprintf(n.message, sizeof(n.message), "sensor %s removed",
- list_item->sensor_name);
+ snprintf(n.message, sizeof(n.message), "sensor %s removed",
+ list_item->sensor_name);
plugin_dispatch_notification(&n);
}
free(list_item);
- return (0);
+ return 0;
} /* int sensor_list_remove */
-static int sensor_list_read_all(void) {
- pthread_mutex_lock(&sensor_list_lock);
+static int sensor_list_read_all(c_ipmi_instance_t *st) {
+ pthread_mutex_lock(&st->sensor_list_lock);
- for (c_ipmi_sensor_list_t *list_item = sensor_list; list_item != NULL;
+ for (c_ipmi_sensor_list_t *list_item = st->sensor_list; list_item != NULL;
list_item = list_item->next) {
+ DEBUG("ipmi plugin: try read sensor `%s` of `%s`, use: %d",
+ list_item->sensor_name, st->name, list_item->use);
+
+ /* Reading already initiated */
+ if (list_item->use)
+ continue;
+
+ list_item->use++;
ipmi_sensor_id_get_reading(list_item->sensor_id, sensor_read_handler,
- /* user data = */ list_item);
+ /* user data = */ (void *)list_item);
} /* for (list_item) */
- pthread_mutex_unlock(&sensor_list_lock);
+ pthread_mutex_unlock(&st->sensor_list_lock);
- return (0);
+ return 0;
} /* int sensor_list_read_all */
-static int sensor_list_remove_all(void) {
+static int sensor_list_remove_all(c_ipmi_instance_t *st) {
c_ipmi_sensor_list_t *list_item;
- pthread_mutex_lock(&sensor_list_lock);
+ pthread_mutex_lock(&st->sensor_list_lock);
- list_item = sensor_list;
- sensor_list = NULL;
+ list_item = st->sensor_list;
+ st->sensor_list = NULL;
- pthread_mutex_unlock(&sensor_list_lock);
+ pthread_mutex_unlock(&st->sensor_list_lock);
while (list_item != NULL) {
c_ipmi_sensor_list_t *list_next = list_item->next;
list_item = list_next;
} /* while (list_item) */
- return (0);
+ return 0;
} /* int sensor_list_remove_all */
+static int sensor_convert_threshold_severity(enum ipmi_thresh_e severity) {
+ switch (severity) {
+ case IPMI_LOWER_NON_CRITICAL:
+ case IPMI_UPPER_NON_CRITICAL:
+ return NOTIF_OKAY;
+ case IPMI_LOWER_CRITICAL:
+ case IPMI_UPPER_CRITICAL:
+ return NOTIF_WARNING;
+ case IPMI_LOWER_NON_RECOVERABLE:
+ case IPMI_UPPER_NON_RECOVERABLE:
+ return NOTIF_FAILURE;
+ default:
+ return NOTIF_OKAY;
+ } /* switch (severity) */
+} /* int sensor_convert_threshold_severity */
+
+static void add_event_common_data(notification_t *n, ipmi_sensor_t *sensor,
+ enum ipmi_event_dir_e dir,
+ ipmi_event_t *event) {
+ ipmi_entity_t *ent = ipmi_sensor_get_entity(sensor);
+
+ plugin_notification_meta_add_string(n, "entity_name",
+ ipmi_entity_get_entity_id_string(ent));
+ plugin_notification_meta_add_signed_int(n, "entity_id",
+ ipmi_entity_get_entity_id(ent));
+ plugin_notification_meta_add_signed_int(n, "entity_instance",
+ ipmi_entity_get_entity_instance(ent));
+ plugin_notification_meta_add_boolean(n, "assert", dir == IPMI_ASSERTION);
+
+ if (event)
+ plugin_notification_meta_add_signed_int(n, "event_type",
+ ipmi_event_get_type(event));
+} /* void add_event_sensor_meta_data */
+
+static int sensor_threshold_event_handler(
+ ipmi_sensor_t *sensor, enum ipmi_event_dir_e dir,
+ enum ipmi_thresh_e threshold, enum ipmi_event_value_dir_e high_low,
+ enum ipmi_value_present_e value_present, unsigned int raw_value,
+ double value, void *cb_data, ipmi_event_t *event) {
+
+ c_ipmi_instance_t *st = cb_data;
+
+ /* From the IPMI specification Chapter 2: Events.
+ * If a callback handles the event, then all future callbacks called due to
+ * the event will receive a NULL for the event. So be ready to handle a NULL
+ * event in all your event handlers. A NULL may also be passed to an event
+ * handler if the callback was not due to an event. */
+ if (event == NULL)
+ return IPMI_EVENT_NOT_HANDLED;
+
+ notification_t n = c_ipmi_notification_init(st, NOTIF_OKAY);
+ /* offset is a table index and it's represented as enum of strings that are
+ organized in the way - high and low for each threshold severity level */
+ unsigned int offset = (2 * threshold) + high_low;
+ unsigned int event_type = ipmi_sensor_get_event_reading_type(sensor);
+ unsigned int sensor_type = ipmi_sensor_get_sensor_type(sensor);
+ const char *event_state =
+ ipmi_get_reading_name(event_type, sensor_type, offset);
+ sensor_get_name(sensor, n.type_instance, sizeof(n.type_instance));
+ if (value_present != IPMI_NO_VALUES_PRESENT)
+ snprintf(n.message, sizeof(n.message),
+ "sensor %s received event: %s, value is %f", n.type_instance,
+ event_state, value);
+ else
+ snprintf(n.message, sizeof(n.message),
+ "sensor %s received event: %s, value not provided",
+ n.type_instance, event_state);
+
+ DEBUG("Threshold event received for sensor %s", n.type_instance);
+
+ sstrncpy(n.type, ipmi_sensor_get_sensor_type_string(sensor), sizeof(n.type));
+ n.severity = sensor_convert_threshold_severity(threshold);
+ n.time = NS_TO_CDTIME_T(ipmi_event_get_timestamp(event));
+
+ plugin_notification_meta_add_string(&n, "severity",
+ ipmi_get_threshold_string(threshold));
+ plugin_notification_meta_add_string(&n, "direction",
+ ipmi_get_value_dir_string(high_low));
+
+ switch (value_present) {
+ case IPMI_BOTH_VALUES_PRESENT:
+ plugin_notification_meta_add_double(&n, "val", value);
+ /* both values present, so fall-through to add raw value too */
+ case IPMI_RAW_VALUE_PRESENT: {
+ char buf[DATA_MAX_NAME_LEN] = {0};
+ snprintf(buf, sizeof(buf), "0x%2.2x", raw_value);
+ plugin_notification_meta_add_string(&n, "raw", buf);
+ } break;
+ default:
+ break;
+ } /* switch (value_present) */
+
+ add_event_common_data(&n, sensor, dir, event);
+
+ plugin_dispatch_notification(&n);
+ plugin_notification_meta_free(n.meta);
+
+ /* Delete handled ipmi event from the list */
+ if (st->sel_clear_event) {
+ ipmi_event_delete(event, NULL, NULL);
+ return IPMI_EVENT_HANDLED;
+ }
+
+ return IPMI_EVENT_NOT_HANDLED;
+} /* int sensor_threshold_event_handler */
+
+static int sensor_discrete_event_handler(ipmi_sensor_t *sensor,
+ enum ipmi_event_dir_e dir, int offset,
+ int severity, int prev_severity,
+ void *cb_data, ipmi_event_t *event) {
+
+ c_ipmi_instance_t *st = cb_data;
+
+ /* From the IPMI specification Chapter 2: Events.
+ * If a callback handles the event, then all future callbacks called due to
+ * the event will receive a NULL for the event. So be ready to handle a NULL
+ * event in all your event handlers. A NULL may also be passed to an event
+ * handler if the callback was not due to an event. */
+ if (event == NULL)
+ return IPMI_EVENT_NOT_HANDLED;
+
+ notification_t n = c_ipmi_notification_init(st, NOTIF_OKAY);
+ unsigned int event_type = ipmi_sensor_get_event_reading_type(sensor);
+ unsigned int sensor_type = ipmi_sensor_get_sensor_type(sensor);
+ const char *event_state =
+ ipmi_get_reading_name(event_type, sensor_type, offset);
+ sensor_get_name(sensor, n.type_instance, sizeof(n.type_instance));
+ snprintf(n.message, sizeof(n.message), "sensor %s received event: %s",
+ n.type_instance, event_state);
+
+ DEBUG("Discrete event received for sensor %s", n.type_instance);
+
+ sstrncpy(n.type, ipmi_sensor_get_sensor_type_string(sensor), sizeof(n.type));
+ n.time = NS_TO_CDTIME_T(ipmi_event_get_timestamp(event));
+
+ plugin_notification_meta_add_signed_int(&n, "offset", offset);
+
+ if (severity != -1)
+ plugin_notification_meta_add_signed_int(&n, "severity", severity);
+
+ if (prev_severity != -1)
+ plugin_notification_meta_add_signed_int(&n, "prevseverity", prev_severity);
+
+ add_event_common_data(&n, sensor, dir, event);
+
+ plugin_dispatch_notification(&n);
+ plugin_notification_meta_free(n.meta);
+
+ /* Delete handled ipmi event from the list */
+ if (st->sel_clear_event) {
+ ipmi_event_delete(event, NULL, NULL);
+ return IPMI_EVENT_HANDLED;
+ }
+
+ return IPMI_EVENT_NOT_HANDLED;
+} /* int sensor_discrete_event_handler */
+
/*
* Entity handlers
*/
-static void entity_sensor_update_handler(
- enum ipmi_update_e op, ipmi_entity_t __attribute__((unused)) * entity,
- ipmi_sensor_t *sensor, void __attribute__((unused)) * user_data) {
- /* TODO: Ignore sensors we cannot read */
+static void
+entity_sensor_update_handler(enum ipmi_update_e op,
+ ipmi_entity_t __attribute__((unused)) * entity,
+ ipmi_sensor_t *sensor, void *user_data) {
+ c_ipmi_instance_t *st = user_data;
if ((op == IPMI_ADDED) || (op == IPMI_CHANGED)) {
/* Will check for duplicate entries.. */
- sensor_list_add(sensor);
+ sensor_list_add(st, sensor);
+
+ if (st->sel_enabled) {
+ int status = 0;
+ /* register threshold event if threshold sensor support events */
+ if ((ipmi_sensor_get_event_reading_type(sensor) ==
+ IPMI_EVENT_READING_TYPE_THRESHOLD) &&
+ (ipmi_sensor_get_threshold_access(sensor) !=
+ IPMI_THRESHOLD_ACCESS_SUPPORT_NONE))
+ status = ipmi_sensor_add_threshold_event_handler(
+ sensor, sensor_threshold_event_handler, st);
+ /* register discrete handler if discrete/specific sensor support events */
+ else if (ipmi_sensor_get_event_support(sensor) != IPMI_EVENT_SUPPORT_NONE)
+ status = ipmi_sensor_add_discrete_event_handler(
+ sensor, sensor_discrete_event_handler, st);
+
+ if (status) {
+ char buf[DATA_MAX_NAME_LEN] = {0};
+ sensor_get_name(sensor, buf, sizeof(buf));
+ ERROR("Unable to add sensor %s event handler, status: %d", buf, status);
+ }
+ }
} else if (op == IPMI_DELETED) {
- sensor_list_remove(sensor);
+ sensor_list_remove(st, sensor);
+
+ if (st->sel_enabled) {
+ if (ipmi_sensor_get_event_reading_type(sensor) ==
+ IPMI_EVENT_READING_TYPE_THRESHOLD)
+ ipmi_sensor_remove_threshold_event_handler(
+ sensor, sensor_threshold_event_handler, st);
+ else
+ ipmi_sensor_remove_discrete_event_handler(
+ sensor, sensor_discrete_event_handler, st);
+ }
}
} /* void entity_sensor_update_handler */
/*
* Domain handlers
*/
-static void domain_entity_update_handler(
- enum ipmi_update_e op, ipmi_domain_t __attribute__((unused)) * domain,
- ipmi_entity_t *entity, void __attribute__((unused)) * user_data) {
+static void
+domain_entity_update_handler(enum ipmi_update_e op,
+ ipmi_domain_t __attribute__((unused)) * domain,
+ ipmi_entity_t *entity, void *user_data) {
int status;
+ c_ipmi_instance_t *st = user_data;
if (op == IPMI_ADDED) {
status = ipmi_entity_add_sensor_update_handler(
- entity, entity_sensor_update_handler, /* user data = */ NULL);
+ entity, entity_sensor_update_handler, /* user data = */ (void *)st);
if (status != 0) {
- c_ipmi_error("ipmi_entity_add_sensor_update_handler", status);
+ c_ipmi_error(st, "ipmi_entity_add_sensor_update_handler", status);
}
} else if (op == IPMI_DELETED) {
status = ipmi_entity_remove_sensor_update_handler(
- entity, entity_sensor_update_handler, /* user data = */ NULL);
+ entity, entity_sensor_update_handler, /* user data = */ (void *)st);
if (status != 0) {
- c_ipmi_error("ipmi_entity_remove_sensor_update_handler", status);
+ c_ipmi_error(st, "ipmi_entity_remove_sensor_update_handler", status);
}
}
} /* void domain_entity_update_handler */
+static void smi_event_handler(ipmi_con_t __attribute__((unused)) * ipmi,
+ const ipmi_addr_t __attribute__((unused)) * addr,
+ unsigned int __attribute__((unused)) addr_len,
+ ipmi_event_t *event, void *cb_data) {
+ unsigned int type = ipmi_event_get_type(event);
+ ipmi_domain_t *domain = cb_data;
+
+ DEBUG("%s: Event received: type %u", __FUNCTION__, type);
+
+ if (type != 0x02)
+ /* It's not a standard IPMI event. */
+ return;
+
+ /* force domain to reread SELs */
+ ipmi_domain_reread_sels(domain, NULL, NULL);
+}
+
static void domain_connection_change_handler(ipmi_domain_t *domain, int err,
unsigned int conn_num,
unsigned int port_num,
int still_connected,
void *user_data) {
- int status;
DEBUG("domain_connection_change_handler (domain = %p, err = %i, "
"conn_num = %u, port_num = %u, still_connected = %i, "
- "user_data = %p);\n",
+ "user_data = %p);",
(void *)domain, err, conn_num, port_num, still_connected, user_data);
- status = ipmi_domain_add_entity_update_handler(
- domain, domain_entity_update_handler, /* user data = */ NULL);
- if (status != 0) {
- c_ipmi_error("ipmi_domain_add_entity_update_handler", status);
+ c_ipmi_instance_t *st = user_data;
+
+ if (err != 0)
+ c_ipmi_error(st, "domain_connection_change_handler", err);
+
+ if (!still_connected) {
+
+ if (st->notify_conn && st->connected && st->init_in_progress == 0) {
+ notification_t n = c_ipmi_notification_init(st, NOTIF_FAILURE);
+
+ sstrncpy(n.message, "IPMI connection lost", sizeof(n.plugin));
+
+ plugin_dispatch_notification(&n);
+ }
+
+ st->connected = 0;
+ return;
}
-} /* void domain_connection_change_handler */
-static int thread_init(os_handler_t **ret_os_handler) {
- os_handler_t *os_handler;
- ipmi_con_t *smi_connection = NULL;
- ipmi_domain_id_t domain_id;
- int status;
+ if (st->notify_conn && !st->connected && st->init_in_progress == 0) {
+ notification_t n = c_ipmi_notification_init(st, NOTIF_OKAY);
- os_handler = ipmi_posix_thread_setup_os_handler(SIGIO);
- if (os_handler == NULL) {
- ERROR("ipmi plugin: ipmi_posix_thread_setup_os_handler failed.");
- return (-1);
+ sstrncpy(n.message, "IPMI connection restored", sizeof(n.plugin));
+
+ plugin_dispatch_notification(&n);
}
- ipmi_init(os_handler);
+ st->connected = 1;
- status = ipmi_smi_setup_con(/* if_num = */ 0, os_handler,
- /* user data = */ NULL, &smi_connection);
+ int status = ipmi_domain_add_entity_update_handler(
+ domain, domain_entity_update_handler, /* user data = */ st);
if (status != 0) {
- c_ipmi_error("ipmi_smi_setup_con", status);
- return (-1);
+ c_ipmi_error(st, "ipmi_domain_add_entity_update_handler", status);
}
- ipmi_open_option_t open_option[1] = {[0] = {.option = IPMI_OPEN_OPTION_ALL,
- {.ival = 1}}};
+ status = st->connection->add_event_handler(st->connection, smi_event_handler,
+ (void *)domain);
+ if (status != 0)
+ c_ipmi_error(st, "Failed to register smi event handler", status);
+} /* void domain_connection_change_handler */
+
+static int c_ipmi_thread_init(c_ipmi_instance_t *st) {
+ ipmi_domain_id_t domain_id;
+ int status;
+
+ if (st->connaddr != NULL) {
+ status = ipmi_ip_setup_con(
+ &st->connaddr, &(char *){IPMI_LAN_STD_PORT_STR}, 1, st->authtype,
+ (unsigned int)IPMI_PRIVILEGE_USER, st->username, strlen(st->username),
+ st->password, strlen(st->password), os_handler,
+ /* user data = */ NULL, &st->connection);
+ if (status != 0) {
+ c_ipmi_error(st, "ipmi_ip_setup_con", status);
+ return -1;
+ }
+ } else {
+ status = ipmi_smi_setup_con(/* if_num = */ 0, os_handler,
+ /* user data = */ NULL, &st->connection);
+ if (status != 0) {
+ c_ipmi_error(st, "ipmi_smi_setup_con", status);
+ return -1;
+ }
+ }
+
+ ipmi_open_option_t opts[] = {
+ {.option = IPMI_OPEN_OPTION_ALL, {.ival = 1}},
+#ifdef IPMI_OPEN_OPTION_USE_CACHE
+ /* OpenIPMI-2.0.17 and later: Disable SDR cache in local file */
+ {.option = IPMI_OPEN_OPTION_USE_CACHE, {.ival = 0}},
+#endif
+ };
+
+ /*
+ * NOTE: Domain names must be unique. There is static `domains_list` common
+ * to all threads inside lib/domain.c and some ops are done by name.
+ */
status = ipmi_open_domain(
- "mydomain", &smi_connection, /* num_con = */ 1,
- domain_connection_change_handler, /* user data = */ NULL,
- /* domain_fully_up_handler = */ NULL, /* user data = */ NULL, open_option,
- sizeof(open_option) / sizeof(open_option[0]), &domain_id);
+ st->name, &st->connection, /* num_con = */ 1,
+ domain_connection_change_handler, /* user data = */ (void *)st,
+ /* domain_fully_up_handler = */ NULL, /* user data = */ NULL, opts,
+ STATIC_ARRAY_SIZE(opts), &domain_id);
if (status != 0) {
- c_ipmi_error("ipmi_open_domain", status);
- return (-1);
+ c_ipmi_error(st, "ipmi_open_domain", status);
+ return -1;
}
- *ret_os_handler = os_handler;
- return (0);
-} /* int thread_init */
+ return 0;
+} /* int c_ipmi_thread_init */
-static void *thread_main(void __attribute__((unused)) * user_data) {
- int status;
- os_handler_t *os_handler = NULL;
+static void *c_ipmi_thread_main(void *user_data) {
+ c_ipmi_instance_t *st = user_data;
- status = thread_init(&os_handler);
+ int status = c_ipmi_thread_init(st);
if (status != 0) {
- ERROR("ipmi plugin: thread_init failed.\n");
- return ((void *)-1);
+ ERROR("ipmi plugin: c_ipmi_thread_init failed.");
+ st->active = 0;
+ return (void *)-1;
}
- while (c_ipmi_active != 0) {
+ while (st->active != 0) {
struct timeval tv = {1, 0};
os_handler->perform_one_op(os_handler, &tv);
}
+ return (void *)0;
+} /* void *c_ipmi_thread_main */
- ipmi_posix_thread_free_os_handler(os_handler);
-
- return ((void *)0);
-} /* void *thread_main */
-
-static int c_ipmi_config(const char *key, const char *value) {
- if (ignorelist == NULL)
- ignorelist = ignorelist_create(/* invert = */ 1);
- if (ignorelist == NULL)
- return (1);
-
- if (strcasecmp("Sensor", key) == 0) {
- ignorelist_add(ignorelist, value);
- } else if (strcasecmp("IgnoreSelected", key) == 0) {
- int invert = 1;
- if (IS_TRUE(value))
- invert = 0;
- ignorelist_set_invert(ignorelist, invert);
- } else if (strcasecmp("NotifySensorAdd", key) == 0) {
- if (IS_TRUE(value))
- c_ipmi_nofiy_add = 1;
- } else if (strcasecmp("NotifySensorRemove", key) == 0) {
- if (IS_TRUE(value))
- c_ipmi_nofiy_remove = 1;
- } else if (strcasecmp("NotifySensorNotPresent", key) == 0) {
- if (IS_TRUE(value))
- c_ipmi_nofiy_notpresent = 1;
- } else {
- return (-1);
+static c_ipmi_instance_t *c_ipmi_init_instance() {
+ c_ipmi_instance_t *st;
+
+ st = calloc(1, sizeof(*st));
+ if (st == NULL) {
+ ERROR("ipmi plugin: calloc failed.");
+ return NULL;
}
- return (0);
-} /* int c_ipmi_config */
+ st->name = strdup("main");
+ if (st->name == NULL) {
+ sfree(st);
+ ERROR("ipmi plugin: strdup() failed.");
+ return NULL;
+ }
-static int c_ipmi_init(void) {
- int status;
+ st->ignorelist = ignorelist_create(/* invert = */ 1);
+ if (st->ignorelist == NULL) {
+ sfree(st->name);
+ sfree(st);
+ ERROR("ipmi plugin: ignorelist_create() failed.");
+ return NULL;
+ }
- /* Don't send `ADD' notifications during startup (~ 1 minute) */
- time_t iv = CDTIME_T_TO_TIME_T(plugin_get_interval());
- c_ipmi_init_in_progress = 1 + (60 / iv);
+ st->sensor_list = NULL;
+ pthread_mutex_init(&st->sensor_list_lock, /* attr = */ NULL);
+
+ st->host = NULL;
+ st->connaddr = NULL;
+ st->username = NULL;
+ st->password = NULL;
+ st->authtype = IPMI_AUTHTYPE_DEFAULT;
+
+ st->next = NULL;
+
+ return st;
+} /* c_ipmi_instance_t *c_ipmi_init_instance */
+
+static void c_ipmi_free_instance(c_ipmi_instance_t *st) {
+ if (st == NULL)
+ return;
+
+ assert(st->next == NULL);
+
+ sfree(st->name);
+ sfree(st->host);
+ sfree(st->connaddr);
+ sfree(st->username);
+ sfree(st->password);
- c_ipmi_active = 1;
+ ignorelist_free(st->ignorelist);
+ pthread_mutex_destroy(&st->sensor_list_lock);
+ sfree(st);
+} /* void c_ipmi_free_instance */
+
+static void c_ipmi_add_instance(c_ipmi_instance_t *instance) {
+ if (instances == NULL) {
+ instances = instance;
+ return;
+ }
+
+ c_ipmi_instance_t *last = instances;
+
+ while (last->next != NULL)
+ last = last->next;
+
+ last->next = instance;
+} /* void c_ipmi_add_instance */
+
+static int c_ipmi_config_add_instance(oconfig_item_t *ci) {
+ int status = 0;
+ c_ipmi_instance_t *st = c_ipmi_init_instance();
+ if (st == NULL)
+ return ENOMEM;
+
+ if (strcasecmp(ci->key, "Instance") == 0)
+ status = cf_util_get_string(ci, &st->name);
- status = plugin_thread_create(&thread_id, /* attr = */ NULL, thread_main,
- /* user data = */ NULL, "ipmi");
if (status != 0) {
- c_ipmi_active = 0;
- thread_id = (pthread_t)0;
- ERROR("ipmi plugin: pthread_create failed.");
- return (-1);
+ c_ipmi_free_instance(st);
+ return status;
}
- return (0);
-} /* int c_ipmi_init */
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp("Sensor", child->key) == 0)
+ ignorelist_add(st->ignorelist, ci->values[0].value.string);
+ else if (strcasecmp("IgnoreSelected", child->key) == 0) {
+ _Bool t;
+ status = cf_util_get_boolean(child, &t);
+ if (status != 0)
+ break;
+ ignorelist_set_invert(st->ignorelist, /* invert = */ !t);
+ } else if (strcasecmp("NotifyIPMIConnectionState", child->key) == 0) {
+ status = cf_util_get_boolean(child, &st->notify_conn);
+ } else if (strcasecmp("NotifySensorAdd", child->key) == 0) {
+ status = cf_util_get_boolean(child, &st->notify_add);
+ } else if (strcasecmp("NotifySensorRemove", child->key) == 0) {
+ status = cf_util_get_boolean(child, &st->notify_remove);
+ } else if (strcasecmp("NotifySensorNotPresent", child->key) == 0) {
+ status = cf_util_get_boolean(child, &st->notify_notpresent);
+ } else if (strcasecmp("SELEnabled", child->key) == 0) {
+ status = cf_util_get_boolean(child, &st->sel_enabled);
+ } else if (strcasecmp("SELClearEvent", child->key) == 0) {
+ status = cf_util_get_boolean(child, &st->sel_clear_event);
+ } else if (strcasecmp("Host", child->key) == 0)
+ status = cf_util_get_string(child, &st->host);
+ else if (strcasecmp("Address", child->key) == 0)
+ status = cf_util_get_string(child, &st->connaddr);
+ else if (strcasecmp("Username", child->key) == 0)
+ status = cf_util_get_string(child, &st->username);
+ else if (strcasecmp("Password", child->key) == 0)
+ status = cf_util_get_string(child, &st->password);
+ else if (strcasecmp("AuthType", child->key) == 0) {
+ char tmp[8];
+ status = cf_util_get_string_buffer(child, tmp, sizeof(tmp));
+ if (status != 0)
+ break;
+
+ if (strcasecmp("MD5", tmp) == 0)
+ st->authtype = IPMI_AUTHTYPE_MD5;
+ else if (strcasecmp("rmcp+", tmp) == 0)
+ st->authtype = IPMI_AUTHTYPE_RMCP_PLUS;
+ else
+ WARNING("ipmi plugin: The value \"%s\" is not valid for the "
+ "\"AuthType\" option.",
+ tmp);
+ } else {
+ WARNING("ipmi plugin: Option `%s' not allowed here.", child->key);
+ status = -1;
+ }
-static int c_ipmi_read(void) {
- if ((c_ipmi_active == 0) || (thread_id == (pthread_t)0)) {
+ if (status != 0)
+ break;
+ }
+
+ if (status != 0) {
+ c_ipmi_free_instance(st);
+ return status;
+ }
+
+ c_ipmi_add_instance(st);
+
+ return 0;
+} /* int c_ipmi_config_add_instance */
+
+static int c_ipmi_config(oconfig_item_t *ci) {
+ _Bool have_instance_block = 0;
+
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp("Instance", child->key) == 0) {
+ int status = c_ipmi_config_add_instance(child);
+ if (status != 0)
+ return status;
+
+ have_instance_block = 1;
+ } else if (!have_instance_block) {
+ /* Non-instance option: Assume legacy configuration (without <Instance />
+ * blocks) and call c_ipmi_config_add_instance with the <Plugin /> block.
+ */
+ WARNING("ipmi plugin: Legacy configuration found! Please update your "
+ "config file.");
+ return c_ipmi_config_add_instance(ci);
+ } else {
+ WARNING("ipmi plugin: The configuration option "
+ "\"%s\" is not allowed here. Did you "
+ "forget to add an <Instance /> block "
+ "around the configuration?",
+ child->key);
+ return -1;
+ }
+ } /* for (ci->children) */
+
+ return 0;
+} /* int c_ipmi_config */
+
+static int c_ipmi_read(user_data_t *user_data) {
+ c_ipmi_instance_t *st = user_data->data;
+
+ if (st->active == 0) {
INFO("ipmi plugin: c_ipmi_read: I'm not active, returning false.");
- return (-1);
+ return -1;
}
- sensor_list_read_all();
+ if (st->connected == 0)
+ return 0;
- if (c_ipmi_init_in_progress > 0)
- c_ipmi_init_in_progress--;
+ sensor_list_read_all(st);
+
+ if (st->init_in_progress > 0)
+ st->init_in_progress--;
else
- c_ipmi_init_in_progress = 0;
+ st->init_in_progress = 0;
- return (0);
+ return 0;
} /* int c_ipmi_read */
+static int c_ipmi_init(void) {
+ c_ipmi_instance_t *st;
+ char callback_name[3 * DATA_MAX_NAME_LEN];
+
+ if (os_handler != NULL) {
+ return 0;
+ }
+
+ os_handler = ipmi_posix_thread_setup_os_handler(SIGIO);
+ if (os_handler == NULL) {
+ ERROR("ipmi plugin: ipmi_posix_thread_setup_os_handler failed.");
+ return -1;
+ }
+
+ os_handler->set_log_handler(os_handler, c_ipmi_log);
+
+ if (ipmi_init(os_handler) != 0) {
+ ERROR("ipmi plugin: ipmi_init() failed.");
+ os_handler->free_os_handler(os_handler);
+ return -1;
+ };
+
+ if (instances == NULL) {
+ /* No instances were configured, let's start a default instance. */
+ st = c_ipmi_init_instance();
+ if (st == NULL)
+ return ENOMEM;
+
+ c_ipmi_add_instance(st);
+ }
+
+ /* Don't send `ADD' notifications during startup (~ 1 minute) */
+ int cycles = 1 + (60 / CDTIME_T_TO_TIME_T(plugin_get_interval()));
+
+ st = instances;
+ while (NULL != st) {
+ /* The `st->name` is used as "domain name" for ipmi_open_domain().
+ * That value should be unique, so we do plugin_register_complex_read()
+ * at first as it checks the uniqueness. */
+ snprintf(callback_name, sizeof(callback_name), "ipmi/%s", st->name);
+
+ user_data_t ud = {
+ .data = st,
+ };
+
+ int status = plugin_register_complex_read(
+ /* group = */ "ipmi",
+ /* name = */ callback_name,
+ /* callback = */ c_ipmi_read,
+ /* interval = */ 0,
+ /* user_data = */ &ud);
+
+ if (status != 0) {
+ st = st->next;
+ continue;
+ }
+
+ st->init_in_progress = cycles;
+ st->active = 1;
+
+ status = plugin_thread_create(&st->thread_id, /* attr = */ NULL,
+ c_ipmi_thread_main,
+ /* user data = */ (void *)st, "ipmi");
+
+ if (status != 0) {
+ st->active = 0;
+ st->thread_id = (pthread_t){0};
+
+ plugin_unregister_read(callback_name);
+
+ ERROR("ipmi plugin: pthread_create failed for `%s`.", callback_name);
+ }
+
+ st = st->next;
+ }
+
+ return 0;
+} /* int c_ipmi_init */
+
static int c_ipmi_shutdown(void) {
- c_ipmi_active = 0;
+ c_ipmi_instance_t *st = instances;
+ instances = NULL;
- if (thread_id != (pthread_t)0) {
- pthread_join(thread_id, NULL);
- thread_id = (pthread_t)0;
+ while (st != NULL) {
+ c_ipmi_instance_t *next = st->next;
+
+ st->next = NULL;
+ st->active = 0;
+
+ if (!pthread_equal(st->thread_id, (pthread_t){0})) {
+ pthread_join(st->thread_id, NULL);
+ st->thread_id = (pthread_t){0};
+ }
+
+ sensor_list_remove_all(st);
+ c_ipmi_free_instance(st);
+
+ st = next;
}
- sensor_list_remove_all();
+ os_handler->free_os_handler(os_handler);
+ os_handler = NULL;
- return (0);
+ return 0;
} /* int c_ipmi_shutdown */
void module_register(void) {
- plugin_register_config("ipmi", c_ipmi_config, config_keys, config_keys_num);
+ plugin_register_complex_config("ipmi", c_ipmi_config);
plugin_register_init("ipmi", c_ipmi_init);
- 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 : */
else if (strcasecmp(key, "Chain6") == 0)
ip_version = IPV6;
else
- return (1);
+ return 1;
ip_chain_t temp = {0};
- ip_chain_t * final, **list;
+ ip_chain_t *final, **list;
char *table;
int table_len;
char *chain;
if (value_copy == NULL) {
char errbuf[1024];
ERROR("strdup failed: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
+ return 1;
}
/*
fields_num = strsplit(value_copy, fields, 4);
if (fields_num < 2) {
free(value_copy);
- return (1);
+ return 1;
}
table = fields[0];
if ((unsigned int)table_len > sizeof(temp.table)) {
ERROR("Table `%s' too long.", table);
free(value_copy);
- return (1);
+ return 1;
}
sstrncpy(temp.table, table, table_len);
if ((unsigned int)chain_len > sizeof(temp.chain)) {
ERROR("Chain `%s' too long.", chain);
free(value_copy);
- return (1);
+ return 1;
}
sstrncpy(temp.chain, chain, chain_len);
temp.rule.comment = strdup(comment);
if (temp.rule.comment == NULL) {
free(value_copy);
- return (1);
+ return 1;
}
temp.rule_type = RTYPE_COMMENT;
}
char errbuf[1024];
ERROR("realloc failed: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
sfree(temp.rule.comment);
- return (1);
+ return 1;
}
chain_list = list;
- final = malloc(sizeof(* final));
+ final = malloc(sizeof(*final));
if (final == NULL) {
char errbuf[1024];
ERROR("malloc failed: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
sfree(temp.rule.comment);
- return (1);
+ return 1;
}
memcpy(final, &temp, sizeof(temp));
chain_list[chain_num] = final;
DEBUG("Chain #%i: table = %s; chain = %s;", chain_num, final->table,
final->chain);
- return (0);
+ return 0;
} /* int iptables_config */
static int submit6_match(const struct ip6t_entry_match *match,
/* Select the rules to collect */
if (chain->rule_type == RTYPE_NUM) {
if (chain->rule.num != rule_num)
- return (0);
+ return 0;
} else {
if (strcmp(match->u.user.name, "comment") != 0)
- return (0);
+ return 0;
if ((chain->rule_type == RTYPE_COMMENT) &&
(strcmp(chain->rule.comment, (char *)match->data) != 0))
- return (0);
+ return 0;
}
sstrncpy(vl.plugin, "ip6tables", sizeof(vl.plugin));
- status = ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
- chain->table, chain->chain);
+ status = snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
+ chain->table, chain->chain);
if ((status < 1) || ((unsigned int)status >= sizeof(vl.plugin_instance)))
- return (0);
+ return 0;
if (chain->name[0] != '\0') {
sstrncpy(vl.type_instance, chain->name, sizeof(vl.type_instance));
} else {
if (chain->rule_type == RTYPE_NUM)
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%i",
- chain->rule.num);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%i",
+ chain->rule.num);
else
sstrncpy(vl.type_instance, (char *)match->data, sizeof(vl.type_instance));
}
vl.values = &(value_t){.derive = (derive_t)entry->counters.pcnt};
plugin_dispatch_values(&vl);
- return (0);
+ return 0;
} /* int submit6_match */
/* This needs to return `int' for IPT_MATCH_ITERATE to work. */
/* Select the rules to collect */
if (chain->rule_type == RTYPE_NUM) {
if (chain->rule.num != rule_num)
- return (0);
+ return 0;
} else {
if (strcmp(match->u.user.name, "comment") != 0)
- return (0);
+ return 0;
if ((chain->rule_type == RTYPE_COMMENT) &&
(strcmp(chain->rule.comment, (char *)match->data) != 0))
- return (0);
+ return 0;
}
sstrncpy(vl.plugin, "iptables", sizeof(vl.plugin));
- status = ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
- chain->table, chain->chain);
+ status = snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
+ chain->table, chain->chain);
if ((status < 1) || ((unsigned int)status >= sizeof(vl.plugin_instance)))
- return (0);
+ return 0;
if (chain->name[0] != '\0') {
sstrncpy(vl.type_instance, chain->name, sizeof(vl.type_instance));
} else {
if (chain->rule_type == RTYPE_NUM)
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%i",
- chain->rule.num);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%i",
+ chain->rule.num);
else
sstrncpy(vl.type_instance, (char *)match->data, sizeof(vl.type_instance));
}
vl.values = &(value_t){.derive = (derive_t)entry->counters.pcnt};
plugin_dispatch_values(&vl);
- return (0);
+ return 0;
} /* int submit_match */
/* ipv6 submit_chain */
num_failures++;
} /* for (i = 0 .. chain_num) */
- return ((num_failures < chain_num) ? 0 : -1);
+ return (num_failures < chain_num) ? 0 : -1;
} /* int iptables_read */
static int iptables_shutdown(void) {
}
sfree(chain_list);
- return (0);
+ return 0;
} /* int iptables_shutdown */
static int iptables_init(void) {
"running \"setcap cap_net_admin=ep\" on the collectd binary.");
}
#endif
- return (0);
+ return 0;
} /* int iptables_init */
void module_register(void) {
#include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
-/* this can probably only be found in the kernel sources */
-#if HAVE_LINUX_IP_VS_H
#include <linux/ip_vs.h>
-#elif HAVE_NET_IP_VS_H
-#include <net/ip_vs.h>
-#elif HAVE_IP_VS_H
-#include <ip_vs.h>
-#endif /* HAVE_IP_VS_H */
#define log_err(...) ERROR("ipvs: " __VA_ARGS__)
#define log_info(...) INFO("ipvs: " __VA_ARGS__)
*/
static struct ip_vs_get_services *ipvs_get_services(void) {
struct ip_vs_getinfo ipvs_info;
- struct ip_vs_get_services *ret;
+ struct ip_vs_get_services *services;
- socklen_t len;
+ socklen_t len = sizeof(ipvs_info);
- len = sizeof(ipvs_info);
-
- if (0 != getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_INFO, (void *)&ipvs_info,
- &len)) {
+ if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_INFO, &ipvs_info, &len) ==
+ -1) {
char errbuf[1024];
log_err("ip_vs_get_services: getsockopt() failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
return NULL;
}
- len = sizeof(*ret) +
+ len = sizeof(*services) +
sizeof(struct ip_vs_service_entry) * ipvs_info.num_services;
- if (NULL == (ret = malloc(len))) {
+ services = malloc(len);
+ if (services == NULL) {
log_err("ipvs_get_services: Out of memory.");
- exit(3);
+ return NULL;
}
- ret->num_services = ipvs_info.num_services;
+ services->num_services = ipvs_info.num_services;
- if (0 != getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_SERVICES, (void *)ret,
- &len)) {
+ if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_SERVICES, services, &len) ==
+ -1) {
char errbuf[1024];
log_err("ipvs_get_services: getsockopt failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- free(ret);
+ free(services);
return NULL;
}
- return ret;
+ return services;
} /* ipvs_get_services */
static struct ip_vs_get_dests *ipvs_get_dests(struct ip_vs_service_entry *se) {
- struct ip_vs_get_dests *ret;
- socklen_t len;
+ struct ip_vs_get_dests *dests;
- len = sizeof(*ret) + sizeof(struct ip_vs_dest_entry) * se->num_dests;
+ socklen_t len =
+ sizeof(*dests) + sizeof(struct ip_vs_dest_entry) * se->num_dests;
- if (NULL == (ret = malloc(len))) {
+ dests = malloc(len);
+ if (dests == NULL) {
log_err("ipvs_get_dests: Out of memory.");
- exit(3);
+ return NULL;
}
- ret->fwmark = se->fwmark;
- ret->protocol = se->protocol;
- ret->addr = se->addr;
- ret->port = se->port;
- ret->num_dests = se->num_dests;
+ dests->fwmark = se->fwmark;
+ dests->protocol = se->protocol;
+ dests->addr = se->addr;
+ dests->port = se->port;
+ dests->num_dests = se->num_dests;
- if (0 !=
- getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_DESTS, (void *)ret, &len)) {
+ if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_DESTS, dests, &len) == -1) {
char errbuf[1024];
log_err("ipvs_get_dests: getsockopt() failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- free(ret);
+ free(dests);
return NULL;
}
- return ret;
+ return dests;
} /* ip_vs_get_dests */
/*
static int cipvs_init(void) {
struct ip_vs_getinfo ipvs_info;
- socklen_t len;
-
- if (-1 == (sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))) {
+ if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) {
char errbuf[1024];
log_err("cipvs_init: socket() failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
return -1;
}
- len = sizeof(ipvs_info);
+ socklen_t len = sizeof(ipvs_info);
- if (0 != getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_INFO, (void *)&ipvs_info,
- &len)) {
+ if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_INFO, &ipvs_info, &len) ==
+ -1) {
char errbuf[1024];
log_err("cipvs_init: getsockopt() failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
/* plugin instance */
static int get_pi(struct ip_vs_service_entry *se, char *pi, size_t size) {
- struct in_addr addr;
- int len = 0;
-
- if ((NULL == se) || (NULL == pi))
+ if ((se == NULL) || (pi == NULL))
return 0;
- addr.s_addr = se->addr;
+ struct in_addr addr = {.s_addr = se->addr};
- /* inet_ntoa() returns a pointer to a statically allocated buffer
- * I hope non-glibc systems behave the same */
- len =
- ssnprintf(pi, size, "%s_%s%u", inet_ntoa(addr),
- (se->protocol == IPPROTO_TCP) ? "TCP" : "UDP", ntohs(se->port));
+ int len =
+ snprintf(pi, size, "%s_%s%u", inet_ntoa(addr),
+ (se->protocol == IPPROTO_TCP) ? "TCP" : "UDP", ntohs(se->port));
- if ((0 > len) || (size <= ((size_t)len))) {
+ if ((len < 0) || (size <= ((size_t)len))) {
log_err("plugin instance truncated: %s", pi);
return -1;
}
/* type instance */
static int get_ti(struct ip_vs_dest_entry *de, char *ti, size_t size) {
- struct in_addr addr;
- int len = 0;
-
- if ((NULL == de) || (NULL == ti))
+ if ((de == NULL) || (ti == NULL))
return 0;
- addr.s_addr = de->addr;
+ struct in_addr addr = {.s_addr = de->addr};
- /* inet_ntoa() returns a pointer to a statically allocated buffer
- * I hope non-glibc systems behave the same */
- len = ssnprintf(ti, size, "%s_%u", inet_ntoa(addr), ntohs(de->port));
+ int len = snprintf(ti, size, "%s_%u", inet_ntoa(addr), ntohs(de->port));
- if ((0 > len) || (size <= ((size_t)len))) {
+ if ((len < 0) || (size <= ((size_t)len))) {
log_err("type instance truncated: %s", ti);
return -1;
}
sstrncpy(vl.plugin, "ipvs", sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, pi, sizeof(vl.plugin_instance));
sstrncpy(vl.type, "connections", sizeof(vl.type));
- sstrncpy(vl.type_instance, (NULL != ti) ? ti : "total",
+ sstrncpy(vl.type_instance, (ti != NULL) ? ti : "total",
sizeof(vl.type_instance));
plugin_dispatch_values(&vl);
- return;
} /* cipvs_submit_connections */
static void cipvs_submit_if(const char *pi, const char *t, const char *ti,
sstrncpy(vl.plugin, "ipvs", sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, pi, sizeof(vl.plugin_instance));
sstrncpy(vl.type, t, sizeof(vl.type));
- sstrncpy(vl.type_instance, (NULL != ti) ? ti : "total",
+ sstrncpy(vl.type_instance, (ti != NULL) ? ti : "total",
sizeof(vl.type_instance));
plugin_dispatch_values(&vl);
- return;
} /* cipvs_submit_if */
static void cipvs_submit_dest(const char *pi, struct ip_vs_dest_entry *de) {
char ti[DATA_MAX_NAME_LEN];
- if (0 != get_ti(de, ti, sizeof(ti)))
+ if (get_ti(de, ti, sizeof(ti)) != 0)
return;
cipvs_submit_connections(pi, ti, stats.conns);
cipvs_submit_if(pi, "if_packets", ti, stats.inpkts, stats.outpkts);
cipvs_submit_if(pi, "if_octets", ti, stats.inbytes, stats.outbytes);
- return;
} /* cipvs_submit_dest */
static void cipvs_submit_service(struct ip_vs_service_entry *se) {
char pi[DATA_MAX_NAME_LEN];
- if (0 != get_pi(se, pi, sizeof(pi))) {
+ if (get_pi(se, pi, sizeof(pi)) != 0) {
free(dests);
return;
}
} /* cipvs_submit_service */
static int cipvs_read(void) {
- struct ip_vs_get_services *services = NULL;
-
if (sockfd < 0)
- return (-1);
+ return -1;
- if (NULL == (services = ipvs_get_services()))
+ struct ip_vs_get_services *services = ipvs_get_services();
+ if (services == NULL)
return -1;
for (size_t i = 0; i < services->num_services; ++i)
plugin_register_shutdown("ipvs", cipvs_shutdown);
return;
} /* module_register */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
invert = 0;
ignorelist_set_invert(ignorelist, invert);
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static void irq_submit(const char *irq_name, derive_t value) {
char errbuf[1024];
ERROR("irq plugin: fopen (/proc/interrupts): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
/* Get CPU count from the first line */
ERROR("irq plugin: unable to get CPU count from first line "
"of /proc/interrupts");
fclose(fh);
- return (-1);
+ return -1;
}
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
fclose(fh);
- return (0);
+ return 0;
} /* int irq_read */
void module_register(void) {
o_string = (*jvm_env)->NewStringUTF(jvm_env, (string != NULL) ? string : "");
if (o_string == NULL) {
ERROR("java plugin: ctoj_string: NewStringUTF failed.");
- return (-1);
+ return -1;
}
/* Search for the `void setFoo (String s)' method. */
ERROR("java plugin: ctoj_string: Cannot find method `void %s (String)'.",
method_name);
(*jvm_env)->DeleteLocalRef(jvm_env, o_string);
- return (-1);
+ return -1;
}
/* Call the method. */
/* Decrease reference counter on the java.lang.String object. */
(*jvm_env)->DeleteLocalRef(jvm_env, o_string);
- return (0);
+ return 0;
} /* }}} int ctoj_string */
static jstring ctoj_output_string(JNIEnv *jvm_env, /* {{{ */
return NULL;
}
- return (o_string);
+ return o_string;
} /* }}} int ctoj_output_string */
static int ctoj_int(JNIEnv *jvm_env, /* {{{ */
if (m_set == NULL) {
ERROR("java plugin: ctoj_int: Cannot find method `void %s (int)'.",
method_name);
- return (-1);
+ return -1;
}
(*jvm_env)->CallVoidMethod(jvm_env, object_ptr, m_set, value);
- return (0);
+ return 0;
} /* }}} int ctoj_int */
static int ctoj_long(JNIEnv *jvm_env, /* {{{ */
if (m_set == NULL) {
ERROR("java plugin: ctoj_long: Cannot find method `void %s (long)'.",
method_name);
- return (-1);
+ return -1;
}
(*jvm_env)->CallVoidMethod(jvm_env, object_ptr, m_set, value);
- return (0);
+ return 0;
} /* }}} int ctoj_long */
static int ctoj_double(JNIEnv *jvm_env, /* {{{ */
if (m_set == NULL) {
ERROR("java plugin: ctoj_double: Cannot find method `void %s (double)'.",
method_name);
- return (-1);
+ return -1;
}
(*jvm_env)->CallVoidMethod(jvm_env, object_ptr, m_set, value);
- return (0);
+ return 0;
} /* }}} int ctoj_double */
/* Convert a jlong to a java.lang.Number */
if (c_long == NULL) {
ERROR("java plugin: ctoj_jlong_to_number: Looking up the "
"java.lang.Long class failed.");
- return (NULL);
+ return NULL;
}
m_long_constructor =
if (m_long_constructor == NULL) {
ERROR("java plugin: ctoj_jlong_to_number: Looking up the "
"`Long (long)' constructor failed.");
- return (NULL);
+ return NULL;
}
- return ((*jvm_env)->NewObject(jvm_env, c_long, m_long_constructor, value));
+ return (*jvm_env)->NewObject(jvm_env, c_long, m_long_constructor, value);
} /* }}} jobject ctoj_jlong_to_number */
/* Convert a jdouble to a java.lang.Number */
if (c_double == NULL) {
ERROR("java plugin: ctoj_jdouble_to_number: Looking up the "
"java.lang.Double class failed.");
- return (NULL);
+ return NULL;
}
m_double_constructor =
if (m_double_constructor == NULL) {
ERROR("java plugin: ctoj_jdouble_to_number: Looking up the "
"`Double (double)' constructor failed.");
- return (NULL);
+ return NULL;
}
- return (
- (*jvm_env)->NewObject(jvm_env, c_double, m_double_constructor, value));
+ return (*jvm_env)->NewObject(jvm_env, c_double, m_double_constructor, value);
} /* }}} jobject ctoj_jdouble_to_number */
/* Convert a value_t to a java.lang.Number */
static jobject ctoj_value_to_number(JNIEnv *jvm_env, /* {{{ */
value_t value, int ds_type) {
if (ds_type == DS_TYPE_COUNTER)
- return (ctoj_jlong_to_number(jvm_env, (jlong)value.counter));
+ return ctoj_jlong_to_number(jvm_env, (jlong)value.counter);
else if (ds_type == DS_TYPE_GAUGE)
- return (ctoj_jdouble_to_number(jvm_env, (jdouble)value.gauge));
+ return ctoj_jdouble_to_number(jvm_env, (jdouble)value.gauge);
if (ds_type == DS_TYPE_DERIVE)
- return (ctoj_jlong_to_number(jvm_env, (jlong)value.derive));
+ return ctoj_jlong_to_number(jvm_env, (jlong)value.derive);
if (ds_type == DS_TYPE_ABSOLUTE)
- return (ctoj_jlong_to_number(jvm_env, (jlong)value.absolute));
+ return ctoj_jlong_to_number(jvm_env, (jlong)value.absolute);
else
- return (NULL);
+ return NULL;
} /* }}} jobject ctoj_value_to_number */
/* Convert a data_source_t to a org/collectd/api/DataSource */
if (c_datasource == NULL) {
ERROR("java plugin: ctoj_data_source: "
"FindClass (org/collectd/api/DataSource) failed.");
- return (NULL);
+ return NULL;
}
/* Lookup the `ValueList ()' constructor. */
if (m_datasource_constructor == NULL) {
ERROR("java plugin: ctoj_data_source: Cannot find the "
"`DataSource ()' constructor.");
- return (NULL);
+ return NULL;
}
/* Create a new instance. */
if (o_datasource == NULL) {
ERROR("java plugin: ctoj_data_source: "
"Creating a new DataSource instance failed.");
- return (NULL);
+ return NULL;
}
/* Set name via `void setName (String name)' */
ERROR("java plugin: ctoj_data_source: "
"ctoj_string (setName) failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_datasource);
- return (NULL);
+ return NULL;
}
/* Set type via `void setType (int type)' */
ERROR("java plugin: ctoj_data_source: "
"ctoj_int (setType) failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_datasource);
- return (NULL);
+ return NULL;
}
/* Set min via `void setMin (double min)' */
ERROR("java plugin: ctoj_data_source: "
"ctoj_double (setMin) failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_datasource);
- return (NULL);
+ return NULL;
}
/* Set max via `void setMax (double max)' */
ERROR("java plugin: ctoj_data_source: "
"ctoj_double (setMax) failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_datasource);
- return (NULL);
+ return NULL;
}
- return (o_datasource);
+ return o_datasource;
} /* }}} jobject ctoj_data_source */
/* Convert a oconfig_value_t to a org/collectd/api/OConfigValue */
if (c_ocvalue == NULL) {
ERROR("java plugin: ctoj_oconfig_value: "
"FindClass (org/collectd/api/OConfigValue) failed.");
- return (NULL);
+ return NULL;
}
if (ocvalue.type == OCONFIG_TYPE_BOOLEAN) {
if (m_ocvalue_constructor == NULL) {
ERROR("java plugin: ctoj_oconfig_value: Cannot find the "
"`OConfigValue (boolean)' constructor.");
- return (NULL);
+ return NULL;
}
- return ((*jvm_env)->NewObject(jvm_env, c_ocvalue, m_ocvalue_constructor,
- tmp_boolean));
+ return (*jvm_env)->NewObject(jvm_env, c_ocvalue, m_ocvalue_constructor,
+ tmp_boolean);
} /* if (ocvalue.type == OCONFIG_TYPE_BOOLEAN) */
else if (ocvalue.type == OCONFIG_TYPE_STRING) {
m_ocvalue_constructor = (*jvm_env)->GetMethodID(
if (m_ocvalue_constructor == NULL) {
ERROR("java plugin: ctoj_oconfig_value: Cannot find the "
"`OConfigValue (String)' constructor.");
- return (NULL);
+ return NULL;
}
o_argument = (*jvm_env)->NewStringUTF(jvm_env, ocvalue.value.string);
if (o_argument == NULL) {
ERROR("java plugin: ctoj_oconfig_value: "
"Creating a String object failed.");
- return (NULL);
+ return NULL;
}
} else if (ocvalue.type == OCONFIG_TYPE_NUMBER) {
m_ocvalue_constructor = (*jvm_env)->GetMethodID(
if (m_ocvalue_constructor == NULL) {
ERROR("java plugin: ctoj_oconfig_value: Cannot find the "
"`OConfigValue (Number)' constructor.");
- return (NULL);
+ return NULL;
}
o_argument = ctoj_jdouble_to_number(jvm_env, (jdouble)ocvalue.value.number);
if (o_argument == NULL) {
ERROR("java plugin: ctoj_oconfig_value: "
"Creating a Number object failed.");
- return (NULL);
+ return NULL;
}
} else {
- return (NULL);
+ return NULL;
}
assert(m_ocvalue_constructor != NULL);
ERROR("java plugin: ctoj_oconfig_value: "
"Creating an OConfigValue object failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_argument);
- return (NULL);
+ return NULL;
}
(*jvm_env)->DeleteLocalRef(jvm_env, o_argument);
- return (o_ocvalue);
+ return o_ocvalue;
} /* }}} jobject ctoj_oconfig_value */
/* Convert a oconfig_item_t to a org/collectd/api/OConfigItem */
if (c_ocitem == NULL) {
ERROR("java plugin: ctoj_oconfig_item: "
"FindClass (org/collectd/api/OConfigItem) failed.");
- return (NULL);
+ return NULL;
}
/* Get the required methods: m_ocitem_constructor, m_addvalue, and m_addchild
if (m_ocitem_constructor == NULL) {
ERROR("java plugin: ctoj_oconfig_item: Cannot find the "
"`OConfigItem (String)' constructor.");
- return (NULL);
+ return NULL;
}
m_addvalue = (*jvm_env)->GetMethodID(jvm_env, c_ocitem, "addValue",
if (m_addvalue == NULL) {
ERROR("java plugin: ctoj_oconfig_item: Cannot find the "
"`addValue (OConfigValue)' method.");
- return (NULL);
+ return NULL;
}
m_addchild = (*jvm_env)->GetMethodID(jvm_env, c_ocitem, "addChild",
if (m_addchild == NULL) {
ERROR("java plugin: ctoj_oconfig_item: Cannot find the "
"`addChild (OConfigItem)' method.");
- return (NULL);
+ return NULL;
}
/* }}} */
if (o_key == NULL) {
ERROR("java plugin: ctoj_oconfig_item: "
"Creating String object failed.");
- return (NULL);
+ return NULL;
}
/* Create an OConfigItem object */
ERROR("java plugin: ctoj_oconfig_item: "
"Creating an OConfigItem object failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_key);
- return (NULL);
+ return NULL;
}
/* We don't need the String object any longer.. */
ERROR("java plugin: ctoj_oconfig_item: "
"Creating an OConfigValue object failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_ocitem);
- return (NULL);
+ return NULL;
}
(*jvm_env)->CallVoidMethod(jvm_env, o_ocitem, m_addvalue, o_value);
ERROR("java plugin: ctoj_oconfig_item: "
"Creating an OConfigItem object failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_ocitem);
- return (NULL);
+ return NULL;
}
(*jvm_env)->CallVoidMethod(jvm_env, o_ocitem, m_addchild, o_child);
(*jvm_env)->DeleteLocalRef(jvm_env, o_child);
} /* }}} for (i = 0; i < ci->children_num; i++) */
- return (o_ocitem);
+ return o_ocitem;
} /* }}} jobject ctoj_oconfig_item */
/* Convert a data_set_t to a org/collectd/api/DataSet */
if (c_dataset == NULL) {
ERROR("java plugin: ctoj_data_set: Looking up the "
"org/collectd/api/DataSet class failed.");
- return (NULL);
+ return NULL;
}
/* Search for the `DataSet (String type)' constructor. */
if (m_constructor == NULL) {
ERROR("java plugin: ctoj_data_set: Looking up the "
"`DataSet (String)' constructor failed.");
- return (NULL);
+ return NULL;
}
/* Search for the `void addDataSource (DataSource)' method. */
if (m_add == NULL) {
ERROR("java plugin: ctoj_data_set: Looking up the "
"`addDataSource (DataSource)' method failed.");
- return (NULL);
+ return NULL;
}
o_type = (*jvm_env)->NewStringUTF(jvm_env, ds->type);
if (o_type == NULL) {
ERROR("java plugin: ctoj_data_set: Creating a String object failed.");
- return (NULL);
+ return NULL;
}
o_dataset = (*jvm_env)->NewObject(jvm_env, c_dataset, m_constructor, o_type);
if (o_dataset == NULL) {
ERROR("java plugin: ctoj_data_set: Creating a DataSet object failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_type);
- return (NULL);
+ return NULL;
}
/* Decrease reference counter on the java.lang.String object. */
ERROR("java plugin: ctoj_data_set: ctoj_data_source (%s.%s) failed",
ds->type, ds->ds[i].name);
(*jvm_env)->DeleteLocalRef(jvm_env, o_dataset);
- return (NULL);
+ return NULL;
}
(*jvm_env)->CallVoidMethod(jvm_env, o_dataset, m_add, o_datasource);
(*jvm_env)->DeleteLocalRef(jvm_env, o_datasource);
} /* for (i = 0; i < ds->ds_num; i++) */
- return (o_dataset);
+ return o_dataset;
} /* }}} jobject ctoj_data_set */
static int ctoj_value_list_add_value(JNIEnv *jvm_env, /* {{{ */
if (m_addvalue == NULL) {
ERROR("java plugin: ctoj_value_list_add_value: "
"Cannot find method `void addValue (Number)'.");
- return (-1);
+ return -1;
}
o_number = ctoj_value_to_number(jvm_env, value, ds_type);
if (o_number == NULL) {
ERROR("java plugin: ctoj_value_list_add_value: "
"ctoj_value_to_number failed.");
- return (-1);
+ return -1;
}
(*jvm_env)->CallVoidMethod(jvm_env, object_ptr, m_addvalue, o_number);
(*jvm_env)->DeleteLocalRef(jvm_env, o_number);
- return (0);
+ return 0;
} /* }}} int ctoj_value_list_add_value */
static int ctoj_value_list_add_data_set(JNIEnv *jvm_env, /* {{{ */
if (m_setdataset == NULL) {
ERROR("java plugin: ctoj_value_list_add_data_set: "
"Cannot find the `void setDataSet (DataSet)' method.");
- return (-1);
+ return -1;
}
/* Create a DataSet object. */
ERROR("java plugin: ctoj_value_list_add_data_set: "
"ctoj_data_set (%s) failed.",
ds->type);
- return (-1);
+ return -1;
}
/* Actually call the method. */
/* Decrease reference counter on the List<DataSource> object. */
(*jvm_env)->DeleteLocalRef(jvm_env, o_dataset);
- return (0);
+ return 0;
} /* }}} int ctoj_value_list_add_data_set */
/* Convert a value_list_t (and data_set_t) to a org/collectd/api/ValueList */
if (c_valuelist == NULL) {
ERROR("java plugin: ctoj_value_list: "
"FindClass (org/collectd/api/ValueList) failed.");
- return (NULL);
+ return NULL;
}
/* Lookup the `ValueList ()' constructor. */
if (m_valuelist_constructor == NULL) {
ERROR("java plugin: ctoj_value_list: Cannot find the "
"`ValueList ()' constructor.");
- return (NULL);
+ return NULL;
}
/* Create a new instance. */
if (o_valuelist == NULL) {
ERROR("java plugin: ctoj_value_list: Creating a new ValueList instance "
"failed.");
- return (NULL);
+ return NULL;
}
status = ctoj_value_list_add_data_set(jvm_env, c_valuelist, o_valuelist, ds);
ERROR("java plugin: ctoj_value_list: "
"ctoj_value_list_add_data_set failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_valuelist);
- return (NULL);
+ return NULL;
}
/* Set the strings.. */
ERROR("java plugin: ctoj_value_list: ctoj_string (%s) failed.", \
method_name); \
(*jvm_env)->DeleteLocalRef(jvm_env, o_valuelist); \
- return (NULL); \
+ return NULL; \
} \
} while (0)
if (status != 0) {
ERROR("java plugin: ctoj_value_list: ctoj_long (setTime) failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_valuelist);
- return (NULL);
+ return NULL;
}
/* Set the `interval' member.. */
if (status != 0) {
ERROR("java plugin: ctoj_value_list: ctoj_long (setInterval) failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_valuelist);
- return (NULL);
+ return NULL;
}
for (size_t i = 0; i < vl->values_len; i++) {
ERROR("java plugin: ctoj_value_list: "
"ctoj_value_list_add_value failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_valuelist);
- return (NULL);
+ return NULL;
}
}
- return (o_valuelist);
+ return o_valuelist;
} /* }}} jobject ctoj_value_list */
/* Convert a notification_t to a org/collectd/api/Notification */
if (c_notification == NULL) {
ERROR("java plugin: ctoj_notification: "
"FindClass (org/collectd/api/Notification) failed.");
- return (NULL);
+ return NULL;
}
/* Lookup the `Notification ()' constructor. */
if (m_constructor == NULL) {
ERROR("java plugin: ctoj_notification: Cannot find the "
"`Notification ()' constructor.");
- return (NULL);
+ return NULL;
}
/* Create a new instance. */
if (o_notification == NULL) {
ERROR("java plugin: ctoj_notification: Creating a new Notification "
"instance failed.");
- return (NULL);
+ return NULL;
}
/* Set the strings.. */
ERROR("java plugin: ctoj_notification: ctoj_string (%s) failed.", \
method_name); \
(*jvm_env)->DeleteLocalRef(jvm_env, o_notification); \
- return (NULL); \
+ return NULL; \
} \
} while (0)
if (status != 0) {
ERROR("java plugin: ctoj_notification: ctoj_long (setTime) failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_notification);
- return (NULL);
+ return NULL;
}
/* Set the `severity' member.. */
if (status != 0) {
ERROR("java plugin: ctoj_notification: ctoj_int (setSeverity) failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, o_notification);
- return (NULL);
+ return NULL;
}
- return (o_notification);
+ return o_notification;
} /* }}} jobject ctoj_notification */
/*
if (method_id == NULL) {
ERROR("java plugin: jtoc_string: Cannot find method `String %s ()'.",
method_name);
- return (-1);
+ return -1;
}
string_obj = (*jvm_env)->CallObjectMethod(jvm_env, object_ptr, method_id);
if ((string_obj == NULL) && (empty_okay == 0)) {
ERROR("java plugin: jtoc_string: CallObjectMethod (%s) failed.",
method_name);
- return (-1);
+ return -1;
} else if ((string_obj == NULL) && (empty_okay != 0)) {
memset(buffer, 0, buffer_size);
- return (0);
+ return 0;
}
c_str = (*jvm_env)->GetStringUTFChars(jvm_env, string_obj, 0);
if (c_str == NULL) {
ERROR("java plugin: jtoc_string: GetStringUTFChars failed.");
(*jvm_env)->DeleteLocalRef(jvm_env, string_obj);
- return (-1);
+ return -1;
}
sstrncpy(buffer, c_str, buffer_size);
(*jvm_env)->ReleaseStringUTFChars(jvm_env, string_obj, c_str);
(*jvm_env)->DeleteLocalRef(jvm_env, string_obj);
- return (0);
+ return 0;
} /* }}} int jtoc_string */
/* Call an `int <method> ()' method. */
if (method_id == NULL) {
ERROR("java plugin: jtoc_int: Cannot find method `int %s ()'.",
method_name);
- return (-1);
+ return -1;
}
*ret_value = (*jvm_env)->CallIntMethod(jvm_env, object_ptr, method_id);
- return (0);
+ return 0;
} /* }}} int jtoc_int */
/* Call a `long <method> ()' method. */
if (method_id == NULL) {
ERROR("java plugin: jtoc_long: Cannot find method `long %s ()'.",
method_name);
- return (-1);
+ return -1;
}
*ret_value = (*jvm_env)->CallLongMethod(jvm_env, object_ptr, method_id);
- return (0);
+ return 0;
} /* }}} int jtoc_long */
/* Call a `double <method> ()' method. */
if (method_id == NULL) {
ERROR("java plugin: jtoc_double: Cannot find method `double %s ()'.",
method_name);
- return (-1);
+ return -1;
}
*ret_value = (*jvm_env)->CallDoubleMethod(jvm_env, object_ptr, method_id);
- return (0);
+ return 0;
} /* }}} int jtoc_double */
static int jtoc_value(JNIEnv *jvm_env, /* {{{ */
if (status != 0) {
ERROR("java plugin: jtoc_value: "
"jtoc_double failed.");
- return (-1);
+ return -1;
}
(*ret_value).gauge = (gauge_t)tmp_double;
} else {
if (status != 0) {
ERROR("java plugin: jtoc_value: "
"jtoc_long failed.");
- return (-1);
+ return -1;
}
if (ds_type == DS_TYPE_DERIVE)
(*ret_value).counter = (counter_t)tmp_long;
}
- return (0);
+ return 0;
} /* }}} int jtoc_value */
/* Read a List<Number>, convert it to `value_t' and add it to the given
(*jvm_env)->DeleteLocalRef(jvm_env, o_number_array); \
if (o_list != NULL) \
(*jvm_env)->DeleteLocalRef(jvm_env, o_list); \
- return (status);
+ return status;
/* Call: List<Number> ValueList.getValues () */
m_getvalues = (*jvm_env)->GetMethodID(jvm_env, class_ptr, "getValues",
#undef BAIL_OUT
(*jvm_env)->DeleteLocalRef(jvm_env, o_number_array);
(*jvm_env)->DeleteLocalRef(jvm_env, o_list);
- return (0);
+ return 0;
} /* }}} int jtoc_values_array */
/* Convert a org/collectd/api/ValueList to a value_list_t. */
class_ptr = (*jvm_env)->GetObjectClass(jvm_env, object_ptr);
if (class_ptr == NULL) {
ERROR("java plugin: jtoc_value_list: GetObjectClass failed.");
- return (-1);
+ return -1;
}
/* eo == empty okay */
object_ptr, method); \
if (status != 0) { \
ERROR("java plugin: jtoc_value_list: jtoc_string (%s) failed.", method); \
- return (-1); \
+ return -1; \
} \
} while (0)
ERROR("java plugin: jtoc_value_list: Data-set `%s' is not defined. "
"Please consult the types.db(5) manpage for mor information.",
vl->type);
- return (-1);
+ return -1;
}
SET_STRING(vl->host, "getHost", /* empty = */ 0);
status = jtoc_long(jvm_env, &tmp_long, class_ptr, object_ptr, "getTime");
if (status != 0) {
ERROR("java plugin: jtoc_value_list: jtoc_long (getTime) failed.");
- return (-1);
+ return -1;
}
/* Java measures time in milliseconds. */
vl->time = MS_TO_CDTIME_T(tmp_long);
status = jtoc_long(jvm_env, &tmp_long, class_ptr, object_ptr, "getInterval");
if (status != 0) {
ERROR("java plugin: jtoc_value_list: jtoc_long (getInterval) failed.");
- return (-1);
+ return -1;
}
vl->interval = MS_TO_CDTIME_T(tmp_long);
status = jtoc_values_array(jvm_env, ds, vl, class_ptr, object_ptr);
if (status != 0) {
ERROR("java plugin: jtoc_value_list: jtoc_values_array failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int jtoc_value_list */
/* Convert a org/collectd/api/Notification to a notification_t. */
class_ptr = (*jvm_env)->GetObjectClass(jvm_env, object_ptr);
if (class_ptr == NULL) {
ERROR("java plugin: jtoc_notification: GetObjectClass failed.");
- return (-1);
+ return -1;
}
/* eo == empty okay */
if (status != 0) { \
ERROR("java plugin: jtoc_notification: jtoc_string (%s) failed.", \
method); \
- return (-1); \
+ return -1; \
} \
} while (0)
status = jtoc_long(jvm_env, &tmp_long, class_ptr, object_ptr, "getTime");
if (status != 0) {
ERROR("java plugin: jtoc_notification: jtoc_long (getTime) failed.");
- return (-1);
+ return -1;
}
/* Java measures time in milliseconds. */
n->time = MS_TO_CDTIME_T(tmp_long);
status = jtoc_int(jvm_env, &tmp_int, class_ptr, object_ptr, "getSeverity");
if (status != 0) {
ERROR("java plugin: jtoc_notification: jtoc_int (getSeverity) failed.");
- return (-1);
+ return -1;
}
n->severity = (int)tmp_int;
- return (0);
+ return 0;
} /* }}} int jtoc_notification */
- /*
- * Functions accessible from Java
- */
+/*
+ * Functions accessible from Java
+ */
static jint JNICALL cjni_api_dispatch_values(JNIEnv *jvm_env, /* {{{ */
jobject this, jobject java_vl) {
value_list_t vl = VALUE_LIST_INIT;
status = jtoc_value_list(jvm_env, &vl, java_vl);
if (status != 0) {
ERROR("java plugin: cjni_api_dispatch_values: jtoc_value_list failed.");
- return (-1);
+ return -1;
}
status = plugin_dispatch_values(&vl);
sfree(vl.values);
- return (status);
+ return status;
} /* }}} jint cjni_api_dispatch_values */
static jint JNICALL cjni_api_dispatch_notification(JNIEnv *jvm_env, /* {{{ */
if (status != 0) {
ERROR("java plugin: cjni_api_dispatch_notification: jtoc_notification "
"failed.");
- return (-1);
+ return -1;
}
status = plugin_dispatch_notification(&n);
- return (status);
+ return status;
} /* }}} jint cjni_api_dispatch_notification */
static jobject JNICALL cjni_api_get_ds(JNIEnv *jvm_env, /* {{{ */
ds_name = (*jvm_env)->GetStringUTFChars(jvm_env, o_string_type, 0);
if (ds_name == NULL) {
ERROR("java plugin: cjni_api_get_ds: GetStringUTFChars failed.");
- return (NULL);
+ return NULL;
}
ds = plugin_get_ds(ds_name);
(*jvm_env)->ReleaseStringUTFChars(jvm_env, o_string_type, ds_name);
if (ds == NULL)
- return (NULL);
+ return NULL;
o_dataset = ctoj_data_set(jvm_env, ds);
- return (o_dataset);
+ return o_dataset;
} /* }}} jint cjni_api_get_ds */
static jint JNICALL cjni_api_register_config(JNIEnv *jvm_env, /* {{{ */
jobject this, jobject o_name,
jobject o_config) {
- return (cjni_callback_register(jvm_env, o_name, o_config, CB_TYPE_CONFIG));
+ return cjni_callback_register(jvm_env, o_name, o_config, CB_TYPE_CONFIG);
} /* }}} jint cjni_api_register_config */
static jint JNICALL cjni_api_register_init(JNIEnv *jvm_env, /* {{{ */
jobject this, jobject o_name,
jobject o_config) {
- return (cjni_callback_register(jvm_env, o_name, o_config, CB_TYPE_INIT));
+ return cjni_callback_register(jvm_env, o_name, o_config, CB_TYPE_INIT);
} /* }}} jint cjni_api_register_init */
static jint JNICALL cjni_api_register_read(JNIEnv *jvm_env, /* {{{ */
cbi = cjni_callback_info_create(jvm_env, o_name, o_read, CB_TYPE_READ);
if (cbi == NULL)
- return (-1);
+ return -1;
DEBUG("java plugin: Registering new read callback: %s", cbi->name);
(*jvm_env)->DeleteLocalRef(jvm_env, o_read);
- return (0);
+ return 0;
} /* }}} jint cjni_api_register_read */
static jint JNICALL cjni_api_register_write(JNIEnv *jvm_env, /* {{{ */
cbi = cjni_callback_info_create(jvm_env, o_name, o_write, CB_TYPE_WRITE);
if (cbi == NULL)
- return (-1);
+ return -1;
DEBUG("java plugin: Registering new write callback: %s", cbi->name);
(*jvm_env)->DeleteLocalRef(jvm_env, o_write);
- return (0);
+ return 0;
} /* }}} jint cjni_api_register_write */
static jint JNICALL cjni_api_register_flush(JNIEnv *jvm_env, /* {{{ */
cbi = cjni_callback_info_create(jvm_env, o_name, o_flush, CB_TYPE_FLUSH);
if (cbi == NULL)
- return (-1);
+ return -1;
DEBUG("java plugin: Registering new flush callback: %s", cbi->name);
(*jvm_env)->DeleteLocalRef(jvm_env, o_flush);
- return (0);
+ return 0;
} /* }}} jint cjni_api_register_flush */
static jint JNICALL cjni_api_register_shutdown(JNIEnv *jvm_env, /* {{{ */
jobject this, jobject o_name,
jobject o_shutdown) {
- return (
- cjni_callback_register(jvm_env, o_name, o_shutdown, CB_TYPE_SHUTDOWN));
+ return cjni_callback_register(jvm_env, o_name, o_shutdown, CB_TYPE_SHUTDOWN);
} /* }}} jint cjni_api_register_shutdown */
static jint JNICALL cjni_api_register_log(JNIEnv *jvm_env, /* {{{ */
cbi = cjni_callback_info_create(jvm_env, o_name, o_log, CB_TYPE_LOG);
if (cbi == NULL)
- return (-1);
+ return -1;
DEBUG("java plugin: Registering new log callback: %s", cbi->name);
(*jvm_env)->DeleteLocalRef(jvm_env, o_log);
- return (0);
+ return 0;
} /* }}} jint cjni_api_register_log */
static jint JNICALL cjni_api_register_notification(JNIEnv *jvm_env, /* {{{ */
cbi = cjni_callback_info_create(jvm_env, o_name, o_notification,
CB_TYPE_NOTIFICATION);
if (cbi == NULL)
- return (-1);
+ return -1;
DEBUG("java plugin: Registering new notification callback: %s", cbi->name);
(*jvm_env)->DeleteLocalRef(jvm_env, o_notification);
- return (0);
+ return 0;
} /* }}} jint cjni_api_register_notification */
static jint JNICALL cjni_api_register_match_target(JNIEnv *jvm_env, /* {{{ */
if (c_name == NULL) {
ERROR("java plugin: cjni_api_register_match_target: "
"GetStringUTFChars failed.");
- return (-1);
+ return -1;
}
status = cjni_callback_register(jvm_env, o_name, o_match, type);
if (status != 0) {
(*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name);
- return (-1);
+ return -1;
}
if (type == CB_TYPE_MATCH) {
ERROR("java plugin: cjni_api_register_match_target: "
"Don't know whether to create a match or a target.");
(*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name);
- return (-1);
+ return -1;
}
if (status != 0) {
"%s failed.",
(type == CB_TYPE_MATCH) ? "fc_register_match" : "fc_register_target");
(*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name);
- return (-1);
+ return -1;
}
(*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name);
- return (0);
+ return 0;
} /* }}} jint cjni_api_register_match_target */
static jint JNICALL cjni_api_register_match(JNIEnv *jvm_env, /* {{{ */
jobject this, jobject o_name,
jobject o_match) {
- return (cjni_api_register_match_target(jvm_env, this, o_name, o_match,
- CB_TYPE_MATCH));
+ return cjni_api_register_match_target(jvm_env, this, o_name, o_match,
+ CB_TYPE_MATCH);
} /* }}} jint cjni_api_register_match */
static jint JNICALL cjni_api_register_target(JNIEnv *jvm_env, /* {{{ */
jobject this, jobject o_name,
jobject o_target) {
- return (cjni_api_register_match_target(jvm_env, this, o_name, o_target,
- CB_TYPE_TARGET));
+ return cjni_api_register_match_target(jvm_env, this, o_name, o_target,
+ CB_TYPE_TARGET);
} /* }}} jint cjni_api_register_target */
static void JNICALL cjni_api_log(JNIEnv *jvm_env, /* {{{ */
default:
ERROR("java plugin: cjni_callback_info_create: Unknown type: %#x", type);
- return (NULL);
+ return NULL;
}
c_name = (*jvm_env)->GetStringUTFChars(jvm_env, o_name, 0);
if (c_name == NULL) {
ERROR("java plugin: cjni_callback_info_create: "
"GetStringUTFChars failed.");
- return (NULL);
+ return NULL;
}
cbi = calloc(1, sizeof(*cbi));
if (cbi == NULL) {
ERROR("java plugin: cjni_callback_info_create: calloc failed.");
(*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name);
- return (NULL);
+ return NULL;
}
cbi->type = type;
ERROR("java plugin: cjni_callback_info_create: strdup failed.");
(*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name);
sfree(cbi);
- return (NULL);
+ return NULL;
}
(*jvm_env)->ReleaseStringUTFChars(jvm_env, o_name, c_name);
ERROR("java plugin: cjni_callback_info_create: NewGlobalRef failed.");
sfree(cbi->name);
sfree(cbi);
- return (NULL);
+ return NULL;
}
cbi->class = (*jvm_env)->GetObjectClass(jvm_env, cbi->object);
(*jvm_env)->DeleteGlobalRef(jvm_env, cbi->object);
sfree(cbi->name);
sfree(cbi);
- return (NULL);
+ return NULL;
}
cbi->method = (*jvm_env)->GetMethodID(jvm_env, cbi->class, method_name,
(*jvm_env)->DeleteGlobalRef(jvm_env, cbi->object);
sfree(cbi->name);
sfree(cbi);
- return (NULL);
+ return NULL;
}
- return (cbi);
+ return cbi;
} /* }}} cjni_callback_info_t cjni_callback_info_create */
/* Allocate a `cjni_callback_info_t' via `cjni_callback_info_create' and add it
cbi = cjni_callback_info_create(jvm_env, o_name, o_callback, type);
if (cbi == NULL)
- return (-1);
+ return -1;
#if COLLECT_DEBUG
switch (type) {
(*jvm_env)->DeleteGlobalRef(jvm_env, cbi->object);
free(cbi);
- return (-1);
+ return -1;
}
java_callbacks = tmp;
java_callbacks[java_callbacks_num] = *cbi;
pthread_mutex_unlock(&java_callbacks_lock);
free(cbi);
- return (0);
+ return 0;
} /* }}} int cjni_callback_register */
/* Callback for `pthread_key_create'. It frees the data contained in
ERROR("cjni_init_native: Cannot find the API class \"org.collectd.api"
".Collectd\". Please set the correct class path "
"using 'JVMArg \"-Djava.class.path=...\"'.");
- return (-1);
+ return -1;
}
status = (*jvm_env)->RegisterNatives(
jvm_env, api_class_ptr, jni_api_functions, (jint)jni_api_functions_num);
if (status != 0) {
ERROR("cjni_init_native: RegisterNatives failed with status %i.", status);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cjni_init_native */
/* Create the JVM. This is called when the first thread tries to access the JVM
int status;
if (jvm != NULL)
- return (0);
+ return 0;
status = pthread_key_create(&jvm_env_key, cjni_jvm_env_destroy);
if (status != 0) {
ERROR("java plugin: cjni_create_jvm: pthread_key_create failed "
"with status %i.",
status);
- return (-1);
+ return -1;
}
jvm_env = NULL;
ERROR("java plugin: cjni_create_jvm: "
"JNI_CreateJavaVM failed with status %i.",
status);
- return (-1);
+ return -1;
}
assert(jvm != NULL);
assert(jvm_env != NULL);
status = cjni_init_native(jvm_env);
if (status != 0) {
ERROR("java plugin: cjni_create_jvm: cjni_init_native failed.");
- return (-1);
+ return -1;
}
DEBUG("java plugin: The JVM has been created.");
- return (0);
+ return 0;
} /* }}} int cjni_create_jvm */
/* Increase the reference counter to the JVM for this thread. If it was zero,
status = cjni_create_jvm();
if (status != 0) {
ERROR("java plugin: cjni_thread_attach: cjni_create_jvm failed.");
- return (NULL);
+ return NULL;
}
}
assert(jvm != NULL);
cjni_env = calloc(1, sizeof(*cjni_env));
if (cjni_env == NULL) {
ERROR("java plugin: cjni_thread_attach: calloc failed.");
- return (NULL);
+ return NULL;
}
cjni_env->reference_counter = 0;
cjni_env->jvm_env = NULL;
ERROR("java plugin: cjni_thread_attach: AttachCurrentThread failed "
"with status %i.",
status);
- return (NULL);
+ return NULL;
}
cjni_env->reference_counter = 1;
DEBUG("java plugin: cjni_thread_attach: cjni_env->reference_counter = %i",
cjni_env->reference_counter);
assert(jvm_env != NULL);
- return (jvm_env);
+ return jvm_env;
} /* }}} JNIEnv *cjni_thread_attach */
/* Decrease the reference counter of this thread. If it reaches zero, detach
cjni_env = pthread_getspecific(jvm_env_key);
if (cjni_env == NULL) {
ERROR("java plugin: cjni_thread_detach: pthread_getspecific failed.");
- return (-1);
+ return -1;
}
assert(cjni_env->reference_counter > 0);
cjni_env->reference_counter);
if (cjni_env->reference_counter > 0)
- return (0);
+ return 0;
status = (*jvm)->DetachCurrentThread(jvm);
if (status != 0) {
cjni_env->reference_counter = 0;
cjni_env->jvm_env = NULL;
- return (0);
+ return 0;
} /* }}} int cjni_thread_detach */
static int cjni_config_add_jvm_arg(oconfig_item_t *ci) /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("java plugin: `JVMArg' needs exactly one string argument.");
- return (-1);
+ return -1;
}
if (jvm != NULL) {
"`LoadPlugin' options! The JVM is already started and I have to "
"ignore this argument: %s",
ci->values[0].value.string);
- return (-1);
+ return -1;
}
tmp = realloc(jvm_argv, sizeof(char *) * (jvm_argc + 1));
if (tmp == NULL) {
ERROR("java plugin: realloc failed.");
- return (-1);
+ return -1;
}
jvm_argv = tmp;
jvm_argv[jvm_argc] = strdup(ci->values[0].value.string);
if (jvm_argv[jvm_argc] == NULL) {
ERROR("java plugin: strdup failed.");
- return (-1);
+ return -1;
}
jvm_argc++;
- return (0);
+ return 0;
} /* }}} int cjni_config_add_jvm_arg */
static int cjni_config_load_plugin(oconfig_item_t *ci) /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("java plugin: `LoadPlugin' needs exactly one string argument.");
- return (-1);
+ return -1;
}
jvm_env = cjni_thread_attach();
if (jvm_env == NULL)
- return (-1);
+ return -1;
class = realloc(java_classes_list,
(java_classes_list_len + 1) * sizeof(*java_classes_list));
if (class == NULL) {
ERROR("java plugin: realloc failed.");
cjni_thread_detach();
- return (-1);
+ return -1;
}
java_classes_list = class;
class = java_classes_list + java_classes_list_len;
if (class->name == NULL) {
ERROR("java plugin: strdup failed.");
cjni_thread_detach();
- return (-1);
+ return -1;
}
class->class = NULL;
class->object = NULL;
class->name);
cjni_thread_detach();
free(class->name);
- return (-1);
+ return -1;
}
constructor_id =
class->name);
cjni_thread_detach();
free(class->name);
- return (-1);
+ return -1;
}
tmp_object = (*jvm_env)->NewObject(jvm_env, class->class, constructor_id);
class->name);
cjni_thread_detach();
free(class->name);
- return (-1);
+ return -1;
}
cjni_thread_detach();
java_classes_list_len++;
- return (0);
+ return 0;
} /* }}} int cjni_config_load_plugin */
static int cjni_config_plugin_block(oconfig_item_t *ci) /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("java plugin: `Plugin' blocks "
"need exactly one string argument.");
- return (-1);
+ return -1;
}
name = ci->values[0].value.string;
"configuration callback has been registered. Please make sure, the "
"`LoadPlugin' lines precede the `Plugin' blocks.",
name);
- return (0);
+ return 0;
}
DEBUG("java plugin: Configuring %s", name);
jvm_env = cjni_thread_attach();
if (jvm_env == NULL)
- return (-1);
+ return -1;
o_ocitem = ctoj_oconfig_item(jvm_env, ci);
if (o_ocitem == NULL) {
ERROR("java plugin: cjni_config_plugin_block: ctoj_oconfig_item failed.");
cjni_thread_detach();
- return (-1);
+ return -1;
}
class = (*jvm_env)->GetObjectClass(jvm_env, cbi->object);
(*jvm_env)->DeleteLocalRef(jvm_env, o_ocitem);
cjni_thread_detach();
- return (0);
+ return 0;
} /* }}} int cjni_config_plugin_block */
static int cjni_config_perform(oconfig_item_t *ci) /* {{{ */
if ((success == 0) && (errors > 0)) {
ERROR("java plugin: All statements failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cjni_config_perform */
/* Copy the children of `ci' to the global `config_block' variable. */
assert(ci != NULL);
if (ci->children_num == 0)
- return (0); /* nothing to do */
+ return 0; /* nothing to do */
ci_copy = oconfig_clone(ci);
if (ci_copy == NULL) {
ERROR("java plugin: oconfig_clone failed.");
- return (-1);
+ return -1;
}
if (config_block == NULL) {
config_block = ci_copy;
- return (0);
+ return 0;
}
tmp = realloc(config_block->children,
if (tmp == NULL) {
ERROR("java plugin: realloc failed.");
oconfig_free(ci_copy);
- return (-1);
+ return -1;
}
config_block->children = tmp;
oconfig_free(ci_copy);
- return (0);
+ return 0;
} /* }}} int cjni_config_callback */
/* Free the data contained in the `user_data_t' pointer passed to `cjni_read'
if (jvm == NULL) {
ERROR("java plugin: cjni_read: jvm == NULL");
- return (-1);
+ return -1;
}
if ((ud == NULL) || (ud->data == NULL)) {
ERROR("java plugin: cjni_read: Invalid user data.");
- return (-1);
+ return -1;
}
jvm_env = cjni_thread_attach();
if (jvm_env == NULL)
- return (-1);
+ return -1;
cbi = (cjni_callback_info_t *)ud->data;
ret_status = (*jvm_env)->CallIntMethod(jvm_env, cbi->object, cbi->method);
cjni_thread_detach();
- return (ret_status);
+ return ret_status;
} /* }}} int cjni_read */
/* Call the CB_TYPE_WRITE callback pointed to by the `user_data_t' pointer. */
if (jvm == NULL) {
ERROR("java plugin: cjni_write: jvm == NULL");
- return (-1);
+ return -1;
}
if ((ud == NULL) || (ud->data == NULL)) {
ERROR("java plugin: cjni_write: Invalid user data.");
- return (-1);
+ return -1;
}
jvm_env = cjni_thread_attach();
if (jvm_env == NULL)
- return (-1);
+ return -1;
cbi = (cjni_callback_info_t *)ud->data;
if (vl_java == NULL) {
ERROR("java plugin: cjni_write: ctoj_value_list failed.");
cjni_thread_detach();
- return (-1);
+ return -1;
}
ret_status =
(*jvm_env)->DeleteLocalRef(jvm_env, vl_java);
cjni_thread_detach();
- return (ret_status);
+ return ret_status;
} /* }}} int cjni_write */
/* Call the CB_TYPE_FLUSH callback pointed to by the `user_data_t' pointer. */
if (jvm == NULL) {
ERROR("java plugin: cjni_flush: jvm == NULL");
- return (-1);
+ return -1;
}
if ((ud == NULL) || (ud->data == NULL)) {
ERROR("java plugin: cjni_flush: Invalid user data.");
- return (-1);
+ return -1;
}
jvm_env = cjni_thread_attach();
if (jvm_env == NULL)
- return (-1);
+ return -1;
cbi = (cjni_callback_info_t *)ud->data;
ERROR("java plugin: cjni_flush: Converting double "
"to Number object failed.");
cjni_thread_detach();
- return (-1);
+ return -1;
}
o_identifier = NULL;
(*jvm_env)->DeleteLocalRef(jvm_env, o_timeout);
ERROR("java plugin: cjni_flush: NewStringUTF failed.");
cjni_thread_detach();
- return (-1);
+ return -1;
}
}
(*jvm_env)->DeleteLocalRef(jvm_env, o_timeout);
cjni_thread_detach();
- return (ret_status);
+ return ret_status;
} /* }}} int cjni_flush */
/* Call the CB_TYPE_LOG callback pointed to by the `user_data_t' pointer. */
if (jvm == NULL) {
ERROR("java plugin: cjni_read: jvm == NULL");
- return (-1);
+ return -1;
}
if ((ud == NULL) || (ud->data == NULL)) {
ERROR("java plugin: cjni_read: Invalid user data.");
- return (-1);
+ return -1;
}
jvm_env = cjni_thread_attach();
if (jvm_env == NULL)
- return (-1);
+ return -1;
cbi = (cjni_callback_info_t *)ud->data;
if (o_notification == NULL) {
ERROR("java plugin: cjni_notification: ctoj_notification failed.");
cjni_thread_detach();
- return (-1);
+ return -1;
}
ret_status = (*jvm_env)->CallIntMethod(jvm_env, cbi->object, cbi->method,
(*jvm_env)->DeleteLocalRef(jvm_env, o_notification);
cjni_thread_detach();
- return (ret_status);
+ return ret_status;
} /* }}} int cjni_notification */
/* Callbacks for matches implemented in Java */
if (jvm == NULL) {
ERROR("java plugin: cjni_read: jvm == NULL");
- return (-1);
+ return -1;
}
jvm_env = cjni_thread_attach();
if (jvm_env == NULL)
- return (-1);
+ return -1;
/* Find out whether to create a match or a target. */
if (strcasecmp("Match", ci->key) == 0)
cbi_ret->name, (type == CB_TYPE_MATCH) ? "match" : "target");
/* Success! */
- return (0);
+ return 0;
#undef BAIL_OUT
} /* }}} int cjni_match_target_create */
cjni_callback_info_destroy(*user_data);
*user_data = NULL;
- return (0);
+ return 0;
} /* }}} int cjni_match_target_destroy */
static int cjni_match_target_invoke(const data_set_t *ds, /* {{{ */
if (jvm == NULL) {
ERROR("java plugin: cjni_match_target_invoke: jvm == NULL");
- return (-1);
+ return -1;
}
jvm_env = cjni_thread_attach();
if (jvm_env == NULL)
- return (-1);
+ return -1;
cbi = (cjni_callback_info_t *)*user_data;
if (o_vl == NULL) {
ERROR("java plugin: cjni_match_target_invoke: ctoj_value_list failed.");
cjni_thread_detach();
- return (-1);
+ return -1;
}
o_ds = ctoj_data_set(jvm_env, ds);
if (o_ds == NULL) {
ERROR("java plugin: cjni_match_target_invoke: ctoj_value_list failed.");
cjni_thread_detach();
- return (-1);
+ return -1;
}
ret_status =
} /* if (cbi->type == CB_TYPE_TARGET) */
cjni_thread_detach();
- return (ret_status);
+ return ret_status;
} /* }}} int cjni_match_target_invoke */
/* Iterate over `java_callbacks' and call all CB_TYPE_INIT callbacks. */
}
}
- return (0);
+ return 0;
} /* }}} int cjni_init_plugins */
/* Iterate over `java_callbacks' and call all CB_TYPE_SHUTDOWN callbacks. */
}
}
- return (0);
+ return 0;
} /* }}} int cjni_shutdown_plugins */
static int cjni_shutdown(void) /* {{{ */
int status;
if (jvm == NULL)
- return (0);
+ return 0;
jvm_env = NULL;
args.version = JNI_VERSION_1_2;
ERROR("java plugin: cjni_shutdown: AttachCurrentThread failed with status "
"%i.",
status);
- return (-1);
+ return -1;
}
/* Execute all the shutdown functions registered by plugins. */
jvm_argc = 0;
sfree(jvm_argv);
- return (0);
+ return 0;
} /* }}} int cjni_shutdown */
/* Initialization: Create a JVM, load all configured classes and call their
if ((config_block == NULL) && (jvm == NULL)) {
ERROR("java plugin: cjni_init: No configuration block for "
"the java plugin was found.");
- return (-1);
+ return -1;
}
if (config_block != NULL) {
if (jvm == NULL) {
ERROR("java plugin: cjni_init: jvm == NULL");
- return (-1);
+ return -1;
}
jvm_env = cjni_thread_attach();
if (jvm_env == NULL)
- return (-1);
+ return -1;
cjni_init_plugins(jvm_env);
cjni_thread_detach();
- return (0);
+ return 0;
} /* }}} int cjni_init */
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 : */
+++ /dev/null
-AUTOMAKE_OPTIONS = foreign no-dependencies
-
-pkginclude_HEADERS = collectd/client.h collectd/network.h collectd/network_buffer.h collectd/lcc_features.h
-lib_LTLIBRARIES = libcollectdclient.la
-nodist_pkgconfig_DATA = libcollectdclient.pc
-
-BUILT_SOURCES = collectd/lcc_features.h
-
-libcollectdclient_la_SOURCES = client.c network.c network_buffer.c
-libcollectdclient_la_CPPFLAGS = $(AM_CPPFLAGS) \
- -I$(top_srcdir)/src/libcollectdclient/collectd \
- -I$(top_builddir)/src/libcollectdclient/collectd \
- -I$(top_srcdir)/src/daemon
-libcollectdclient_la_LDFLAGS = -version-info 1:0:0
-libcollectdclient_la_LIBADD =
-if BUILD_WITH_LIBGCRYPT
-libcollectdclient_la_CPPFLAGS += $(GCRYPT_CPPFLAGS)
-libcollectdclient_la_LDFLAGS += $(GCRYPT_LDFLAGS)
-libcollectdclient_la_LIBADD += $(GCRYPT_LIBS)
-endif
* Florian octo Forster <octo at collectd.org>
**/
-#if HAVE_CONFIG_H
#include "config.h"
-#endif
#if !defined(__GNUC__) || !__GNUC__
#define __attribute__(x) /**/
#define LCC_SET_ERRSTR(c, ...) \
do { \
snprintf((c)->errbuf, sizeof((c)->errbuf), __VA_ARGS__); \
- (c)->errbuf[sizeof((c)->errbuf) - 1] = 0; \
} while (0)
/*
*/
struct lcc_connection_s {
FILE *fh;
- char errbuf[1024];
+ char errbuf[2048];
};
struct lcc_response_s {
buf[buflen - 1] = 0;
- return (buf);
+ return buf;
} /* char *sstrerror */
static int lcc_set_errno(lcc_connection_t *c, int err) /* {{{ */
{
if (c == NULL)
- return (-1);
+ return -1;
sstrerror(err, c->errbuf, sizeof(c->errbuf));
c->errbuf[sizeof(c->errbuf) - 1] = 0;
- return (0);
+ return 0;
} /* }}} int lcc_set_errno */
static char *lcc_strescape(char *dest, const char *src,
size_t src_pos;
if ((dest == NULL) || (src == NULL))
- return (NULL);
+ return NULL;
dest_pos = 0;
src_pos = 0;
dest_pos++;
src_pos++;
- return (dest);
+ return dest;
} /* }}} char *lcc_strescape */
/* lcc_chomp: Removes all control-characters at the end of a string. */
status = fprintf(c->fh, "%s\r\n", command);
if (status < 0) {
lcc_set_errno(c, errno);
- return (-1);
+ return -1;
}
fflush(c->fh);
- return (0);
+ return 0;
} /* }}} int lcc_send */
static int lcc_receive(lcc_connection_t *c, /* {{{ */
ptr = fgets(buffer, sizeof(buffer), c->fh);
if (ptr == NULL) {
lcc_set_errno(c, errno);
- return (-1);
+ return -1;
}
lcc_chomp(buffer);
lcc_tracef("receive: <-- %s\n", buffer);
res.status = (int)strtol(buffer, &ptr, 0);
if ((errno != 0) || (ptr == &buffer[0])) {
lcc_set_errno(c, errno);
- return (-1);
+ return -1;
}
/* Skip white spaces after the status number */
/* Error or no lines follow: We're done. */
if (res.status <= 0) {
memcpy(ret_res, &res, sizeof(res));
- return (0);
+ return 0;
}
/* Allocate space for the char-pointers */
res.lines = malloc(res.lines_num * sizeof(*res.lines));
if (res.lines == NULL) {
lcc_set_errno(c, ENOMEM);
- return (-1);
+ return -1;
}
/* Now receive all the lines */
free(res.lines[i]);
}
free(res.lines);
- return (-1);
+ return -1;
}
memcpy(ret_res, &res, sizeof(res));
- return (0);
+ return 0;
} /* }}} int lcc_receive */
static int lcc_sendreceive(lcc_connection_t *c, /* {{{ */
if (c->fh == NULL) {
lcc_set_errno(c, EBADF);
- return (-1);
+ return -1;
}
status = lcc_send(c, command);
if (status != 0)
- return (status);
+ return status;
status = lcc_receive(c, &res);
if (status == 0)
memcpy(ret_res, &res, sizeof(*ret_res));
- return (status);
+ return status;
} /* }}} int lcc_sendreceive */
static int lcc_open_unixsocket(lcc_connection_t *c, const char *path) /* {{{ */
fd = socket(AF_UNIX, SOCK_STREAM, /* protocol = */ 0);
if (fd < 0) {
lcc_set_errno(c, errno);
- return (-1);
+ return -1;
}
sa.sun_family = AF_UNIX;
if (status != 0) {
lcc_set_errno(c, errno);
close(fd);
- return (-1);
+ return -1;
}
c->fh = fdopen(fd, "r+");
if (c->fh == NULL) {
lcc_set_errno(c, errno);
close(fd);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int lcc_open_unixsocket */
static int lcc_open_netsocket(lcc_connection_t *c, /* {{{ */
port = strchr(addr, ']');
if (port == NULL) {
LCC_SET_ERRSTR(c, "malformed address: %s", addr_orig);
- return (-1);
+ return -1;
}
*port = 0;
port++;
port = NULL;
else {
LCC_SET_ERRSTR(c, "garbage after address: %s", port);
- return (-1);
+ return -1;
}
} /* if (*addr = ']') */
else if (strchr(addr, '.') != NULL) /* Hostname or IPv4 */
&ai_res);
if (status != 0) {
LCC_SET_ERRSTR(c, "getaddrinfo: %s", gai_strerror(status));
- return (-1);
+ return -1;
}
for (struct addrinfo *ai_ptr = ai_res; ai_ptr != NULL;
if (status != 0) {
lcc_set_errno(c, status);
freeaddrinfo(ai_res);
- return (-1);
+ return -1;
}
freeaddrinfo(ai_res);
- return (0);
+ return 0;
} /* }}} int lcc_open_netsocket */
static int lcc_open_socket(lcc_connection_t *c, const char *addr) /* {{{ */
int status = 0;
if (addr == NULL)
- return (-1);
+ return -1;
assert(c != NULL);
assert(c->fh == NULL);
else
status = lcc_open_netsocket(c, addr);
- return (status);
+ return status;
} /* }}} int lcc_open_socket */
/*
*/
unsigned int lcc_version(void) /* {{{ */
{
- return (LCC_VERSION);
+ return LCC_VERSION;
} /* }}} unsigned int lcc_version */
const char *lcc_version_string(void) /* {{{ */
{
- return (LCC_VERSION_STRING);
+ return LCC_VERSION_STRING;
} /* }}} const char *lcc_version_string */
const char *lcc_version_extra(void) /* {{{ */
{
- return (LCC_VERSION_EXTRA);
+ return LCC_VERSION_EXTRA;
} /* }}} const char *lcc_version_extra */
int lcc_connect(const char *address, lcc_connection_t **ret_con) /* {{{ */
int status;
if (address == NULL)
- return (-1);
+ return -1;
if (ret_con == NULL)
- return (-1);
+ return -1;
c = calloc(1, sizeof(*c));
if (c == NULL)
- return (-1);
+ return -1;
status = lcc_open_socket(c, address);
if (status != 0) {
lcc_disconnect(c);
- return (status);
+ return status;
}
*ret_con = c;
- return (0);
+ return 0;
} /* }}} int lcc_connect */
int lcc_disconnect(lcc_connection_t *c) /* {{{ */
{
if (c == NULL)
- return (-1);
+ return -1;
if (c->fh != NULL) {
fclose(c->fh);
}
free(c);
- return (0);
+ return 0;
} /* }}} int lcc_disconnect */
int lcc_getval(lcc_connection_t *c, lcc_identifier_t *ident, /* {{{ */
int status;
if (c == NULL)
- return (-1);
+ return -1;
if (ident == NULL) {
lcc_set_errno(c, EINVAL);
- return (-1);
+ return -1;
}
/* Build a commend with an escaped version of the identifier string. */
status = lcc_identifier_to_string(c, ident_str, sizeof(ident_str), ident);
if (status != 0)
- return (status);
+ return status;
snprintf(command, sizeof(command), "GETVAL %s",
lcc_strescape(ident_esc, ident_str, sizeof(ident_esc)));
/* Send talk to the daemon.. */
status = lcc_sendreceive(c, command, &res);
if (status != 0)
- return (status);
+ return status;
if (res.status != 0) {
LCC_SET_ERRSTR(c, "Server error: %s", res.message);
lcc_response_free(&res);
- return (-1);
+ return -1;
}
values_num = res.lines_num;
} \
free(values_names); \
lcc_response_free(&res); \
- return (-1); \
+ return -1; \
} while (0)
/* If neither the values nor the names are requested, return here.. */
if (ret_values_num != NULL)
*ret_values_num = values_num;
lcc_response_free(&res);
- return (0);
+ return 0;
}
/* Allocate space for the values */
lcc_response_free(&res);
- return (0);
+ return 0;
} /* }}} int lcc_getval */
int lcc_putval(lcc_connection_t *c, const lcc_value_list_t *vl) /* {{{ */
if ((c == NULL) || (vl == NULL) || (vl->values_len < 1) ||
(vl->values == NULL) || (vl->values_types == NULL)) {
lcc_set_errno(c, EINVAL);
- return (-1);
+ return -1;
}
status = lcc_identifier_to_string(c, ident_str, sizeof(ident_str),
&vl->identifier);
if (status != 0)
- return (status);
+ return status;
SSTRCATF(command, "PUTVAL %s",
lcc_strescape(ident_esc, ident_str, sizeof(ident_esc)));
status = lcc_sendreceive(c, command, &res);
if (status != 0)
- return (status);
+ return status;
if (res.status != 0) {
LCC_SET_ERRSTR(c, "Server error: %s", res.message);
lcc_response_free(&res);
- return (-1);
+ return -1;
}
lcc_response_free(&res);
- return (0);
+ return 0;
} /* }}} int lcc_putval */
int lcc_flush(lcc_connection_t *c, const char *plugin, /* {{{ */
if (c == NULL) {
lcc_set_errno(c, EINVAL);
- return (-1);
+ return -1;
}
SSTRCPY(command, "FLUSH");
status = lcc_identifier_to_string(c, ident_str, sizeof(ident_str), ident);
if (status != 0)
- return (status);
+ return status;
SSTRCATF(command, " identifier=%s",
lcc_strescape(ident_esc, ident_str, sizeof(ident_esc)));
status = lcc_sendreceive(c, command, &res);
if (status != 0)
- return (status);
+ return status;
if (res.status != 0) {
LCC_SET_ERRSTR(c, "Server error: %s", res.message);
lcc_response_free(&res);
- return (-1);
+ return -1;
}
lcc_response_free(&res);
- return (0);
+ return 0;
} /* }}} int lcc_flush */
/* TODO: Implement lcc_putnotif */
size_t ident_num;
if (c == NULL)
- return (-1);
+ return -1;
if ((ret_ident == NULL) || (ret_ident_num == NULL)) {
lcc_set_errno(c, EINVAL);
- return (-1);
+ return -1;
}
status = lcc_sendreceive(c, "LISTVAL", &res);
if (status != 0)
- return (status);
+ return status;
if (res.status != 0) {
LCC_SET_ERRSTR(c, "Server error: %s", res.message);
lcc_response_free(&res);
- return (-1);
+ return -1;
}
ident_num = res.lines_num;
if (ident == NULL) {
lcc_response_free(&res);
lcc_set_errno(c, ENOMEM);
- return (-1);
+ return -1;
}
for (size_t i = 0; i < res.lines_num; i++) {
if (status != 0) {
free(ident);
- return (-1);
+ return -1;
}
*ret_ident = ident;
*ret_ident_num = ident_num;
- return (0);
+ return 0;
} /* }}} int lcc_listval */
const char *lcc_strerror(lcc_connection_t *c) /* {{{ */
{
if (c == NULL)
- return ("Invalid object");
- return (c->errbuf);
+ return "Invalid object";
+ return c->errbuf;
} /* }}} const char *lcc_strerror */
int lcc_identifier_to_string(lcc_connection_t *c, /* {{{ */
const lcc_identifier_t *ident) {
if ((string == NULL) || (string_size < 6) || (ident == NULL)) {
lcc_set_errno(c, EINVAL);
- return (-1);
+ return -1;
}
if (ident->plugin_instance[0] == 0) {
}
string[string_size - 1] = 0;
- return (0);
+ return 0;
} /* }}} int lcc_identifier_to_string */
int lcc_string_to_identifier(lcc_connection_t *c, /* {{{ */
string_copy = strdup(string);
if (string_copy == NULL) {
lcc_set_errno(c, ENOMEM);
- return (-1);
+ return -1;
}
host = string_copy;
if (plugin == NULL) {
LCC_SET_ERRSTR(c, "Malformed identifier string: %s", string);
free(string_copy);
- return (-1);
+ return -1;
}
*plugin = 0;
plugin++;
if (type == NULL) {
LCC_SET_ERRSTR(c, "Malformed identifier string: %s", string);
free(string_copy);
- return (-1);
+ return -1;
}
*type = 0;
type++;
SSTRCPY(ident->type_instance, type_instance);
free(string_copy);
- return (0);
+ return 0;
} /* }}} int lcc_string_to_identifier */
int lcc_identifier_compare(const void *a, /* {{{ */
int status;
if ((i0 == NULL) && (i1 == NULL))
- return (0);
+ return 0;
else if (i0 == NULL)
- return (-1);
+ return -1;
else if (i1 == NULL)
- return (1);
+ return 1;
#define CMP_FIELD(f) \
do { \
status = strcmp(i0->f, i1->f); \
if (status != 0) \
- return (status); \
+ return status; \
} while (0);
CMP_FIELD(host);
#undef CMP_FIELD
- return (0);
+ return 0;
} /* }}} int lcc_identifier_compare */
int lcc_sort_identifiers(lcc_connection_t *c, /* {{{ */
lcc_identifier_t *idents, size_t idents_num) {
if (idents == NULL) {
lcc_set_errno(c, EINVAL);
- return (-1);
+ return -1;
}
qsort(idents, idents_num, sizeof(*idents), lcc_identifier_compare);
- return (0);
+ return 0;
} /* }}} int lcc_sort_identifiers */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
#ifndef LIBCOLLECTD_COLLECTDCLIENT_H
#define LIBCOLLECTD_COLLECTDCLIENT_H 1
-#include "lcc_features.h"
+#include "collectd/lcc_features.h"
+#include "collectd/types.h"
/* COLLECTD_TRACE is the environment variable used to control trace output. When
* set to something non-zero, all lines sent to / received from the daemon are
/*
* Includes (for data types)
*/
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
#include <inttypes.h>
+#include <stdint.h>
#include <time.h>
-/*
- * Defines
- */
-#define LCC_NAME_LEN 64
-#define LCC_DEFAULT_PORT "25826"
-
-/*
- * Types
- */
-#define LCC_TYPE_COUNTER 0
-#define LCC_TYPE_GAUGE 1
-#define LCC_TYPE_DERIVE 2
-#define LCC_TYPE_ABSOLUTE 3
-
LCC_BEGIN_DECLS
-typedef uint64_t counter_t;
-typedef double gauge_t;
-typedef uint64_t derive_t;
-typedef uint64_t absolute_t;
-
-union value_u {
- counter_t counter;
- gauge_t gauge;
- derive_t derive;
- absolute_t absolute;
-};
-typedef union value_u value_t;
-
-struct lcc_identifier_s {
- char host[LCC_NAME_LEN];
- char plugin[LCC_NAME_LEN];
- char plugin_instance[LCC_NAME_LEN];
- char type[LCC_NAME_LEN];
- char type_instance[LCC_NAME_LEN];
-};
-typedef struct lcc_identifier_s lcc_identifier_t;
-#define LCC_IDENTIFIER_INIT \
- { "localhost", "", "", "", "" }
-
-struct lcc_value_list_s {
- value_t *values;
- int *values_types;
- size_t values_len;
- double time;
- double interval;
- lcc_identifier_t identifier;
-};
-typedef struct lcc_value_list_s lcc_value_list_t;
-#define LCC_VALUE_LIST_INIT \
- { NULL, NULL, 0, 0, 0, LCC_IDENTIFIER_INIT }
-
struct lcc_connection_s;
typedef struct lcc_connection_s lcc_connection_t;
LCC_END_DECLS
-/* vim: set sw=2 sts=2 et : */
#endif /* LIBCOLLECTD_COLLECTDCLIENT_H */
LCC_END_DECLS
#endif /* ! LIBCOLLECTD_LCC_FEATURES_H */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
-
#ifndef LIBCOLLECTDCLIENT_NETWORK_H
#define LIBCOLLECTDCLIENT_NETWORK_H 1
+#include "collectd/client.h"
+
#include <inttypes.h>
#include <stdint.h>
-#include "client.h"
-
#define NET_DEFAULT_V4_ADDR "239.192.74.66"
#define NET_DEFAULT_V6_ADDR "ff18::efc0:4a42"
#define NET_DEFAULT_PORT "25826"
const lcc_notification_t *notif);
#endif
-/* vim: set sw=2 sts=2 et : */
#endif /* LIBCOLLECTDCLIENT_NETWORK_H */
#ifndef LIBCOLLECTDCLIENT_NETWORK_BUFFER_H
#define LIBCOLLECTDCLIENT_NETWORK_BUFFER_H 1
-/* FIXME */
-#include "client.h"
-#include "network.h"
+#include "collectd/network.h" /* for lcc_security_level_t */
+#include "collectd/types.h"
/* Ethernet frame - (IPv6 header + UDP header) */
#define LCC_NETWORK_BUFFER_SIZE_DEFAULT 1452
size_t *buffer_size);
#endif /* LIBCOLLECTDCLIENT_NETWORK_BUFFER_H */
-/* vim: set sw=2 sts=2 et : */
--- /dev/null
+/**
+ * Copyright 2017 Florian Forster
+ *
+ * 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:
+ * Florian octo Forster <octo at collectd.org>
+ **/
+
+#ifndef LIBCOLLECTD_NETWORK_PARSE_H
+#define LIBCOLLECTD_NETWORK_PARSE_H 1
+
+#include "collectd/lcc_features.h"
+
+#include "collectd/network.h" /* for lcc_security_level_t */
+#include "collectd/types.h"
+
+#include <stdint.h>
+
+LCC_BEGIN_DECLS
+
+typedef struct {
+ /* writer is the callback used to send incoming lcc_value_list_t to. */
+ lcc_value_list_writer_t writer;
+
+ /* password_lookup is used to look up the password for a given username. */
+ lcc_password_lookup_t password_lookup;
+
+ /* security_level is the minimal required security level. */
+ lcc_security_level_t security_level;
+} lcc_network_parse_options_t;
+
+/* lcc_network_parse parses data received from the network and calls "w" with
+ * the parsed lcc_value_list_ts. */
+int lcc_network_parse(void *buffer, size_t buffer_size,
+ lcc_network_parse_options_t opts);
+
+LCC_END_DECLS
+
+#endif /* LIBCOLLECTD_NETWORK_PARSE_H */
--- /dev/null
+/**
+ * Copyright 2017 Florian Forster
+ *
+ * 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:
+ * Florian octo Forster <octo at collectd.org>
+ **/
+
+#ifndef LIBCOLLECTD_SERVER_H
+#define LIBCOLLECTD_SERVER_H 1
+
+#include "collectd/lcc_features.h"
+
+#include "collectd/network.h" /* for lcc_security_level_t */
+#include "collectd/network_parse.h" /* for lcc_network_parse_options_t */
+#include "collectd/types.h"
+
+#include <stdint.h>
+
+#ifndef LCC_NETWORK_BUFFER_SIZE
+#define LCC_NETWORK_BUFFER_SIZE 1452
+#endif
+
+LCC_BEGIN_DECLS
+
+/* lcc_network_parser_t is a callback that parses received network packets. It
+ * is expected to call lcc_network_parse_options_t.writer with each
+ * lcc_value_list_t it parses that has the required security level. */
+typedef int (*lcc_network_parser_t)(void *payload, size_t payload_size,
+ lcc_network_parse_options_t opts);
+
+/* lcc_listener_t holds parameters for running a collectd server. */
+typedef struct {
+ /* conn is a UDP socket for the server to listen on. If set to <0 node and
+ * service will be used to open a new UDP socket. If >=0, it is the caller's
+ * job to clean up the socket. */
+ int conn;
+
+ /* node is the local address to listen on if conn is <0. Defaults to "::" (any
+ * address). */
+ char *node;
+
+ /* service is the local address to listen on if conn is <0. Defaults to
+ * LCC_DEFAULT_PORT. */
+ char *service;
+
+ /* parser is the callback used to parse incoming network packets. Defaults to
+ * lcc_network_parse() if set to NULL. */
+ lcc_network_parser_t parser;
+
+ /* parse_options contains options for parser and is passed on verbatimely. */
+ lcc_network_parse_options_t parse_options;
+
+ /* buffer_size determines the maximum packet size to accept. Defaults to
+ * LCC_NETWORK_BUFFER_SIZE if set to zero. */
+ uint16_t buffer_size;
+
+ /* interface is the name of the interface to use when subscribing to a
+ * multicast group. Has no effect when using unicast. */
+ char *interface;
+} lcc_listener_t;
+
+/* lcc_listen_and_write listens on the provided UDP socket (or opens one using
+ * srv.addr if srv.conn is less than zero), parses the received packets and
+ * writes them to the provided lcc_value_list_writer_t. Returns non-zero on
+ * failure and does not return otherwise. */
+int lcc_listen_and_write(lcc_listener_t srv);
+
+LCC_END_DECLS
+
+#endif /* LIBCOLLECTD_SERVER_H */
--- /dev/null
+/**
+ * libcollectdclient - src/libcollectdclient/collectd/types.h
+ * Copyright (C) 2008-2017 Florian octo Forster
+ *
+ * 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:
+ * Florian octo Forster <octo at collectd.org>
+ **/
+
+#ifndef LIBCOLLECTD_COLLECTD_TYPES_H
+#define LIBCOLLECTD_COLLECTD_TYPES_H 1
+
+#include "collectd/lcc_features.h"
+
+#include <stdint.h> /* for uint64_t */
+#include <sys/types.h> /* for size_t */
+
+/*
+ * Defines
+ */
+#define LCC_NAME_LEN 64
+#define LCC_DEFAULT_PORT "25826"
+
+/*
+ * Types
+ */
+#define LCC_TYPE_COUNTER 0
+#define LCC_TYPE_GAUGE 1
+#define LCC_TYPE_DERIVE 2
+#define LCC_TYPE_ABSOLUTE 3
+
+LCC_BEGIN_DECLS
+
+typedef uint64_t counter_t;
+typedef double gauge_t;
+typedef uint64_t derive_t;
+typedef uint64_t absolute_t;
+
+union value_u {
+ counter_t counter;
+ gauge_t gauge;
+ derive_t derive;
+ absolute_t absolute;
+};
+typedef union value_u value_t;
+
+struct lcc_identifier_s {
+ char host[LCC_NAME_LEN];
+ char plugin[LCC_NAME_LEN];
+ char plugin_instance[LCC_NAME_LEN];
+ char type[LCC_NAME_LEN];
+ char type_instance[LCC_NAME_LEN];
+};
+typedef struct lcc_identifier_s lcc_identifier_t;
+#define LCC_IDENTIFIER_INIT \
+ { "localhost", "", "", "", "" }
+
+struct lcc_value_list_s {
+ value_t *values;
+ int *values_types;
+ size_t values_len;
+ double time;
+ double interval;
+ lcc_identifier_t identifier;
+};
+typedef struct lcc_value_list_s lcc_value_list_t;
+#define LCC_VALUE_LIST_INIT \
+ { NULL, NULL, 0, 0, 0, LCC_IDENTIFIER_INIT }
+
+/* lcc_value_list_writer_t is a write callback to which value lists are
+ * dispatched. */
+typedef int (*lcc_value_list_writer_t)(lcc_value_list_t const *);
+
+/* lcc_password_lookup_t is a callback for looking up the password for a given
+ * user. Must return NULL if the user is not known. */
+typedef char const *(*lcc_password_lookup_t)(char const *);
+
+LCC_END_DECLS
+
+#endif /* LIBCOLLECTD_COLLECTD_TYPES_H */
static int server_close_socket(lcc_server_t *srv) /* {{{ */
{
if (srv == NULL)
- return (EINVAL);
+ return EINVAL;
if (srv->fd < 0)
- return (0);
+ return 0;
close(srv->fd);
srv->fd = -1;
srv->sa = NULL;
srv->sa_len = 0;
- return (0);
+ return 0;
} /* }}} int server_close_socket */
static void int_server_destroy(lcc_server_t *srv) /* {{{ */
int status;
if (srv == NULL)
- return (EINVAL);
+ return EINVAL;
if (srv->fd >= 0)
server_close_socket(srv);
status = getaddrinfo(srv->node, srv->service, &ai_hints, &ai_list);
if (status != 0)
- return (status);
+ return status;
assert(ai_list != NULL);
for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
freeaddrinfo(ai_list);
if (srv->fd < 0)
- return (-1);
- return (0);
+ return -1;
+ return 0;
} /* }}} int server_open_socket */
static int server_send_buffer(lcc_server_t *srv) /* {{{ */
if (srv->fd < 0) {
status = server_open_socket(srv);
if (status != 0)
- return (status);
+ return status;
}
buffer_size = sizeof(buffer);
status = lcc_network_buffer_finalize(srv->buffer);
if (status != 0) {
lcc_network_buffer_initialize(srv->buffer);
- return (status);
+ return status;
}
status = lcc_network_buffer_get(srv->buffer, buffer, &buffer_size);
lcc_network_buffer_initialize(srv->buffer);
if (status != 0)
- return (status);
+ return status;
if (buffer_size > sizeof(buffer))
buffer_size = sizeof(buffer);
}
if (status < 0)
- return (status);
- return (0);
+ return status;
+ return 0;
} /* }}} int server_send_buffer */
static int server_value_add(lcc_server_t *srv, /* {{{ */
status = lcc_network_buffer_add_value(srv->buffer, vl);
if (status == 0)
- return (0);
+ return 0;
server_send_buffer(srv);
- return (lcc_network_buffer_add_value(srv->buffer, vl));
+ return lcc_network_buffer_add_value(srv->buffer, vl);
} /* }}} int server_value_add */
/*
net = calloc(1, sizeof(*net));
if (net == NULL)
- return (NULL);
+ return NULL;
net->servers = NULL;
- return (net);
+ return net;
} /* }}} lcc_network_t *lcc_network_create */
void lcc_network_destroy(lcc_network_t *net) /* {{{ */
lcc_server_t *srv;
if ((net == NULL) || (node == NULL))
- return (NULL);
+ return NULL;
if (service == NULL)
service = NET_DEFAULT_PORT;
srv = calloc(1, sizeof(*srv));
if (srv == NULL)
- return (NULL);
+ return NULL;
srv->fd = -1;
srv->security_level = NONE;
srv->node = strdup(node);
if (srv->node == NULL) {
free(srv);
- return (NULL);
+ return NULL;
}
srv->service = strdup(service);
if (srv->service == NULL) {
free(srv->node);
free(srv);
- return (NULL);
+ return NULL;
}
srv->buffer = lcc_network_buffer_create(/* size = */ 0);
free(srv->service);
free(srv->node);
free(srv);
- return (NULL);
+ return NULL;
}
if (net->servers == NULL) {
last->next = srv;
}
- return (srv);
+ return srv;
} /* }}} lcc_server_t *lcc_server_create */
int lcc_server_destroy(lcc_network_t *net, lcc_server_t *srv) /* {{{ */
{
if ((net == NULL) || (srv == NULL))
- return (EINVAL);
+ return EINVAL;
if (net->servers == srv) {
net->servers = srv->next;
prev = prev->next;
if (prev == NULL)
- return (ENOENT);
+ return ENOENT;
prev->next = srv->next;
srv->next = NULL;
int_server_destroy(srv);
- return (0);
+ return 0;
} /* }}} int lcc_server_destroy */
int lcc_server_set_ttl(lcc_server_t *srv, uint8_t ttl) /* {{{ */
{
if (srv == NULL)
- return (EINVAL);
+ return EINVAL;
srv->ttl = (int)ttl;
- return (0);
+ return 0;
} /* }}} int lcc_server_set_ttl */
int lcc_server_set_interface(lcc_server_t *srv, char const *interface) /* {{{ */
int status;
if ((srv == NULL) || (interface == NULL))
- return (EINVAL);
+ return EINVAL;
if_index = if_nametoindex(interface);
if (if_index == 0)
- return (ENOENT);
+ return ENOENT;
/* IPv4 multicast */
if (srv->sa->sa_family == AF_INET) {
status =
setsockopt(srv->fd, IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq));
if (status != 0)
- return (status);
+ return status;
- return (0);
+ return 0;
}
}
status = setsockopt(srv->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &if_index,
sizeof(if_index));
if (status != 0)
- return (status);
+ return status;
- return (0);
+ return 0;
}
}
status = setsockopt(srv->fd, SOL_SOCKET, SO_BINDTODEVICE, interface,
(socklen_t)(strlen(interface) + 1));
if (status != 0)
- return (-1);
+ return -1;
#endif
- return (0);
+ return 0;
} /* }}} int lcc_server_set_interface */
int lcc_server_set_security_level(lcc_server_t *srv, /* {{{ */
lcc_security_level_t level,
const char *username, const char *password) {
- return (lcc_network_buffer_set_security_level(srv->buffer, level, username,
- password));
+ return lcc_network_buffer_set_security_level(srv->buffer, level, username,
+ password);
} /* }}} int lcc_server_set_security_level */
int lcc_network_values_send(lcc_network_t *net, /* {{{ */
const lcc_value_list_t *vl) {
if ((net == NULL) || (vl == NULL))
- return (EINVAL);
+ return EINVAL;
for (lcc_server_t *srv = net->servers; srv != NULL; srv = srv->next)
server_value_add(srv, vl);
- return (0);
+ return 0;
} /* }}} int lcc_network_values_send */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
#include <pthread.h>
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
#if defined __APPLE__
/* default xcode compiler throws warnings even when deprecated functionality
* is not used. -Werror breaks the build because of erroneous warnings.
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];
static _Bool need_init = 1;
if (!need_init)
- return (result);
+ 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);
+ return 0;
#endif
if (!gcry_check_version(GCRYPT_VERSION))
- return (0);
+ return 0;
if (!gcry_control(GCRYCTL_INIT_SECMEM, 32768, 0))
- return (0);
+ return 0;
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
result = 1;
- return (1);
+ return 1;
#else
- return (0);
+ return 0;
#endif
} /* }}} _Bool have_gcrypt */
}
if (config == 1)
- return (val);
+ return val;
hi = (uint32_t)(val >> 32);
lo = (uint32_t)(val & 0x00000000FFFFFFFF);
hi = htonl(hi);
lo = htonl(lo);
- return ((((uint64_t)lo) << 32) | ((uint64_t)hi));
+ return (((uint64_t)lo) << 32) | ((uint64_t)hi);
} /* }}} uint64_t htonll */
#endif
out.byte[4] = out.byte[5] = 0x00;
out.byte[6] = 0xf8;
out.byte[7] = 0x7f;
- return (out.floating);
+ return out.floating;
} else if (config == 1)
- return (val);
+ return val;
else if (config == 2) {
in.floating = val;
out.byte[0] = in.byte[7];
out.byte[5] = in.byte[2];
out.byte[6] = in.byte[1];
out.byte[7] = in.byte[0];
- return (out.floating);
+ return out.floating;
} else if (config == 3) {
in.floating = val;
out.byte[0] = in.byte[4];
out.byte[5] = in.byte[1];
out.byte[6] = in.byte[2];
out.byte[7] = in.byte[3];
- return (out.floating);
+ return out.floating;
} else {
/* If in doubt, just copy the value back to the caller. */
- return (val);
+ return val;
}
} /* }}} double htond */
static int nb_add_values(char **ret_buffer, /* {{{ */
size_t *ret_buffer_len, const lcc_value_list_t *vl) {
+ if ((vl == NULL) || (vl->values_len < 1)) {
+ return EINVAL;
+ }
+
char *packet_ptr;
size_t packet_len;
sizeof(pkg_values_types) + sizeof(pkg_values);
if (*ret_buffer_len < packet_len)
- return (ENOMEM);
+ return ENOMEM;
pkg_type = htons(TYPE_VALUES);
pkg_length = htons((uint16_t)packet_len);
break;
default:
- return (EINVAL);
+ return EINVAL;
} /* switch (vl->values_types[i]) */
} /* for (vl->values_len) */
*ret_buffer = packet_ptr + packet_len;
*ret_buffer_len -= packet_len;
- return (0);
+ return 0;
} /* }}} int nb_add_values */
static int nb_add_number(char **ret_buffer, /* {{{ */
packet_len = sizeof(pkg_type) + sizeof(pkg_length) + sizeof(pkg_value);
if (*ret_buffer_len < packet_len)
- return (ENOMEM);
+ return ENOMEM;
pkg_type = htons(type);
pkg_length = htons((uint16_t)packet_len);
*ret_buffer = packet_ptr + packet_len;
*ret_buffer_len -= packet_len;
- return (0);
+ return 0;
} /* }}} int nb_add_number */
static int nb_add_time(char **ret_buffer, /* {{{ */
size_t *ret_buffer_len, uint16_t type, double value) {
/* Convert to collectd's "cdtime" representation. */
uint64_t cdtime_value = (uint64_t)(value * 1073741824.0);
- return (nb_add_number(ret_buffer, ret_buffer_len, type, cdtime_value));
+ return nb_add_number(ret_buffer, ret_buffer_len, type, cdtime_value);
} /* }}} int nb_add_time */
static int nb_add_string(char **ret_buffer, /* {{{ */
packet_len = sizeof(pkg_type) + sizeof(pkg_length) + str_len + 1;
if (*ret_buffer_len < packet_len)
- return (ENOMEM);
+ return ENOMEM;
pkg_type = htons(type);
pkg_length = htons((uint16_t)packet_len);
*ret_buffer = packet_ptr + packet_len;
*ret_buffer_len -= packet_len;
- return (0);
+ return 0;
} /* }}} int nb_add_string */
static int nb_add_value_list(lcc_network_buffer_t *nb, /* {{{ */
if (strcmp(ident_dst->host, ident_src->host) != 0) {
if (nb_add_string(&buffer, &buffer_size, TYPE_HOST, ident_src->host,
strlen(ident_src->host)) != 0)
- return (-1);
+ return -1;
SSTRNCPY(ident_dst->host, ident_src->host, sizeof(ident_dst->host));
}
if (strcmp(ident_dst->plugin, ident_src->plugin) != 0) {
if (nb_add_string(&buffer, &buffer_size, TYPE_PLUGIN, ident_src->plugin,
strlen(ident_src->plugin)) != 0)
- return (-1);
+ return -1;
SSTRNCPY(ident_dst->plugin, ident_src->plugin, sizeof(ident_dst->plugin));
}
if (nb_add_string(&buffer, &buffer_size, TYPE_PLUGIN_INSTANCE,
ident_src->plugin_instance,
strlen(ident_src->plugin_instance)) != 0)
- return (-1);
+ return -1;
SSTRNCPY(ident_dst->plugin_instance, ident_src->plugin_instance,
sizeof(ident_dst->plugin_instance));
}
if (strcmp(ident_dst->type, ident_src->type) != 0) {
if (nb_add_string(&buffer, &buffer_size, TYPE_TYPE, ident_src->type,
strlen(ident_src->type)) != 0)
- return (-1);
+ return -1;
SSTRNCPY(ident_dst->type, ident_src->type, sizeof(ident_dst->type));
}
if (nb_add_string(&buffer, &buffer_size, TYPE_TYPE_INSTANCE,
ident_src->type_instance,
strlen(ident_src->type_instance)) != 0)
- return (-1);
+ return -1;
SSTRNCPY(ident_dst->type_instance, ident_src->type_instance,
sizeof(ident_dst->type_instance));
}
if (nb->state.time != vl->time) {
if (nb_add_time(&buffer, &buffer_size, TYPE_TIME_HR, vl->time))
- return (-1);
+ return -1;
nb->state.time = vl->time;
}
if (nb->state.interval != vl->interval) {
if (nb_add_time(&buffer, &buffer_size, TYPE_INTERVAL_HR, vl->interval))
- return (-1);
+ return -1;
nb->state.interval = vl->interval;
}
if (nb_add_values(&buffer, &buffer_size, vl) != 0)
- return (-1);
+ return -1;
nb->ptr = buffer;
nb->free = buffer_size;
- return (0);
+ 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;
hd = NULL;
err = gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
if (err != 0)
- return (-1);
+ return -1;
assert(nb->password != NULL);
err = gcry_md_setkey(hd, nb->password, strlen(nb->password));
if (err != 0) {
gcry_md_close(hd);
- return (-1);
+ return -1;
}
gcry_md_write(hd, buffer, buffer_size);
hash = gcry_md_read(hd, GCRY_MD_SHA256);
if (hash == NULL) {
gcry_md_close(hd);
- return (-1);
+ return -1;
}
assert(((2 * sizeof(uint16_t)) + hash_length) == PART_SIGNATURE_SHA256_SIZE);
memcpy(nb->buffer + (2 * sizeof(uint16_t)), hash, hash_length);
gcry_md_close(hd);
- return (0);
+ return 0;
} /* }}} int nb_add_signature */
static int nb_add_encryption(lcc_network_buffer_t *nb) /* {{{ */
err = gcry_cipher_open(&nb->encr_cypher, GCRY_CIPHER_AES256,
GCRY_CIPHER_MODE_OFB, /* flags = */ 0);
if (err != 0)
- return (-1);
+ return -1;
/* Calculate our 256bit key used for AES */
gcry_md_hash_buffer(GCRY_MD_SHA256, password_hash, nb->password,
if (err != 0) {
gcry_cipher_close(nb->encr_cypher);
nb->encr_cypher = NULL;
- return (-1);
+ return -1;
}
} else /* if (nb->encr_cypher != NULL) */
{
if (err != 0) {
gcry_cipher_close(nb->encr_cypher);
nb->encr_cypher = NULL;
- return (-1);
+ return -1;
}
/* Encrypt the buffer in-place */
if (err != 0) {
gcry_cipher_close(nb->encr_cypher);
nb->encr_cypher = NULL;
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int nb_add_encryption */
#endif
if (size < 128) {
errno = EINVAL;
- return (NULL);
+ return NULL;
}
nb = calloc(1, sizeof(*nb));
if (nb == NULL)
- return (NULL);
+ return NULL;
nb->size = size;
nb->buffer = calloc(1, nb->size);
if (nb->buffer == NULL) {
free(nb);
- return (NULL);
+ return NULL;
}
nb->ptr = nb->buffer;
nb->username = NULL;
nb->password = NULL;
- return (nb);
+ return nb;
} /* }}} lcc_network_buffer_t *lcc_network_buffer_create */
void lcc_network_buffer_destroy(lcc_network_buffer_t *nb) /* {{{ */
nb->password = NULL;
nb->seclevel = NONE;
lcc_network_buffer_initialize(nb);
- return (0);
+ return 0;
}
if (!have_gcrypt())
- return (ENOTSUP);
+ return ENOTSUP;
username_copy = strdup(username);
password_copy = strdup(password);
if ((username_copy == NULL) || (password_copy == NULL)) {
free(username_copy);
free(password_copy);
- return (ENOMEM);
+ return ENOMEM;
}
free(nb->username);
nb->seclevel = level;
lcc_network_buffer_initialize(nb);
- return (0);
+ return 0;
} /* }}} int lcc_network_buffer_set_security_level */
int lcc_network_buffer_initialize(lcc_network_buffer_t *nb) /* {{{ */
{
if (nb == NULL)
- return (EINVAL);
+ return EINVAL;
memset(nb->buffer, 0, nb->size);
memset(&nb->state, 0, sizeof(nb->state));
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);
}
#endif
- return (0);
+ return 0;
} /* }}} int lcc_network_buffer_initialize */
int lcc_network_buffer_finalize(lcc_network_buffer_t *nb) /* {{{ */
{
if (nb == NULL)
- return (EINVAL);
+ return EINVAL;
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
if (nb->seclevel == SIGN)
return nb_add_signature(nb);
else if (nb->seclevel == ENCRYPT)
return nb_add_encryption(nb);
#endif
- return (0);
+ return 0;
} /* }}} int lcc_network_buffer_finalize */
int lcc_network_buffer_add_value(lcc_network_buffer_t *nb, /* {{{ */
int status;
if ((nb == NULL) || (vl == NULL))
- return (EINVAL);
+ return EINVAL;
status = nb_add_value_list(nb, vl);
- return (status);
+ return status;
} /* }}} int lcc_network_buffer_add_value */
int lcc_network_buffer_get(lcc_network_buffer_t *nb, /* {{{ */
size_t sz_available;
if ((nb == NULL) || (buffer_size == NULL))
- return (EINVAL);
+ return EINVAL;
assert(nb->size >= nb->free);
sz_required = nb->size - nb->free;
memcpy(buffer, nb->buffer,
(sz_available < sz_required) ? sz_available : sz_required);
- return (0);
+ return 0;
} /* }}} int lcc_network_buffer_get */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
--- /dev/null
+/**
+ * Copyright 2017 Florian Forster
+ *
+ * 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:
+ * Florian octo Forster <octo at collectd.org>
+ **/
+
+#include "config.h"
+
+#if !defined(__GNUC__) || !__GNUC__
+#define __attribute__(x) /**/
+#endif
+
+#include "collectd/lcc_features.h"
+#include "collectd/network_parse.h"
+
+#include <errno.h>
+#include <math.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* for be{16,64}toh */
+#if HAVE_ENDIAN_H
+#include <endian.h>
+#elif HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#else /* fallback */
+__attribute__((const)) static uint16_t be16toh(uint16_t n) {
+ uint8_t tmp[2];
+ memmove(tmp, &n, sizeof(tmp));
+
+ return ((uint16_t)tmp[0] << 8) | ((uint16_t)tmp[1] << 0);
+}
+
+__attribute__((const)) static uint64_t be64toh(uint64_t n) {
+ uint8_t tmp[8];
+ memmove(tmp, &n, sizeof(tmp));
+
+ return ((uint64_t)tmp[0] << 56) | ((uint64_t)tmp[1] << 48) |
+ ((uint64_t)tmp[2] << 40) | ((uint64_t)tmp[3] << 32) |
+ ((uint64_t)tmp[4] << 24) | ((uint64_t)tmp[5] << 16) |
+ ((uint64_t)tmp[6] << 8) | ((uint64_t)tmp[7] << 0);
+}
+#endif
+
+#if HAVE_GCRYPT_H
+#define GCRYPT_NO_DEPRECATED
+#include <gcrypt.h>
+#endif
+
+#include <stdio.h>
+#define DEBUG(...) printf(__VA_ARGS__)
+
+#if HAVE_GCRYPT_H
+#if GCRYPT_VERSION_NUMBER < 0x010600
+GCRY_THREAD_OPTION_PTHREAD_IMPL;
+#endif
+#endif
+
+/* forward declaration because parse_sign_sha256()/parse_encrypt_aes256() and
+ * network_parse() need to call each other. */
+static int network_parse(void *data, size_t data_size, lcc_security_level_t sl,
+ lcc_network_parse_options_t const *opts);
+
+#if HAVE_GCRYPT_H
+static int init_gcrypt() {
+ /* http://lists.gnupg.org/pipermail/gcrypt-devel/2003-August/000458.html
+ * Because you can't know in a library whether another library has
+ * already initialized the library */
+ if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P))
+ return (0);
+
+/* http://www.gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
+ * To ensure thread-safety, it's important to set GCRYCTL_SET_THREAD_CBS
+ * *before* initalizing Libgcrypt with gcry_check_version(), which itself must
+ * be called before any other gcry_* function. GCRYCTL_ANY_INITIALIZATION_P
+ * above doesn't count, as it doesn't implicitly initalize Libgcrypt.
+ *
+ * tl;dr: keep all these gry_* statements in this exact order please. */
+#if GCRYPT_VERSION_NUMBER < 0x010600
+ if (gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread)) {
+ return -1;
+ }
+#endif
+
+ gcry_check_version(NULL);
+
+ if (gcry_control(GCRYCTL_INIT_SECMEM, 32768)) {
+ return -1;
+ }
+
+ gcry_control(GCRYCTL_INITIALIZATION_FINISHED);
+ return 0;
+}
+#endif
+
+typedef struct {
+ uint8_t *data;
+ size_t len;
+} buffer_t;
+
+static int buffer_next(buffer_t *b, void *out, size_t n) {
+ if (b->len < n) {
+ return -1;
+ }
+ memmove(out, b->data, n);
+
+ b->data += n;
+ b->len -= n;
+
+ return 0;
+}
+
+static int buffer_uint16(buffer_t *b, uint16_t *out) {
+ uint16_t tmp;
+ if (buffer_next(b, &tmp, sizeof(tmp)) != 0)
+ return -1;
+
+ *out = be16toh(tmp);
+ return 0;
+}
+
+#define TYPE_HOST 0x0000
+#define TYPE_TIME 0x0001
+#define TYPE_TIME_HR 0x0008
+#define TYPE_PLUGIN 0x0002
+#define TYPE_PLUGIN_INSTANCE 0x0003
+#define TYPE_TYPE 0x0004
+#define TYPE_TYPE_INSTANCE 0x0005
+#define TYPE_VALUES 0x0006
+#define TYPE_INTERVAL 0x0007
+#define TYPE_INTERVAL_HR 0x0009
+#define TYPE_SIGN_SHA256 0x0200
+#define TYPE_ENCR_AES256 0x0210
+
+static int parse_int(void *payload, size_t payload_size, uint64_t *out) {
+ uint64_t tmp;
+
+ if (payload_size != sizeof(tmp))
+ return EINVAL;
+
+ memmove(&tmp, payload, sizeof(tmp));
+ *out = be64toh(tmp);
+ return 0;
+}
+
+static int parse_string(void *payload, size_t payload_size, char *out,
+ size_t out_size) {
+ char *in = payload;
+
+ if ((payload_size < 1) || (in[payload_size - 1] != 0) ||
+ (payload_size > out_size))
+ return EINVAL;
+
+ strncpy(out, in, out_size);
+ return 0;
+}
+
+static int parse_identifier(uint16_t type, void *payload, size_t payload_size,
+ lcc_value_list_t *state) {
+ char buf[LCC_NAME_LEN];
+
+ if (parse_string(payload, payload_size, buf, sizeof(buf)) != 0)
+ return EINVAL;
+
+ switch (type) {
+ case TYPE_HOST:
+ memmove(state->identifier.host, buf, LCC_NAME_LEN);
+ break;
+ case TYPE_PLUGIN:
+ memmove(state->identifier.plugin, buf, LCC_NAME_LEN);
+ break;
+ case TYPE_PLUGIN_INSTANCE:
+ memmove(state->identifier.plugin_instance, buf, LCC_NAME_LEN);
+ break;
+ case TYPE_TYPE:
+ memmove(state->identifier.type, buf, LCC_NAME_LEN);
+ break;
+ case TYPE_TYPE_INSTANCE:
+ memmove(state->identifier.type_instance, buf, LCC_NAME_LEN);
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static int parse_time(uint16_t type, void *payload, size_t payload_size,
+ lcc_value_list_t *state) {
+ uint64_t tmp = 0;
+ if (parse_int(payload, payload_size, &tmp))
+ return EINVAL;
+
+ double t = (double)tmp;
+ switch (type) {
+ case TYPE_INTERVAL:
+ state->interval = t;
+ break;
+ case TYPE_INTERVAL_HR:
+ state->interval = t / 1073741824.0;
+ break;
+ case TYPE_TIME:
+ state->time = t;
+ break;
+ case TYPE_TIME_HR:
+ state->time = t / 1073741824.0;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static double ntohd(double val) /* {{{ */
+{
+ static int config = 0;
+
+ union {
+ uint8_t byte[8];
+ double floating;
+ } in = {
+ .floating = val,
+ };
+ union {
+ uint8_t byte[8];
+ double floating;
+ } out = {
+ .byte = {0},
+ };
+
+ if (config == 0) {
+ double d = 8.642135e130;
+ uint8_t b[8];
+
+ memcpy(b, &d, sizeof(b));
+
+ if ((b[0] == 0x2f) && (b[1] == 0x25) && (b[2] == 0xc0) && (b[3] == 0xc7) &&
+ (b[4] == 0x43) && (b[5] == 0x2b) && (b[6] == 0x1f) && (b[7] == 0x5b))
+ config = 1; /* need nothing */
+ else if ((b[7] == 0x2f) && (b[6] == 0x25) && (b[5] == 0xc0) &&
+ (b[4] == 0xc7) && (b[3] == 0x43) && (b[2] == 0x2b) &&
+ (b[1] == 0x1f) && (b[0] == 0x5b))
+ config = 2; /* endian flip */
+ else if ((b[4] == 0x2f) && (b[5] == 0x25) && (b[6] == 0xc0) &&
+ (b[7] == 0xc7) && (b[0] == 0x43) && (b[1] == 0x2b) &&
+ (b[2] == 0x1f) && (b[3] == 0x5b))
+ config = 3; /* int swap */
+ else
+ config = 4;
+ }
+
+ if (memcmp((char[]){0, 0, 0, 0, 0, 0, 0xf8, 0x7f}, in.byte, 8) == 0) {
+ return NAN;
+ } else if (config == 1) {
+ return val;
+ } else if (config == 2) {
+ in.floating = val;
+ out.byte[0] = in.byte[7];
+ out.byte[1] = in.byte[6];
+ out.byte[2] = in.byte[5];
+ out.byte[3] = in.byte[4];
+ out.byte[4] = in.byte[3];
+ out.byte[5] = in.byte[2];
+ out.byte[6] = in.byte[1];
+ out.byte[7] = in.byte[0];
+ return (out.floating);
+ } else if (config == 3) {
+ in.floating = val;
+ out.byte[0] = in.byte[4];
+ out.byte[1] = in.byte[5];
+ out.byte[2] = in.byte[6];
+ out.byte[3] = in.byte[7];
+ out.byte[4] = in.byte[0];
+ out.byte[5] = in.byte[1];
+ out.byte[6] = in.byte[2];
+ out.byte[7] = in.byte[3];
+ return out.floating;
+ } else {
+ /* If in doubt, just copy the value back to the caller. */
+ return val;
+ }
+} /* }}} double ntohd */
+
+static int parse_values(void *payload, size_t payload_size,
+ lcc_value_list_t *state) {
+ buffer_t *b = &(buffer_t){
+ .data = payload, .len = payload_size,
+ };
+
+ uint16_t n;
+ if (buffer_uint16(b, &n))
+ return EINVAL;
+
+ if (((size_t)n * 9) != b->len)
+ return EINVAL;
+
+ state->values_len = (size_t)n;
+ state->values = calloc(sizeof(*state->values), state->values_len);
+ state->values_types = calloc(sizeof(*state->values_types), state->values_len);
+ if ((state->values == NULL) || (state->values_types == NULL)) {
+ return ENOMEM;
+ }
+
+ for (uint16_t i = 0; i < n; i++) {
+ uint8_t tmp;
+ if (buffer_next(b, &tmp, sizeof(tmp)))
+ return EINVAL;
+ state->values_types[i] = (int)tmp;
+ }
+
+ for (uint16_t i = 0; i < n; i++) {
+ uint64_t tmp;
+ if (buffer_next(b, &tmp, sizeof(tmp)))
+ return EINVAL;
+
+ if (state->values_types[i] == LCC_TYPE_GAUGE) {
+ union {
+ uint64_t i;
+ double d;
+ } conv = {.i = tmp};
+ state->values[i].gauge = ntohd(conv.d);
+ continue;
+ }
+
+ tmp = be64toh(tmp);
+ switch (state->values_types[i]) {
+ case LCC_TYPE_COUNTER:
+ state->values[i].counter = (counter_t)tmp;
+ break;
+ case LCC_TYPE_DERIVE:
+ state->values[i].derive = (derive_t)tmp;
+ break;
+ case LCC_TYPE_ABSOLUTE:
+ state->values[i].absolute = (absolute_t)tmp;
+ break;
+ default:
+ return EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+#if HAVE_GCRYPT_H
+static int verify_sha256(void *payload, size_t payload_size,
+ char const *username, char const *password,
+ uint8_t hash_provided[32]) {
+ gcry_md_hd_t hd = NULL;
+
+ gcry_error_t err = gcry_md_open(&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
+ if (err != 0) {
+ return (int)err;
+ }
+
+ err = gcry_md_setkey(hd, password, strlen(password));
+ if (err != 0) {
+ gcry_md_close(hd);
+ return (int)err;
+ }
+
+ gcry_md_write(hd, username, strlen(username));
+ gcry_md_write(hd, payload, payload_size);
+
+ unsigned char *hash_calculated = gcry_md_read(hd, GCRY_MD_SHA256);
+ if (!hash_calculated) {
+ gcry_md_close(hd);
+ return -1;
+ }
+
+ int ret = memcmp(hash_provided, hash_calculated, 32);
+
+ gcry_md_close(hd);
+ hash_calculated = NULL;
+
+ return !!ret;
+}
+#else /* !HAVE_GCRYPT_H */
+static int verify_sha256(void *payload, size_t payload_size,
+ char const *username, char const *password,
+ uint8_t hash_provided[32]) {
+ return ENOTSUP;
+}
+#endif
+
+static int parse_sign_sha256(void *signature, size_t signature_len,
+ void *payload, size_t payload_size,
+ lcc_network_parse_options_t const *opts) {
+ if (opts->password_lookup == NULL) {
+ /* The sender signed the packet but we can't verify it. Handle it as if it
+ * were unsigned, i.e. security level NONE. */
+ return network_parse(payload, payload_size, NONE, opts);
+ }
+
+ buffer_t *b = &(buffer_t){
+ .data = signature, .len = signature_len,
+ };
+
+ uint8_t hash[32];
+ if (buffer_next(b, hash, sizeof(hash)))
+ return EINVAL;
+
+ char username[b->len + 1];
+ memset(username, 0, sizeof(username));
+ if (buffer_next(b, username, sizeof(username) - 1)) {
+ return EINVAL;
+ }
+
+ char const *password = opts->password_lookup(username);
+ if (!password)
+ return network_parse(payload, payload_size, NONE, opts);
+
+ int status = verify_sha256(payload, payload_size, username, password, hash);
+ if (status != 0)
+ return status;
+
+ return network_parse(payload, payload_size, SIGN, opts);
+}
+
+#if HAVE_GCRYPT_H
+static int decrypt_aes256(buffer_t *b, void *iv, size_t iv_size,
+ char const *password) {
+ gcry_cipher_hd_t cipher = NULL;
+
+ if (gcry_cipher_open(&cipher, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB,
+ /* flags = */ 0))
+ return -1;
+
+ uint8_t pwhash[32] = {0};
+ gcry_md_hash_buffer(GCRY_MD_SHA256, pwhash, password, strlen(password));
+
+ fprintf(stderr, "sizeof(iv) = %zu\n", sizeof(iv));
+ if (gcry_cipher_setkey(cipher, pwhash, sizeof(pwhash)) ||
+ gcry_cipher_setiv(cipher, iv, iv_size) ||
+ gcry_cipher_decrypt(cipher, b->data, b->len, /* in = */ NULL,
+ /* in_size = */ 0)) {
+ gcry_cipher_close(cipher);
+ return -1;
+ }
+
+ gcry_cipher_close(cipher);
+ return 0;
+}
+
+static int parse_encrypt_aes256(void *data, size_t data_size,
+ lcc_network_parse_options_t const *opts) {
+ if (opts->password_lookup == NULL) {
+ /* Without a password source it's (hopefully) impossible to decrypt the
+ * network packet. */
+ return ENOENT;
+ }
+
+ buffer_t *b = &(buffer_t){
+ .data = data, .len = data_size,
+ };
+
+ uint16_t username_len;
+ if (buffer_uint16(b, &username_len))
+ return EINVAL;
+ if ((size_t)username_len > data_size)
+ return ENOMEM;
+ char username[((size_t)username_len) + 1];
+ memset(username, 0, sizeof(username));
+ if (buffer_next(b, username, (size_t)username_len))
+ return EINVAL;
+
+ char const *password = opts->password_lookup(username);
+ if (!password)
+ return ENOENT;
+
+ uint8_t iv[16];
+ if (buffer_next(b, iv, sizeof(iv)))
+ return EINVAL;
+
+ int status = decrypt_aes256(b, iv, sizeof(iv), password);
+ if (status != 0)
+ return status;
+
+ uint8_t hash_provided[20];
+ if (buffer_next(b, hash_provided, sizeof(hash_provided))) {
+ return -1;
+ }
+
+ uint8_t hash_calculated[20];
+ gcry_md_hash_buffer(GCRY_MD_SHA1, hash_calculated, b->data, b->len);
+
+ if (memcmp(hash_provided, hash_calculated, sizeof(hash_provided)) != 0) {
+ return -1;
+ }
+
+ return network_parse(b->data, b->len, ENCRYPT, opts);
+}
+#else /* !HAVE_GCRYPT_H */
+static int parse_encrypt_aes256(void *data, size_t data_size,
+ lcc_network_parse_options_t const *opts) {
+ return ENOTSUP;
+}
+#endif
+
+static int network_parse(void *data, size_t data_size, lcc_security_level_t sl,
+ lcc_network_parse_options_t const *opts) {
+ buffer_t *b = &(buffer_t){
+ .data = data, .len = data_size,
+ };
+
+ lcc_value_list_t state = {0};
+
+ while (b->len > 0) {
+ uint16_t type = 0, sz = 0;
+ if (buffer_uint16(b, &type) || buffer_uint16(b, &sz)) {
+ DEBUG("lcc_network_parse(): reading type and/or length failed.\n");
+ return EINVAL;
+ }
+
+ if ((sz < 5) || (((size_t)sz - 4) > b->len)) {
+ DEBUG("lcc_network_parse(): invalid 'sz' field: sz = %" PRIu16
+ ", b->len = %zu\n",
+ sz, b->len);
+ return EINVAL;
+ }
+ sz -= 4;
+
+ uint8_t payload[sz];
+ if (buffer_next(b, payload, sizeof(payload)))
+ return EINVAL;
+
+ switch (type) {
+ case TYPE_HOST:
+ case TYPE_PLUGIN:
+ case TYPE_PLUGIN_INSTANCE:
+ case TYPE_TYPE:
+ case TYPE_TYPE_INSTANCE: {
+ if (parse_identifier(type, payload, sizeof(payload), &state)) {
+ DEBUG("lcc_network_parse(): parse_identifier failed.\n");
+ return EINVAL;
+ }
+ break;
+ }
+
+ case TYPE_INTERVAL:
+ case TYPE_INTERVAL_HR:
+ case TYPE_TIME:
+ case TYPE_TIME_HR: {
+ if (parse_time(type, payload, sizeof(payload), &state)) {
+ DEBUG("lcc_network_parse(): parse_time failed.\n");
+ return EINVAL;
+ }
+ break;
+ }
+
+ case TYPE_VALUES: {
+ lcc_value_list_t vl = state;
+ if (parse_values(payload, sizeof(payload), &vl)) {
+ free(vl.values);
+ free(vl.values_types);
+ DEBUG("lcc_network_parse(): parse_values failed.\n");
+ return EINVAL;
+ }
+
+ int status = 0;
+
+ /* Write metrics if they have the required security level. */
+ if (sl >= opts->security_level)
+ status = opts->writer(&vl);
+
+ free(vl.values);
+ free(vl.values_types);
+
+ if (status != 0)
+ return status;
+ break;
+ }
+
+ case TYPE_SIGN_SHA256: {
+ int status =
+ parse_sign_sha256(payload, sizeof(payload), b->data, b->len, opts);
+ if (status != 0) {
+ DEBUG("lcc_network_parse(): parse_sign_sha256() = %d\n", status);
+ return -1;
+ }
+ /* parse_sign_sha256, if successful, consumes all remaining data. */
+ b->data = NULL;
+ b->len = 0;
+ break;
+ }
+
+ case TYPE_ENCR_AES256: {
+ int status = parse_encrypt_aes256(payload, sizeof(payload), opts);
+ if (status != 0) {
+ DEBUG("lcc_network_parse(): parse_encrypt_aes256() = %d\n", status);
+ return -1;
+ }
+ break;
+ }
+
+ default: {
+ DEBUG("lcc_network_parse(): ignoring unknown type %" PRIu16 "\n", type);
+ return EINVAL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int lcc_network_parse(void *data, size_t data_size,
+ lcc_network_parse_options_t opts) {
+ if (opts.password_lookup) {
+#if HAVE_GCRYPT_H
+ int status;
+ if ((status = init_gcrypt())) {
+ return status;
+ }
+#else
+ return ENOTSUP;
+#endif
+ }
+
+ return network_parse(data, data_size, NONE, &opts);
+}
--- /dev/null
+/**
+ * Copyright 2017 Florian Forster
+ *
+ * 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:
+ * Florian octo Forster <octo at collectd.org>
+ **/
+
+#include "collectd/lcc_features.h"
+
+#include "collectd/network_buffer.h" /* for LCC_NETWORK_BUFFER_SIZE_DEFAULT */
+
+#include <assert.h>
+
+#include "network_parse.c" /* sic */
+
+char *raw_packet_data[] = {
+ "0000000e6c6f63616c686f7374000008000c1513676ac3a6e0970009000c00000002800000"
+ "000002000973776170000004000973776170000005000966726565000006000f0001010000"
+ "0080ff610f420008000c1513676ac3a8fc120004000c737761705f696f0000050007696e00"
+ "0006000f00010200000000000000000008000c1513676ac3a9077d000500086f7574000006"
+ "000f00010200000000000000000008000c1513676ac3bd2a8c0002000e696e746572666163"
+ "65000003000965746830000004000e69665f6f637465747300000500050000060018000202"
+ "02000000000000000000000000000000000008000c1513676ac3bd5a970004000e69665f65"
+ "72726f7273000006001800020202000000000000000000000000000000000008000c151367"
+ "6ac3bd7fea000300076c6f000004000e69665f6f6374657473000006001800020202000000"
+ "000009e79c000000000009e79c0008000c1513676ac3bdaae60003000a776c616e30000006"
+ "001800020202000000001009fa5400000000011cf6670008000c1513676ac3bdb0e0000400"
+ "0e69665f6572726f7273000006001800020202000000000000000000000000000000000008"
+ "000c1513676ac3bd3d6d0003000965746830000004000f69665f7061636b65747300000600"
+ "1800020202000000000000000000000000000000000008000c1513676ac3bdae290003000a"
+ "776c616e300000060018000202020000000000032f8f00000000000205e50008000c151367"
+ "6ac3bdbb7b0003000c646f636b657230000006001800020202000000000000000000000000"
+ "000000000008000c1513676ac3bda0db000300076c6f000004000e69665f6572726f727300"
+ "0006001800020202000000000000000000000000000000000008000c1513676ac3bdbde800"
+ "03000c646f636b657230000006001800020202000000000000000000000000000000000008"
+ "000c1513676ac3bd8d8e000300076c6f000004000f69665f7061636b657473000006001800"
+ "0202020000000000000c9c0000000000000c9c0008000c1513676ac3bdb90b0003000c646f"
+ "636b657230000004000e69665f6f6374657473000006001800020202000000000000000000"
+ "000000000000000008000c1513676ac469b10f0002000e70726f6365737365730000030005"
+ "000004000d70735f7374617465000005000c7a6f6d62696573000006000f00010100000000"
+ "000000000008000c1513676ac469a4a30005000d736c656570696e67000006000f00010100"
+ "00000000006e400008000c1513676ac469c6320005000b706167696e67000006000f000101"
+ "00000000000000000008000c1513676ac469f06e0005000c626c6f636b6564000006000f00"
+ "010100000000000000000008000c1513676ac4698af40005000c72756e6e696e6700000600"
+ "0f00010100000000000000000008000c1513676ac469bbe10005000c73746f707065640000"
+ "06000f00010100000000000000000008000c1513676ac46b8e710004000e666f726b5f7261"
+ "74650000050005000006000f0001020000000000001bcf0008000c1513676d437f12960002"
+ "00086370750000030006300000040008637075000005000b73797374656d000006000f0001"
+ "0200000000000021870008000c1513676d437f36020005000969646c65000006000f000102"
+ "000000000005847a0008000c1513676d437f979b0005000977616974000006000f00010200"
+ "000000000005210008000c1513676d43802ff60005000c736f6674697271000006000f0001"
+ "02000000000000001f0008000c1513676d43803b3a0005000a737465616c000006000f0001"
+ "020000000000000000",
+ "0000000e6c6f63616c686f7374000008000c1513676d4380551f0009000c00000002800000"
+ "00000200086370750000030006310000040008637075000005000975736572000006000f00"
+ "01020000000000007cad0008000c1513676d43805dbe000500096e696365000006000f0001"
+ "0200000000000001de0008000c1513676d4380697d0005000b73797374656d000006000f00"
+ "01020000000000001ce80008000c1513676d438072bd0005000969646c65000006000f0001"
+ "02000000000005931c0008000c1513676d43807c430005000977616974000006000f000102"
+ "000000000000094b0008000c1513676d43808cee0005000c736f6674697271000006000f00"
+ "010200000000000000120008000c1513676d4380843a0005000e696e746572727570740000"
+ "06000f00010200000000000000000008000c1513676d438096230005000a737465616c0000"
+ "06000f00010200000000000000000008000c1513676d4380aa9c0003000632000005000975"
+ "736572000006000f00010200000000000089580008000c1513676d4380b29f000500096e69"
+ "6365000006000f00010200000000000003610008000c1513676d4380c44c0005000969646c"
+ "65000006000f000102000000000005873d0008000c1513676d4380bc0f0005000b73797374"
+ "656d000006000f000102000000000000201d0008000c1513676d4380cea400050009776169"
+ "74000006000f00010200000000000005810008000c1513676d4380d7370005000e696e7465"
+ "7272757074000006000f00010200000000000000000008000c1513676d4380ea830005000a"
+ "737465616c000006000f00010200000000000000000008000c1513676d437eef6200030006"
+ "3000000500096e696365000006000f00010200000000000003920008000c1513676d4380e0"
+ "260003000632000005000c736f6674697271000006000f0001020000000000000016000800"
+ "0c1513676d438101410003000633000005000975736572000006000f000102000000000000"
+ "7d8a0008000c1513676d438109f5000500096e696365000006000f00010200000000000004"
+ "350008000c1513676d4380244b0003000630000005000e696e74657272757074000006000f"
+ "00010200000000000000000008000c1513676d438122070003000633000005000969646c65"
+ "000006000f0001020000000000058eb60008000c1513676d43812e83000500097761697400"
+ "0006000f0001020000000000000ca80008000c1513676d438141480005000c736f66746972"
+ "71000006000f000102000000000000001e0008000c1513676d43814a5d0005000a73746561"
+ "6c000006000f00010200000000000000000008000c1513676d4381149e0005000b73797374"
+ "656d000006000f0001020000000000001b9a0008000c1513676d437ea86000030006300000"
+ "05000975736572000006000f00010200000000000089a80008000c1513676d438138190003"
+ "000633000005000e696e74657272757074000006000f00010200000000000000000008000c"
+ "1513676d438a9ca00002000e696e74657266616365000003000965746830000004000e6966"
+ "5f6f6374657473000005000500000600180002020200000000000000000000000000000000"
+ "0008000c1513676d438aea760004000f69665f7061636b6574730000060018000202020000"
+ "00000000000000000000000000000008000c1513676d438b214d0004000e69665f6572726f"
+ "727300000600180002020200000000000000000000000000000000",
+ "0000000e6c6f63616c686f7374000008000c1513676d438aac590009000c00000002800000"
+ "000002000764660000030009726f6f74000004000f64665f636f6d706c6578000005000966"
+ "726565000006000f0001010000004c077e57420008000c1513676d438b6ada0005000d7265"
+ "736572766564000006000f00010100000000338116420008000c1513676d438b7a17000200"
+ "0e696e7465726661636500000300076c6f000004000e69665f6f6374657473000005000500"
+ "0006001800020202000000000009ecf5000000000009ecf50008000c1513676d438b757800"
+ "02000764660000030009726f6f74000004000f64665f636f6d706c65780000050009757365"
+ "64000006000f000101000000e0a41b26420008000c1513676d438b8ed20002000e696e7465"
+ "726661636500000300076c6f000004000e69665f6572726f72730000050005000006001800"
+ "020202000000000000000000000000000000000008000c1513676d438b86bf0004000f6966"
+ "5f7061636b6574730000060018000202020000000000000c9d0000000000000c9d0008000c"
+ "1513676d438bb3e60003000a776c616e300000060018000202020000000000032fab000000"
+ "00000205ed0008000c1513676d438bd62e0003000c646f636b657230000004000e69665f6f"
+ "6374657473000006001800020202000000000000000000000000000000000008000c151367"
+ "6d438bbc8f0003000a776c616e30000004000e69665f6572726f7273000006001800020202"
+ "000000000000000000000000000000000008000c1513676d438bdf030003000c646f636b65"
+ "7230000004000f69665f7061636b6574730000060018000202020000000000000000000000"
+ "00000000000008000c1513676d438baaf10003000a776c616e30000004000e69665f6f6374"
+ "65747300000600180002020200000000100a042300000000011cfa460008000c1513676d43"
+ "8c5f100002000764660000030009626f6f74000004000f64665f636f6d706c657800000500"
+ "0966726565000006000f0001010000000010e198410008000c1513676d438c689c0005000d"
+ "7265736572766564000006000f00010100000000804c68410008000c1513676d438c70ce00"
+ "05000975736564000006000f0001010000000020ea9e410008000c1513676d438be7bc0002"
+ "000e696e74657266616365000003000c646f636b657230000004000e69665f6572726f7273"
+ "0000050005000006001800020202000000000000000000000000000000000008000c151367"
+ "6d43beca8c0002000c656e74726f70790000030005000004000c656e74726f707900000600"
+ "0f0001010000000000088f400008000c1513676d43bf1d13000200096c6f61640000040009"
+ "6c6f6164000006002100030101019a9999999999a93f666666666666d63f5c8fc2f5285cdf"
+ "3f0008000c1513676d43c02b85000200096469736b00000300087364610000040010646973"
+ "6b5f6f63746574730000060018000202020000000075887800000000005b6f3c000008000c"
+ "1513676d43c06d1f0004000d6469736b5f6f7073000006001800020202000000000003cbbd"
+ "000000000001c0510008000c1513676d43c08b6a0004000e6469736b5f74696d6500000600"
+ "1800020202000000000000003f00000000000001720008000c1513676d43c0a5fb00040010"
+ "6469736b5f6d65726765640000060018000202020000000000001285000000000000f80100"
+ "08000c1513676d43c0c8b4000300097364613100000400106469736b5f6f63746574730000"
+ "060018000202020000000001107c000000000000003c00",
+ "0000000e6c6f63616c686f7374000008000c1513676d43c0d00a0009000c00000002800000"
+ "00000200096469736b000003000973646131000004000d6469736b5f6f7073000006001800"
+ "020202000000000000029b00000000000000080008000c1513676d43c0d7b20004000e6469"
+ "736b5f74696d650000060018000202020000000000000004000000000000000f0008000c15"
+ "13676d43c0df73000400106469736b5f6d6572676564000006001800020202000000000000"
+ "0fb400000000000000010008000c1513676d43c0f87c000300097364613200000400106469"
+ "736b5f6f637465747300000600180002020200000000000008000000000000000000000800"
+ "0c1513676d43c1003e0004000d6469736b5f6f707300000600180002020200000000000000"
+ "0200000000000000000008000c1513676d43c107bf000400106469736b5f6d657267656400"
+ "0006001800020202000000000000000000000000000000000008000c1513676d43c12fa400"
+ "03000973646135000004000d6469736b5f6f7073000006001800020202000000000003c867"
+ "000000000001aef20008000c1513676d43c13d5e000400106469736b5f6d65726765640000"
+ "0600180002020200000000000002d1000000000000f8000008000c1513676d43c136a90004"
+ "000e6469736b5f74696d65000006001800020202000000000000003f000000000000011c00"
+ "08000c1513676d43c1740500030009646d2d3000000400106469736b5f6f63746574730000"
+ "060018000202020000000074596400000000005b6f00000008000c1513676d43c179c70004"
+ "000d6469736b5f6f7073000006001800020202000000000003cae4000000000002b0f30008"
+ "000c1513676d43c18abe000400106469736b5f6d6572676564000006001800020202000000"
+ "000000000000000000000000000008000c1513676d43c181b90004000e6469736b5f74696d"
+ "650000060018000202020000000000000040000000000000013e0008000c1513676d43c1a9"
+ "5e00030009646d2d3100000400106469736b5f6f6374657473000006001800020202000000"
+ "00000e000000000000000000000008000c1513676d43c1b7ea0004000e6469736b5f74696d"
+ "65000006001800020202000000000000000200000000000000000008000c1513676d43c1b0"
+ "3e0004000d6469736b5f6f707300000600180002020200000000000000e000000000000000"
+ "000008000c1513676d43c1c00d000400106469736b5f6d6572676564000006001800020202"
+ "000000000000000000000000000000000008000c1513676d43c12818000300097364613500"
+ "000400106469736b5f6f637465747300000600180002020200000000746c6400000000005b"
+ "6f00000008000c1513676d43d320a80002000c62617474657279000003000630000004000b"
+ "636861726765000006000f0001018fc2f5285c2f58400008000c1513676d43d36fd6000400"
+ "0c63757272656e74000006000f00010100000000000000800008000c1513676d43d3cdb600"
+ "04000c766f6c74616765000006000f000101736891ed7cbf28400008000c1513676d43d59d"
+ "d60002000869727100000300050000040008697271000005000630000006000f0001020000"
+ "0000000000110008000c1513676d43d5d2cf0005000631000006000f000102000000000000"
+ "00100008000c1513676d43d5fe820005000638000006000f00010200000000000000010008"
+ "000c1513676d43d635440005000639000006000f00010200000000000035210008000c1513"
+ "676d43d66265000500073132000006000f0001020000000000000790",
+ "0000000e6c6f63616c686f7374000008000c1513676d43d68e940009000c00000002800000"
+ "0000020008697271000004000869727100000500073136000006000f000102000000000000"
+ "00210008000c1513676d43d69be20002000a7573657273000004000a757365727300000500"
+ "05000006000f00010100000000000010400008000c1513676d43d6aa5d0002000869727100"
+ "0004000869727100000500073233000006000f00010200000000000000250008000c151367"
+ "6d43d6c7dc000500073431000006000f000102000000000000ff7d0008000c1513676d43d6"
+ "e23d000500073432000006000f00010200000000000008070008000c1513676d43d9aa3a00"
+ "0500073437000006000f0001020000000000079a260008000c1513676d43d9cca900050007"
+ "3438000006000f00010200000000000000c70008000c1513676d43d9ea5d00050007343900"
+ "0006000f00010200000000000004c20008000c1513676d43da050e00050007353000000600"
+ "0f000102000000000000001c0008000c1513676d43da1efa000500084e4d49000006000f00"
+ "010200000000000000000008000c1513676d43da3c82000500084c4f43000006000f000102"
+ "000000000018d3080008000c1513676d43da544e00050008535055000006000f0001020000"
+ "0000000000000008000c1513676d43da6cca00050008504d49000006000f00010200000000"
+ "000000000008000c1513676d43da885400050008495749000006000f000102000000000000"
+ "a9da0008000c1513676d43daa23a00050008525452000006000f0001020000000000000003"
+ "0008000c1513676d43dabaed00050008524553000006000f00010200000000000ac8360008"
+ "000c1513676d43dad4150005000843414c000006000f000102000000000000191f0008000c"
+ "1513676d43daeef300050008544c42000006000f000102000000000003dbdc0008000c1513"
+ "676d43db11410005000854524d000006000f00010200000000000000000008000c1513676d"
+ "43db292c00050008544852000006000f00010200000000000000000008000c1513676d43db"
+ "411d000500084d4345000006000f00010200000000000000000008000c1513676d43db5b59"
+ "000500084d4350000006000f000102000000000000003c0008000c1513676d43db68010005"
+ "0008455252000006000f00010200000000000000000008000c1513676d43db758a00050008"
+ "4d4953000006000f00010200000000000000000008000c1513676d43dd2e800002000b6d65"
+ "6d6f7279000004000b6d656d6f7279000005000975736564000006000f00010100000000fe"
+ "bbe0410008000c1513676d43dd3f4b0005000d6275666665726564000006000f0001010000"
+ "000070fbc8410008000c1513676d43dd48700005000b636163686564000006000f00010100"
+ "000000c008df410008000c1513676d43dd51c60005000966726565000006000f0001010000"
+ "0080481d05420008000c1513676d43dec7e300020009737761700000040009737761700000"
+ "05000975736564000006000f00010100000000000000000008000c1513676d43ded4490005"
+ "000966726565000006000f00010100000080ff610f420008000c1513676d43dedcfd000500"
+ "0b636163686564000006000f00010100000000000000000008000c1513676d43d715e30002"
+ "0008697271000004000869727100000500073434000006000f0001020000000000031b6100"
+ "08000c1513676d43d73116000500073435000006000f00010200000000000000180008000c"
+ "1513676d43ee00150002000973776170000004000c737761705f696f0000050007696e0000"
+ "06000f0001020000000000000000",
+};
+
+static int decode_string(char const *in, uint8_t *out, size_t *out_size) {
+ size_t in_size = strlen(in);
+ if (*out_size < (in_size / 2))
+ return -1;
+ *out_size = in_size / 2;
+
+ for (size_t i = 0; i < *out_size; i++) {
+ char tmp[] = {in[2 * i], in[2 * i + 1], 0};
+ out[i] = (uint8_t)strtoul(tmp, NULL, 16);
+ }
+
+ return 0;
+}
+
+static int nop_writer(lcc_value_list_t const *vl) {
+ if (!strlen(vl->identifier.host) || !strlen(vl->identifier.plugin) ||
+ !strlen(vl->identifier.type)) {
+ return EINVAL;
+ }
+ return 0;
+}
+
+static int test_network_parse() {
+ int ret = 0;
+
+ for (size_t i = 0; i < sizeof(raw_packet_data) / sizeof(raw_packet_data[0]);
+ i++) {
+ uint8_t buffer[LCC_NETWORK_BUFFER_SIZE_DEFAULT];
+ size_t buffer_size = sizeof(buffer);
+ if (decode_string(raw_packet_data[i], buffer, &buffer_size)) {
+ fprintf(
+ stderr,
+ "lcc_network_parse(raw_packet_data[%zu]): decoding string failed\n",
+ i);
+ return -1;
+ }
+
+ int status =
+ lcc_network_parse(buffer, buffer_size, (lcc_network_parse_options_t){
+ .writer = nop_writer,
+ });
+ if (status != 0) {
+ fprintf(stderr, "lcc_network_parse(raw_packet_data[%zu]) = %d, want 0\n",
+ i, status);
+ ret = status;
+ }
+
+ printf("ok - lcc_network_parse(raw_packet_data[%zu])\n", i);
+ }
+
+ return ret;
+}
+
+static int test_parse_time() {
+ int ret = 0;
+
+ struct {
+ uint64_t in;
+ double want;
+ } cases[] = {
+ {1439980823, 1439980823.0},
+ {1439981005, 1439981005.0},
+ {1439981150, 1439981150.0},
+ };
+
+ for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
+ lcc_value_list_t vl = LCC_VALUE_LIST_INIT;
+
+ uint64_t be = htobe64(cases[i].in);
+ int status = parse_time(TYPE_TIME, &be, sizeof(be), &vl);
+ if ((status != 0) || (vl.time != cases[i].want)) {
+ fprintf(stderr, "parse_time(%" PRIu64 ") = (%.0f, %d), want (%.0f, 0)\n",
+ cases[i].in, vl.time, status, cases[i].want);
+ ret = -1;
+ }
+ }
+
+ struct {
+ uint64_t in;
+ double want;
+ } cases_hr[] = {
+ {1546167635576736987, 1439980823.152453627},
+ {1546167831554815222, 1439981005.671262017},
+ {1546167986577716567, 1439981150.047589622},
+ };
+
+ for (size_t i = 0; i < sizeof(cases_hr) / sizeof(cases_hr[0]); i++) {
+ lcc_value_list_t vl = LCC_VALUE_LIST_INIT;
+
+ uint64_t be = htobe64(cases_hr[i].in);
+ int status = parse_time(TYPE_TIME_HR, &be, sizeof(be), &vl);
+ if ((status != 0) || (vl.time != cases_hr[i].want)) {
+ fprintf(stderr, "parse_time(%" PRIu64 ") = (%.9f, %d), want (%.9f, 0)\n",
+ cases_hr[i].in, vl.time, status, cases_hr[i].want);
+ ret = -1;
+ }
+ }
+
+ return ret;
+}
+
+static int test_parse_string() {
+ int ret = 0;
+
+ struct {
+ uint8_t *in;
+ size_t in_len;
+ char *want;
+ } cases[] = {
+ {(uint8_t[]){0}, 1, ""},
+ {(uint8_t[]){'t', 'e', 's', 't', 0}, 5, "test"},
+ {(uint8_t[]){'t', 'e', 's', 't'}, 4, NULL}, // null byte missing
+ {(uint8_t[]){'t', 'e', 's', 't', 'x', 0}, 6,
+ NULL}, // output buffer too small
+ };
+
+ for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
+ char got[5] = {0};
+
+ int status = parse_string(cases[i].in, cases[i].in_len, got, sizeof(got));
+ if (cases[i].want == NULL) {
+ if (status == 0) {
+ fprintf(stderr, "parse_string() = (\"%s\", 0), want error\n", got);
+ ret = -1;
+ }
+ } else /* if cases[i].want != NULL */ {
+ if (status != 0) {
+ fprintf(stderr, "parse_string() = %d, want 0\n", status);
+ ret = -1;
+ } else if (strcmp(got, cases[i].want) != 0) {
+ fprintf(stderr, "parse_string() = (\"%s\", 0), want (\"%s\", 0)\n", got,
+ cases[i].want);
+ ret = -1;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static int test_parse_values() {
+ int ret = 0;
+
+ uint8_t testcase[] = {
+ // 0, 6, // pkg type
+ // 0, 33, // pkg len
+ 0, 3, // num values
+ 1, 2, 1, // gauge, derive, gauge
+ 0, 0, 0, 0, 0, 0, 0x45, 0x40, // 42.0
+ 0, 0, 0, 0, 0, 0, 0x7a, 0x69, // 31337
+ 0, 0, 0, 0, 0, 0, 0xf8, 0x7f, // NaN
+ };
+
+ lcc_value_list_t vl = LCC_VALUE_LIST_INIT;
+ int status = parse_values(testcase, sizeof(testcase), &vl);
+ if (status != 0) {
+ fprintf(stderr, "parse_values() = %d, want 0\n", status);
+ return -1;
+ }
+
+ if (vl.values_len != 3) {
+ fprintf(stderr, "parse_values(): vl.values_len = %zu, want 3\n",
+ vl.values_len);
+ return -1;
+ }
+
+ int want_types[] = {LCC_TYPE_GAUGE, LCC_TYPE_DERIVE, LCC_TYPE_GAUGE};
+ for (size_t i = 0; i < sizeof(want_types) / sizeof(want_types[0]); i++) {
+ if (vl.values_types[i] != want_types[i]) {
+ fprintf(stderr, "parse_values(): vl.values_types[%zu] = %d, want %d\n", i,
+ vl.values_types[i], want_types[i]);
+ ret = -1;
+ }
+ }
+
+ if (vl.values[0].gauge != 42.0) {
+ fprintf(stderr, "parse_values(): vl.values[0] = %g, want 42\n",
+ vl.values[0].gauge);
+ ret = -1;
+ }
+ if (vl.values[1].derive != 31337) {
+ fprintf(stderr, "parse_values(): vl.values[1] = %" PRIu64 ", want 31337\n",
+ vl.values[1].derive);
+ ret = -1;
+ }
+ if (!isnan(vl.values[2].gauge)) {
+ fprintf(stderr, "parse_values(): vl.values[2] = %g, want NaN\n",
+ vl.values[2].gauge);
+ ret = -1;
+ }
+
+ free(vl.values);
+ free(vl.values_types);
+
+ return ret;
+}
+
+#if HAVE_GCRYPT_H
+static int test_verify_sha256() {
+ int ret = 0;
+
+ int status = verify_sha256(
+ (char[]){'c', 'o', 'l', 'l', 'e', 'c', 't', 'd'}, 8, "admin", "admin",
+ (uint8_t[]){
+ 0xcd, 0xa5, 0x9a, 0x37, 0xb0, 0x81, 0xc2, 0x31, 0x24, 0x2a, 0x6d,
+ 0xbd, 0xfb, 0x44, 0xdb, 0xd7, 0x41, 0x2a, 0xf4, 0x29, 0x83, 0xde,
+ 0xa5, 0x11, 0x96, 0xd2, 0xe9, 0x30, 0x21, 0xae, 0xc5, 0x45,
+ });
+ if (status != 0) {
+ fprintf(stderr, "verify_sha256() = %d, want 0\n", status);
+ ret = -1;
+ }
+
+ status = verify_sha256(
+ (char[]){'c', 'o', 'l', 'l', 'E', 'c', 't', 'd'}, 8, "admin", "admin",
+ (uint8_t[]){
+ 0xcd, 0xa5, 0x9a, 0x37, 0xb0, 0x81, 0xc2, 0x31, 0x24, 0x2a, 0x6d,
+ 0xbd, 0xfb, 0x44, 0xdb, 0xd7, 0x41, 0x2a, 0xf4, 0x29, 0x83, 0xde,
+ 0xa5, 0x11, 0x96, 0xd2, 0xe9, 0x30, 0x21, 0xae, 0xc5, 0x45,
+ });
+ if (status != 1) {
+ fprintf(stderr, "verify_sha256() = %d, want 1\n", status);
+ ret = -1;
+ }
+
+ return ret;
+}
+#endif
+
+#if HAVE_GCRYPT_H
+static int test_decrypt_aes256() {
+ char const *iv_str = "4cbe2a747c9f9dcfa0e66f0c2fa74875";
+ uint8_t iv[16] = {0};
+ size_t iv_len = sizeof(iv);
+
+ char const *ciphertext_str =
+ "8f023b0b15178f8428da1221a5f653e840f065db4aff032c22e5a3df";
+ uint8_t ciphertext[28] = {0};
+ size_t ciphertext_len = sizeof(ciphertext);
+
+ if (decode_string(iv_str, iv, &iv_len) ||
+ decode_string(ciphertext_str, ciphertext, &ciphertext_len)) {
+ fprintf(stderr, "test_decrypt_aes256: decode_string failed.\n");
+ return -1;
+ }
+ assert(iv_len == sizeof(iv));
+ assert(ciphertext_len == sizeof(ciphertext));
+
+ int status = decrypt_aes256(
+ &(buffer_t){
+ .data = ciphertext, .len = ciphertext_len,
+ },
+ iv, iv_len, "admin");
+ if (status != 0) {
+ fprintf(stderr, "decrypt_aes256() = %d, want 0\n", status);
+ return -1;
+ }
+
+ char const *want = "collectd";
+ char got[9] = {0};
+ memmove(got, &ciphertext[20], sizeof(got) - 1);
+ if (strcmp(got, want) != 0) {
+ fprintf(stderr, "decrypt_aes256() = \"%s\", want \"%s\"\n", got, want);
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
+int main(void) {
+ int ret = 0;
+
+ int status;
+ if ((status = test_network_parse())) {
+ ret = status;
+ }
+ if ((status = test_parse_time())) {
+ ret = status;
+ }
+ if ((status = test_parse_string())) {
+ ret = status;
+ }
+ if ((status = test_parse_values())) {
+ ret = status;
+ }
+
+#if HAVE_GCRYPT_H
+ if ((status = test_verify_sha256())) {
+ ret = status;
+ }
+ if ((status = test_decrypt_aes256())) {
+ ret = status;
+ }
+#endif
+
+ return ret;
+}
--- /dev/null
+/**
+ * Copyright 2017 Florian Forster
+ *
+ * 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:
+ * Florian octo Forster <octo at collectd.org>
+ **/
+
+#include "config.h"
+
+#if !defined(__GNUC__) || !__GNUC__
+#define __attribute__(x) /**/
+#endif
+
+#include "collectd/lcc_features.h"
+#include "collectd/network_parse.h" /* for lcc_network_parse_options_t */
+#include "collectd/server.h"
+
+#include <errno.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <stdio.h>
+#define DEBUG(...) printf(__VA_ARGS__)
+
+static _Bool is_multicast(struct addrinfo const *ai) {
+ if (ai->ai_family == AF_INET) {
+ struct sockaddr_in *addr = (struct sockaddr_in *)ai->ai_addr;
+ return IN_MULTICAST(ntohl(addr->sin_addr.s_addr));
+ } else if (ai->ai_family == AF_INET6) {
+ struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ai->ai_addr;
+ return IN6_IS_ADDR_MULTICAST(&addr->sin6_addr);
+ }
+ return 0;
+}
+
+static int server_multicast_join(lcc_listener_t *srv,
+ struct sockaddr_storage *group, int loop_back,
+ int ttl) {
+ if (group->ss_family == AF_INET) {
+ struct sockaddr_in *sa = (struct sockaddr_in *)group;
+
+ int status = setsockopt(srv->conn, IPPROTO_IP, IP_MULTICAST_LOOP,
+ &loop_back, sizeof(loop_back));
+ if (status == -1) {
+ DEBUG("setsockopt(IP_MULTICAST_LOOP, %d) = %d\n", loop_back, errno);
+ return errno;
+ }
+
+ status =
+ setsockopt(srv->conn, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
+ if (status == -1)
+ return errno;
+
+#if HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
+ struct ip_mreqn mreq = {
+ .imr_address.s_addr = INADDR_ANY,
+ .imr_multiaddr.s_addr = sa->sin_addr.s_addr,
+ .imr_ifindex = if_nametoindex(srv->interface),
+ };
+#else
+ struct ip_mreq mreq = {
+ .imr_multiaddr.s_addr = sa->sin_addr.s_addr,
+ };
+#endif
+ status = setsockopt(srv->conn, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
+ sizeof(mreq));
+ if (status == -1)
+ return errno;
+ } else if (group->ss_family == AF_INET6) {
+ struct sockaddr_in6 *sa = (struct sockaddr_in6 *)group;
+
+ int status = setsockopt(srv->conn, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
+ &loop_back, sizeof(loop_back));
+ if (status == -1)
+ return errno;
+
+ status = setsockopt(srv->conn, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl,
+ sizeof(ttl));
+ if (status == -1)
+ return errno;
+
+ struct ipv6_mreq mreq6 = {
+ .ipv6mr_interface = if_nametoindex(srv->interface),
+ };
+ memmove(&mreq6.ipv6mr_multiaddr, &sa->sin6_addr, sizeof(struct in6_addr));
+
+ status = setsockopt(srv->conn, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6,
+ sizeof(mreq6));
+ if (status == -1)
+ return errno;
+ } else {
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static int server_bind_socket(lcc_listener_t *srv, struct addrinfo const *ai) {
+ /* allow multiple sockets to use the same PORT number */
+ if (setsockopt(srv->conn, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) ==
+ -1) {
+ return errno;
+ }
+
+ if (bind(srv->conn, ai->ai_addr, ai->ai_addrlen) == -1) {
+ return -1;
+ }
+
+ if (is_multicast(ai)) {
+ int status = server_multicast_join(srv, (void *)ai->ai_addr, /* loop = */ 1,
+ /* ttl = */ 16);
+ if (status != 0)
+ return status;
+ }
+
+ return 0;
+}
+
+static int server_open(lcc_listener_t *srv) {
+ struct addrinfo *res = NULL;
+ int status = getaddrinfo(srv->node ? srv->node : "::",
+ srv->service ? srv->service : LCC_DEFAULT_PORT,
+ &(struct addrinfo){
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_DGRAM,
+ },
+ &res);
+ if (status != 0)
+ return status;
+
+ for (struct addrinfo *ai = res; ai != NULL; ai = ai->ai_next) {
+ srv->conn = socket(ai->ai_family, ai->ai_socktype, 0);
+ if (srv->conn == -1)
+ continue;
+
+ status = server_bind_socket(srv, ai);
+ if (status != 0) {
+ close(srv->conn);
+ srv->conn = -1;
+ continue;
+ }
+
+ break;
+ }
+
+ freeaddrinfo(res);
+
+ if (srv->conn >= 0)
+ return 0;
+ return status != 0 ? status : -1;
+}
+
+int lcc_listen_and_write(lcc_listener_t srv) {
+ _Bool close_socket = 0;
+
+ if (srv.conn < 0) {
+ int status = server_open(&srv);
+ if (status != 0)
+ return status;
+ close_socket = 1;
+ }
+
+ if (srv.buffer_size == 0)
+ srv.buffer_size = LCC_NETWORK_BUFFER_SIZE;
+
+ if (srv.parser == NULL)
+ srv.parser = lcc_network_parse;
+
+ int ret = 0;
+ while (42) {
+ char buffer[srv.buffer_size];
+ ssize_t len = recv(srv.conn, buffer, sizeof(buffer), /* flags = */ 0);
+ if (len == -1) {
+ ret = errno;
+ break;
+ } else if (len == 0) {
+ break;
+ }
+
+ (void)srv.parser(buffer, (size_t)len, srv.parse_options);
+ }
+
+ if (close_socket) {
+ close(srv.conn);
+ srv.conn = -1;
+ }
+
+ return ret;
+}
+++ /dev/null
-BUILT_SOURCES = parser.h
-#CLEANFILES = parser.[ch] scanner.c
-AM_YFLAGS = -d
-
-noinst_LTLIBRARIES = liboconfig.la
-
-liboconfig_la_LDFLAGS = -avoid-version $(LEXLIB)
-liboconfig_la_SOURCES = oconfig.c oconfig.h aux_types.h scanner.l parser.y
status = yyparse();
if (status != 0) {
fprintf(stderr, "yyparse returned error #%i\n", status);
- return (NULL);
+ return NULL;
}
c_file = NULL;
ci_root = NULL;
yyset_in((FILE *)0);
- return (ret);
+ return ret;
} /* oconfig_item_t *oconfig_parse_fh */
oconfig_item_t *oconfig_parse_file(const char *file) {
fh = fopen(file, "r");
if (fh == NULL) {
fprintf(stderr, "fopen (%s) failed: %s\n", file, strerror(errno));
- return (NULL);
+ return NULL;
}
ret = oconfig_parse_fh(fh);
c_file = NULL;
- return (ret);
+ return ret;
} /* oconfig_item_t *oconfig_parse_file */
oconfig_item_t *oconfig_clone(const oconfig_item_t *ci_orig) {
ci_copy = calloc(1, sizeof(*ci_copy));
if (ci_copy == NULL) {
fprintf(stderr, "calloc failed.\n");
- return (NULL);
+ return NULL;
}
ci_copy->values = NULL;
ci_copy->parent = NULL;
if (ci_copy->key == NULL) {
fprintf(stderr, "strdup failed.\n");
free(ci_copy);
- return (NULL);
+ return NULL;
}
if (ci_orig->values_num > 0) /* {{{ */
fprintf(stderr, "calloc failed.\n");
free(ci_copy->key);
free(ci_copy);
- return (NULL);
+ return NULL;
}
ci_copy->values_num = ci_orig->values_num;
if (ci_copy->values[i].value.string == NULL) {
fprintf(stderr, "strdup failed.\n");
oconfig_free(ci_copy);
- return (NULL);
+ return NULL;
}
} else /* ci_copy->values[i].type != OCONFIG_TYPE_STRING) */
{
if (ci_copy->children == NULL) {
fprintf(stderr, "calloc failed.\n");
oconfig_free(ci_copy);
- return (NULL);
+ return NULL;
}
ci_copy->children_num = ci_orig->children_num;
child = oconfig_clone(ci_orig->children + i);
if (child == NULL) {
oconfig_free(ci_copy);
- return (NULL);
+ return NULL;
}
child->parent = ci_copy;
ci_copy->children[i] = *child;
} /* for (i = 0; i < ci_copy->children_num; i++) */
} /* }}} if (ci_orig->children_num > 0) */
- return (ci_copy);
+ return ci_copy;
} /* oconfig_item_t *oconfig_clone */
static void oconfig_free_all(oconfig_item_t *ci) {
oconfig_free_all(ci);
free(ci);
}
-
-/*
- * vim:shiftwidth=2:tabstop=8:softtabstop=2:fdm=marker
- */
void oconfig_free(oconfig_item_t *ci);
-/*
- * vim: shiftwidth=2:tabstop=8:softtabstop=2
- */
#endif /* OCONFIG_H */
"is not available, because I can't determine the "
"number of CPUS on this system. Sorry.");
#endif
- return (-1);
+ return -1;
}
static void load_submit(gauge_t snum, gauge_t mnum, gauge_t lnum) {
int cores = 0;
if ((loadavg = fopen("/proc/loadavg", "r")) == NULL) {
char errbuf[1024];
WARNING("load: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
if (fgets(buffer, 16, loadavg) == NULL) {
char errbuf[1024];
WARNING("load: fgets: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
fclose(loadavg);
- return (-1);
+ return -1;
}
if (fclose(loadavg)) {
numfields = strsplit(buffer, fields, 8);
if (numfields < 3)
- return (-1);
+ return -1;
snum = atof(fields[0]);
mnum = atof(fields[1]);
char errbuf[1024];
WARNING("load: perfstat_cpu : %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
snum = (float)cputotal.loadavg[0] / (float)(1 << SBITS);
#error "No applicable input method."
#endif
- return (0);
+ return 0;
}
void module_register(void) {
if (g == NULL) {
fprintf(stderr, "Could not allocate JSON generator.\n");
- return (0);
+ return 0;
}
if (yajl_gen_map_open(g) != yajl_gen_status_ok)
}
log_logstash_print(g, LOG_INFO, (n->time != 0) ? n->time : cdtime());
- return (0);
+ return 0;
err:
yajl_gen_free(g);
fprintf(stderr, "Could not correctly generate JSON notification\n");
- return (0);
+ return 0;
} /* int log_logstash_notification */
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 : */
if (log_level < 0) {
log_level = LOG_INFO;
ERROR("logfile: invalid loglevel [%s] defaulting to 'info'", value);
- return (1);
+ return 1;
}
} else if (0 == strcasecmp(key, "File")) {
sfree(log_file);
int buf_len = sizeof(buf);
int status;
- status = ssnprintf(
+ status = snprintf(
buf_ptr, buf_len, "Notification: severity = %s",
(n->severity == NOTIF_FAILURE)
? "FAILURE"
#define APPEND(bufptr, buflen, key, value) \
if ((buflen > 0) && (strlen(value) > 0)) { \
- status = ssnprintf(bufptr, buflen, ", %s = %s", key, value); \
+ status = snprintf(bufptr, buflen, ", %s = %s", key, value); \
if (status > 0) { \
bufptr += status; \
buflen -= status; \
logfile_print(buf, LOG_INFO, (n->time != 0) ? n->time : cdtime());
- return (0);
+ return 0;
} /* int logfile_notification */
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 : */
else
report_by_serial = 0;
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int lpar_config */
static int lpar_init(void) {
char errbuf[1024];
ERROR("lpar plugin: perfstat_partition_total failed: %s (%i)",
sstrerror(errno, errbuf, sizeof(errbuf)), status);
- return (-1);
+ return -1;
}
#if PERFSTAT_SUPPORTS_DONATION
pool_stats = 0;
}
- return (0);
+ return 0;
} /* int lpar_init */
static void lpar_submit(const char *type_instance, double value) {
from chassis to chassis through Live Partition Mobility (LPM). */
if (uname(&name) != 0) {
ERROR("lpar plugin: uname failed.");
- return (-1);
+ return -1;
}
sstrncpy(serial, name.machine, sizeof(serial));
char errbuf[1024];
ERROR("lpar plugin: perfstat_partition_total failed: %s (%i)",
sstrerror(errno, errbuf, sizeof(errbuf)), status);
- return (-1);
+ return -1;
}
/* Number of ticks since we last run. */
if (ticks == 0) {
/* The stats have not been updated. Return now to avoid
* dividing by zero */
- return (0);
+ return 0;
}
/*
if (pool_busy_cpus < 0.0)
pool_busy_cpus = 0.0;
- ssnprintf(typinst, sizeof(typinst), "pool-%X-busy", lparstats.pool_id);
+ snprintf(typinst, sizeof(typinst), "pool-%X-busy", lparstats.pool_id);
lpar_submit(typinst, pool_busy_cpus);
- ssnprintf(typinst, sizeof(typinst), "pool-%X-idle", lparstats.pool_id);
+ snprintf(typinst, sizeof(typinst), "pool-%X-idle", lparstats.pool_id);
lpar_submit(typinst, pool_idle_cpus);
}
memcpy(&lparstats_old, &lparstats, sizeof(lparstats_old));
- return (0);
+ return 0;
} /* int lpar_read */
void module_register(void) {
plugin_register_init("lpar", lpar_init);
plugin_register_read("lpar", lpar_read);
} /* void module_register */
-
-/* vim: set sw=8 noet : */
if (!lua_isfunction(L, -1)) {
lua_pop(L, 1);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int clua_load_callback */
/* Store the threads in a global variable so they are not cleaned up by the
lua_pushvalue(L, idx); /* +1 = 3 */
if (!lua_isthread(L, -1)) {
lua_pop(L, 3); /* -3 = 0 */
- return (-1);
+ return -1;
}
luaL_ref(L, LUA_REGISTRYINDEX);
lua_pop(L, 1); /* -1 = 0 */
- return (0);
+ return 0;
} /* }}} int clua_store_thread */
static int clua_read(user_data_t *ud) /* {{{ */
ERROR("Lua plugin: Unable to load callback \"%s\" (id %i).",
cb->lua_function_name, cb->callback_id);
pthread_mutex_unlock(&cb->lock);
- return (-1);
+ return -1;
}
/* +1 = 1 */
ERROR("Lua plugin: Calling a read callback failed: %s", errmsg);
lua_pop(L, 1);
pthread_mutex_unlock(&cb->lock);
- return (-1);
+ return -1;
}
if (!lua_isnumber(L, -1)) {
lua_pop(L, 1); /* -1 = 0 */
pthread_mutex_unlock(&cb->lock);
- return (status);
+ return status;
} /* }}} int clua_read */
static int clua_write(const data_set_t *ds, const value_list_t *vl, /* {{{ */
ERROR("Lua plugin: Unable to load callback \"%s\" (id %i).",
cb->lua_function_name, cb->callback_id);
pthread_mutex_unlock(&cb->lock);
- return (-1);
+ return -1;
}
/* +1 = 1 */
lua_pop(L, 1); /* -1 = 0 */
pthread_mutex_unlock(&cb->lock);
ERROR("Lua plugin: luaC_pushvaluelist failed.");
- return (-1);
+ return -1;
}
/* +1 = 2 */
ERROR("Lua plugin: Calling the write callback failed:\n%s", errmsg);
lua_pop(L, 1); /* -1 = 0 */
pthread_mutex_unlock(&cb->lock);
- return (-1);
+ return -1;
}
if (!lua_isnumber(L, -1)) {
lua_pop(L, 1); /* -1 = 0 */
pthread_mutex_unlock(&cb->lock);
- return (status);
+ return status;
} /* }}} int clua_write */
/*
luaL_checktype(L, 1, LUA_TFUNCTION);
char function_name[DATA_MAX_NAME_LEN];
- ssnprintf(function_name, sizeof(function_name), "lua/%s", lua_tostring(L, 1));
+ snprintf(function_name, sizeof(function_name), "lua/%s", lua_tostring(L, 1));
int callback_id = clua_store_callback(L, 1);
if (callback_id < 0)
int status = plugin_register_complex_read(/* group = */ "lua",
/* name = */ function_name,
/* callback = */ clua_read,
- /* interval = */ 0, &(user_data_t){
- .data = cb,
- });
+ /* interval = */ 0,
+ &(user_data_t){
+ .data = cb,
+ });
if (status != 0)
return luaL_error(L, "%s", "plugin_register_complex_read failed");
luaL_checktype(L, 1, LUA_TFUNCTION);
char function_name[DATA_MAX_NAME_LEN] = "";
- ssnprintf(function_name, sizeof(function_name), "lua/%s", lua_tostring(L, 1));
+ snprintf(function_name, sizeof(function_name), "lua/%s", lua_tostring(L, 1));
int callback_id = clua_store_callback(L, 1);
if (callback_id < 0)
cb->lua_function_name = strdup(function_name);
pthread_mutex_init(&cb->lock, NULL);
- int status =
- plugin_register_write(/* name = */ function_name,
- /* callback = */ clua_write, &(user_data_t){
- .data = cb,
- });
+ int status = plugin_register_write(/* name = */ function_name,
+ /* callback = */ clua_write,
+ &(user_data_t){
+ .data = cb,
+ });
if (status != 0)
return luaL_error(L, "%s", "plugin_register_write failed");
script->lua_state = luaL_newstate();
if (script->lua_state == NULL) {
ERROR("Lua plugin: luaL_newstate() failed.");
- return (-1);
+ return -1;
}
/* Open up all the standard Lua libraries. */
lua_pop(script->lua_state, 1);
}
- return (0);
+ return 0;
} /* }}} int lua_script_init */
static int lua_script_load(const char *script_path) /* {{{ */
lua_script_t *script = malloc(sizeof(*script));
if (script == NULL) {
ERROR("Lua plugin: malloc failed.");
- return (-1);
+ return -1;
}
int status = lua_script_init(script);
if (status != 0) {
lua_script_free(script);
- return (status);
+ return status;
}
script->script_path = strdup(script_path);
if (script->script_path == NULL) {
ERROR("Lua plugin: strdup failed.");
lua_script_free(script);
- return (-1);
+ return -1;
}
status = luaL_loadfile(script->lua_state, script->script_path);
lua_tostring(script->lua_state, -1));
lua_pop(script->lua_state, 1);
lua_script_free(script);
- return (-1);
+ return -1;
}
status = lua_pcall(script->lua_state,
script->script_path, errmsg);
lua_script_free(script);
- return (-1);
+ return -1;
}
/* Append this script to the global list of scripts. */
scripts = script;
}
- return (0);
+ return 0;
} /* }}} int lua_script_load */
static int lua_config_base_path(const oconfig_item_t *ci) /* {{{ */
{
int status = cf_util_get_string_buffer(ci, base_path, sizeof(base_path));
if (status != 0)
- return (status);
+ return status;
size_t len = strlen(base_path);
while ((len > 0) && (base_path[len - 1] == '/')) {
DEBUG("Lua plugin: base_path = \"%s\";", base_path);
- return (0);
+ return 0;
} /* }}} int lua_config_base_path */
static int lua_config_script(const oconfig_item_t *ci) /* {{{ */
int status = cf_util_get_string_buffer(ci, rel_path, sizeof(rel_path));
if (status != 0)
- return (status);
+ return status;
char abs_path[PATH_MAX];
if (base_path[0] == '\0')
sstrncpy(abs_path, rel_path, sizeof(abs_path));
else
- ssnprintf(abs_path, sizeof(abs_path), "%s/%s", base_path, rel_path);
+ snprintf(abs_path, sizeof(abs_path), "%s/%s", base_path, rel_path);
DEBUG("Lua plugin: abs_path = \"%s\";", abs_path);
status = lua_script_load(abs_path);
if (status != 0)
- return (status);
+ return status;
INFO("Lua plugin: File \"%s\" loaded successfully", abs_path);
{
lua_script_free(scripts);
- return (0);
+ return 0;
} /* }}} int lua_shutdown */
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 : */
* Benjamin Gilbert <bgilbert at backtick.net>
**/
-#include <lvm2app.h>
-
#include "collectd.h"
#include "common.h"
#include "plugin.h"
+#include <lvm2app.h>
+
+#ifdef HAVE_SYS_CAPABILITY_H
+#include <sys/capability.h>
+#endif /* HAVE_SYS_CAPABILITY_H */
+
#define NO_VALUE UINT64_MAX
#define PERCENT_SCALE_FACTOR 1e-8
return;
used_bytes = lv_size * (used_percent_unscaled * PERCENT_SCALE_FACTOR);
- ssnprintf(plugin_instance, sizeof(plugin_instance), "%s-%s", vg_name,
- lv_name);
+ snprintf(plugin_instance, sizeof(plugin_instance), "%s-%s", vg_name, lv_name);
lvm_submit(plugin_instance, "used", used_bytes);
lvm_submit(plugin_instance, "free", lv_size - used_bytes);
}
lvm = lvm_init(NULL);
if (!lvm) {
ERROR("lvm plugin: lvm_init failed.");
- return (-1);
+ return -1;
}
vg_names = lvm_list_vg_names(lvm);
if (!vg_names) {
ERROR("lvm plugin lvm_list_vg_name failed %s", lvm_errmsg(lvm));
lvm_quit(lvm);
- return (-1);
+ return -1;
}
dm_list_iterate_items(name_list, vg_names) {
}
lvm_quit(lvm);
- return (0);
+ return 0;
} /*lvm_read */
+static int c_lvm_init(void) {
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_ADMIN)
+ if (check_capability(CAP_SYS_ADMIN) != 0) {
+ if (getuid() == 0)
+ WARNING("lvm plugin: Running collectd as root, but the "
+ "CAP_SYS_ADMIN capability is missing. The plugin's read "
+ "function will probably fail. Is your init system dropping "
+ "capabilities?");
+ else
+ WARNING("lvm plugin: collectd doesn't have the CAP_SYS_ADMIN "
+ "capability. If you don't want to run collectd as root, try "
+ "running \"setcap cap_sys_admin=ep\" on the collectd binary.");
+ }
+#endif
+ return 0;
+}
+
void module_register(void) {
+ plugin_register_init("lvm", c_lvm_init);
plugin_register_read("lvm", lvm_read);
} /* void module_register */
for (size_t i = 0; i < STATIC_ARRAY_SIZE(bounds); i++)
bounds[i]++;
- return (0);
+ return 0;
}
static int madwifi_config(const char *key, const char *value) {
int id = watchitem_find(value);
if (id < 0)
- return (-1);
+ return -1;
else
watchlist_add(watch_items, id);
}
int id = watchitem_find(value);
if (id < 0)
- return (-1);
+ return -1;
else
watchlist_remove(watch_items, id);
}
int id = watchitem_find(value);
if (id < 0)
- return (-1);
+ return -1;
else
watchlist_add(misc_items, id);
}
int id = watchitem_find(value);
if (id < 0)
- return (-1);
+ return -1;
else
watchlist_remove(misc_items, id);
}
else
- return (-1);
+ return -1;
- return (0);
+ return 0;
}
static void submit(const char *dev, const char *type, const char *ti1,
sstrncpy(vl.type, type, sizeof(vl.type));
if ((ti1 != NULL) && (ti2 != NULL))
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-%s", ti1, ti2);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-%s", ti1, ti2);
else if ((ti1 != NULL) && (ti2 == NULL))
sstrncpy(vl.type_instance, ti1, sizeof(vl.type_instance));
if (vals[i] == 0)
continue;
- ssnprintf(ti2, sizeof(ti2), "%i", i);
+ snprintf(ti2, sizeof(ti2), "%i", i);
submit_derive(dev, "ath_stat", name, ti2, (derive_t)vals[i]);
}
}
static inline void macaddr_to_str(char *buf, size_t bufsize,
const uint8_t mac[IEEE80211_ADDR_LEN]) {
- ssnprintf(buf, bufsize, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1],
- mac[2], mac[3], mac[4], mac[5]);
+ snprintf(buf, bufsize, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1],
+ mac[2], mac[3], mac[4], mac[5]);
}
static void process_stat_struct(int which, const void *ptr, const char *dev,
"SIOCGATHSTATS to device %s "
"failed with status %i.",
dev, status);
- return (status);
+ return status;
}
/* These stats are handled as a special case, because they are
/* All other ath statistics */
process_stat_struct(ATH_STAT, &stats, dev, NULL, "ath_stat", "ast_misc");
- return (0);
+ return 0;
}
static int process_80211stats(int sk, const char *dev) {
"SIOCG80211STATS to device %s "
"failed with status %i.",
dev, status);
- return (status);
+ return status;
}
process_stat_struct(IFA_STAT, &stats, dev, NULL, "ath_stat", "is_misc");
- return (0);
+ return 0;
}
static int process_station(int sk, const char *dev,
"IEEE80211_IOCTL_STA_STATS to device %s "
"failed with status %i.",
dev, status);
- return (status);
+ return status;
}
/* These two stats are handled as a special case as they are
/* All other node statistics */
process_stat_struct(NOD_STAT, ns, dev, mac, "node_stat", "ns_misc");
- return (0);
+ return 0;
}
static int process_stations(int sk, const char *dev) {
"IEEE80211_IOCTL_STA_INFO to device %s "
"failed with status %i.",
dev, status);
- return (status);
+ return status;
}
len = iwr.u.data.length;
if (item_watched(STAT_ATH_NODES))
submit_gauge(dev, "ath_nodes", NULL, NULL, nodes);
- return (0);
+ return 0;
}
static int process_device(int sk, const char *dev) {
if (status == 0)
num_success++;
- return ((num_success == 0) ? -1 : 0);
+ return (num_success == 0) ? -1 : 0;
}
static int check_devname(const char *dev) {
if (dev[0] == '.')
return 0;
- ssnprintf(buf, sizeof(buf), "/sys/class/net/%s/device/driver", dev);
+ snprintf(buf, sizeof(buf), "/sys/class/net/%s/device/driver", dev);
buf[sizeof(buf) - 1] = '\0';
i = readlink(buf, buf2, sizeof(buf2) - 1);
nets = opendir("/sys/class/net/");
if (nets == NULL) {
WARNING("madwifi plugin: opening /sys/class/net failed");
- return (-1);
+ return -1;
}
num_success = 0;
closedir(nets);
if ((num_success == 0) && (num_fail != 0))
- return (-1);
- return (0);
+ return -1;
+ return 0;
}
static int procfs_iterate(int sk) {
if ((fh = fopen("/proc/net/dev", "r")) == NULL) {
WARNING("madwifi plugin: opening /proc/net/dev failed");
- return (-1);
+ return -1;
}
num_success = 0;
fclose(fh);
if ((num_success == 0) && (num_fail != 0))
- return (-1);
+ return -1;
return 0;
}
sk = socket(AF_INET, SOCK_DGRAM, 0);
if (sk < 0)
- return (-1);
+ return -1;
/* procfs iteration is not safe because it does not check whether given
interface is madwifi interface and there are private ioctls used, which
}
*user_data = NULL;
- return (0);
+ return 0;
} /* }}} int mec_create */
static int mec_destroy(__attribute__((unused)) void **user_data) /* {{{ */
{
- return (0);
+ return 0;
} /* }}} int mec_destroy */
static int mec_match(__attribute__((unused)) const data_set_t *ds, /* {{{ */
}
if ((num_counters != 0) && (num_counters == num_empty))
- return (FC_MATCH_MATCHES);
+ return FC_MATCH_MATCHES;
- return (FC_MATCH_NO_MATCH);
+ return FC_MATCH_NO_MATCH;
} /* }}} int mec_match */
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 : */
(ci->values[1].type != OCONFIG_TYPE_NUMBER)) {
ERROR("hashed match: The `Match' option requires "
"exactly two numeric arguments.");
- return (-1);
+ return -1;
}
if ((ci->values[0].value.number < 0) || (ci->values[1].value.number < 0)) {
ERROR("hashed match: The arguments of the `Match' "
"option must be positive.");
- return (-1);
+ return -1;
}
tmp = realloc(m->matches, sizeof(*tmp) * (m->matches_num + 1));
if (tmp == NULL) {
ERROR("hashed match: realloc failed.");
- return (-1);
+ return -1;
}
m->matches = tmp;
tmp = m->matches + m->matches_num;
if (tmp->match >= tmp->total) {
ERROR("hashed match: The first argument of the `Match' option "
"must be smaller than the second argument.");
- return (-1);
+ return -1;
}
assert(tmp->total != 0);
m->matches_num++;
- return (0);
+ return 0;
} /* }}} int mh_config_match */
static int mh_create(const oconfig_item_t *ci, void **user_data) /* {{{ */
m = calloc(1, sizeof(*m));
if (m == NULL) {
ERROR("mh_create: calloc failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
for (int i = 0; i < ci->children_num; i++) {
sfree(m->matches);
sfree(m);
ERROR("hashed match: No matches were configured. Not creating match.");
- return (-1);
+ return -1;
}
*user_data = m;
- return (0);
+ return 0;
} /* }}} int mh_create */
static int mh_destroy(void **user_data) /* {{{ */
mh_match_t *mh;
if ((user_data == NULL) || (*user_data == NULL))
- return (0);
+ return 0;
mh = *user_data;
sfree(mh->matches);
sfree(mh);
- return (0);
+ return 0;
} /* }}} int mh_destroy */
static int mh_match(const data_set_t __attribute__((unused)) * ds, /* {{{ */
uint32_t hash_val;
if ((user_data == NULL) || (*user_data == NULL))
- return (-1);
+ return -1;
m = *user_data;
for (size_t i = 0; i < m->matches_num; i++)
if ((hash_val % m->matches[i].total) == m->matches[i].match)
- return (FC_MATCH_MATCHES);
+ return FC_MATCH_MATCHES;
- return (FC_MATCH_NO_MATCH);
+ return FC_MATCH_NO_MATCH;
} /* }}} int mh_match */
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 : */
static int mr_match_regexen(mr_regex_t *re_head, /* {{{ */
const char *string) {
if (re_head == NULL)
- return (FC_MATCH_MATCHES);
+ return FC_MATCH_MATCHES;
for (mr_regex_t *re = re_head; re != NULL; re = re->next) {
int status;
} else {
DEBUG("regex match: Regular expression `%s' does not match `%s'.",
re->re_str, string);
- return (FC_MATCH_NO_MATCH);
+ return FC_MATCH_NO_MATCH;
}
}
- return (FC_MATCH_MATCHES);
+ return FC_MATCH_MATCHES;
} /* }}} int mr_match_regexen */
static int mr_add_regex(mr_regex_t **re_head, const char *re_str, /* {{{ */
re = calloc(1, sizeof(*re));
if (re == NULL) {
log_err("mr_add_regex: calloc failed.");
- return (-1);
+ return -1;
}
re->next = NULL;
if (re->re_str == NULL) {
sfree(re);
log_err("mr_add_regex: strdup failed.");
- return (-1);
+ return -1;
}
status = regcomp(&re->re, re->re_str, REG_EXTENDED | REG_NOSUB);
errmsg);
sfree(re->re_str);
sfree(re);
- return (-1);
+ return -1;
}
if (*re_head == NULL) {
ptr->next = re;
}
- return (0);
+ return 0;
} /* }}} int mr_add_regex */
static int mr_config_add_regex(mr_regex_t **re_head, /* {{{ */
oconfig_item_t *ci) {
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
log_warn("`%s' needs exactly one string argument.", ci->key);
- return (-1);
+ return -1;
}
return mr_add_regex(re_head, ci->values[0].value.string, ci->key);
if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) ||
(ci->values[1].type != OCONFIG_TYPE_STRING)) {
log_warn("`%s' needs exactly two string arguments.", ci->key);
- return (-1);
+ return -1;
}
if (*meta == NULL) {
*meta = llist_create();
if (*meta == NULL) {
log_err("mr_config_add_meta_regex: llist_create failed.");
- return (-1);
+ return -1;
}
}
meta_key = strdup(meta_key);
if (meta_key == NULL) {
log_err("mr_config_add_meta_regex: strdup failed.");
- return (-1);
+ return -1;
}
entry = llentry_create(meta_key, NULL);
if (entry == NULL) {
log_err("mr_config_add_meta_regex: llentry_create failed.");
sfree(meta_key);
- return (-1);
+ return -1;
}
/* meta_key and entry will now be freed by mr_free_match(). */
llist_append(*meta, entry);
}
- ssnprintf(buffer, sizeof(buffer), "%s `%s'", ci->key, meta_key);
+ snprintf(buffer, sizeof(buffer), "%s `%s'", ci->key, meta_key);
/* Can't pass &entry->value into mr_add_regex, so copy in/out. */
re_head = entry->value;
status = mr_add_regex(&re_head, ci->values[1].value.string, buffer);
m = calloc(1, sizeof(*m));
if (m == NULL) {
log_err("mr_create: calloc failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
m->invert = 0;
if (status != 0) {
mr_free_match(m);
- return (status);
+ return status;
}
*user_data = m;
- return (0);
+ return 0;
} /* }}} int mr_create */
static int mr_destroy(void **user_data) /* {{{ */
{
if ((user_data != NULL) && (*user_data != NULL))
mr_free_match(*user_data);
- return (0);
+ return 0;
} /* }}} int mr_destroy */
static int mr_match(const data_set_t __attribute__((unused)) * ds, /* {{{ */
int nomatch_value = FC_MATCH_NO_MATCH;
if ((user_data == NULL) || (*user_data == NULL))
- return (-1);
+ return -1;
m = *user_data;
}
if (mr_match_regexen(m->host, vl->host) == FC_MATCH_NO_MATCH)
- return (nomatch_value);
+ return nomatch_value;
if (mr_match_regexen(m->plugin, vl->plugin) == FC_MATCH_NO_MATCH)
- return (nomatch_value);
+ return nomatch_value;
if (mr_match_regexen(m->plugin_instance, vl->plugin_instance) ==
FC_MATCH_NO_MATCH)
- return (nomatch_value);
+ return nomatch_value;
if (mr_match_regexen(m->type, vl->type) == FC_MATCH_NO_MATCH)
- return (nomatch_value);
+ return nomatch_value;
if (mr_match_regexen(m->type_instance, vl->type_instance) ==
FC_MATCH_NO_MATCH)
- return (nomatch_value);
+ return nomatch_value;
if (vl->meta != NULL) {
for (llentry_t *e = llist_head(m->meta); e != NULL; e = e->next) {
mr_regex_t *meta_re = (mr_regex_t *)e->value;
char *value;
int status = meta_data_get_string(vl->meta, e->key, &value);
if (status == (-ENOENT)) /* key is not present */
- return (nomatch_value);
+ return nomatch_value;
if (status != 0) /* some other problem */
continue; /* error will have already been printed. */
if (mr_match_regexen(meta_re, value) == FC_MATCH_NO_MATCH) {
sfree(value);
- return (nomatch_value);
+ return nomatch_value;
}
sfree(value);
}
}
- return (match_value);
+ return match_value;
} /* }}} int mr_match */
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 : */
m = calloc(1, sizeof(*m));
if (m == NULL) {
ERROR("mt_create: calloc failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
m->future = 0;
if (status != 0) {
free(m);
- return (status);
+ return status;
}
*user_data = m;
- return (0);
+ return 0;
} /* }}} int mt_create */
static int mt_destroy(void **user_data) /* {{{ */
sfree(*user_data);
}
- return (0);
+ return 0;
} /* }}} int mt_destroy */
static int mt_match(const data_set_t __attribute__((unused)) * ds, /* {{{ */
cdtime_t now;
if ((user_data == NULL) || (*user_data == NULL))
- return (-1);
+ return -1;
m = *user_data;
now = cdtime();
if (m->future != 0) {
if (vl->time >= (now + m->future))
- return (FC_MATCH_MATCHES);
+ return FC_MATCH_MATCHES;
}
if (m->past != 0) {
if (vl->time <= (now - m->past))
- return (FC_MATCH_MATCHES);
+ return FC_MATCH_MATCHES;
}
- return (FC_MATCH_NO_MATCH);
+ return FC_MATCH_NO_MATCH;
} /* }}} int mt_match */
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 : */
oconfig_item_t *ci) {
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
ERROR("`value' match: `%s' needs exactly one string argument.", ci->key);
- return (-1);
+ return -1;
}
if (strcasecmp("All", ci->values[0].value.string) == 0)
ERROR("`value' match: Passing `%s' to the `%s' option is invalid. "
"The argument must either be `All' or `Any'.",
ci->values[0].value.string, ci->key);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int mv_config_add_satisfy */
static int mv_config_add_data_source(mv_match_t *m, /* {{{ */
/* Check number of arbuments. */
if (ci->values_num < 1) {
ERROR("`value' match: `%s' needs at least one argument.", ci->key);
- return (-1);
+ return -1;
}
/* Check type of arguments */
ci->key, i + 1,
(ci->values[i].type == OCONFIG_TYPE_BOOLEAN) ? "truth value"
: "number");
- return (-1);
+ return -1;
}
/* Allocate space for the char pointers */
temp = realloc(m->data_sources, new_data_sources_num * sizeof(char *));
if (temp == NULL) {
ERROR("`value' match: realloc failed.");
- return (-1);
+ return -1;
}
m->data_sources = temp;
m->data_sources_num++;
}
- return (0);
+ return 0;
} /* }}} int mv_config_add_data_source */
static int mv_config_add_gauge(gauge_t *ret_value, /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) {
ERROR("`value' match: `%s' needs exactly one numeric argument.", ci->key);
- return (-1);
+ return -1;
}
*ret_value = ci->values[0].value.number;
- return (0);
+ return 0;
} /* }}} int mv_config_add_gauge */
static int mv_config_add_boolean(int *ret_value, /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) {
ERROR("`value' match: `%s' needs exactly one boolean argument.", ci->key);
- return (-1);
+ return -1;
}
if (ci->values[0].value.boolean)
else
*ret_value = 0;
- return (0);
+ return 0;
} /* }}} int mv_config_add_boolean */
static int mv_create(const oconfig_item_t *ci, void **user_data) /* {{{ */
m = calloc(1, sizeof(*m));
if (m == NULL) {
ERROR("mv_create: calloc failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
m->min = NAN;
if (status != 0) {
mv_free_match(m);
- return (status);
+ return status;
}
*user_data = m;
- return (0);
+ return 0;
} /* }}} int mv_create */
static int mv_destroy(void **user_data) /* {{{ */
{
if ((user_data != NULL) && (*user_data != NULL))
mv_free_match(*user_data);
- return (0);
+ return 0;
} /* }}} int mv_destroy */
static int mv_match(const data_set_t *ds, const value_list_t *vl, /* {{{ */
int status;
if ((user_data == NULL) || (*user_data == NULL))
- return (-1);
+ return -1;
m = *user_data;
if (values == NULL) {
ERROR("`value' match: Retrieving the current rate from the cache "
"failed.");
- return (-1);
+ return -1;
}
status = FC_MATCH_NO_MATCH;
} /* for (i = 0; i < ds->ds_num; i++) */
free(values);
- return (status);
+ return status;
} /* }}} int mv_match */
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 : */
ERROR("mbmon: getaddrinfo (%s, %s): %s", host, port,
(ai_return == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
: gai_strerror(ai_return));
- return (-1);
+ return -1;
}
fd = -1;
if (fd < 0) {
ERROR("mbmon: Could not connect to daemon.");
- return (-1);
+ return -1;
}
/* receive data from the mbmon daemon */
ERROR("mbmon: Error reading from socket: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
close(fd);
- return (-1);
+ return -1;
}
buffer_fill += status;
"Buffer: `%s'",
buffer);
close(fd);
- return (-1);
+ return -1;
}
close(fd);
- return (0);
+ return 0;
}
static int mbmon_config(const char *key, const char *value) {
free(mbmon_port);
mbmon_port = strdup(value);
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static void mbmon_submit(const char *type, const char *type_instance,
/* get data from daemon */
if (mbmon_query_daemon(buf, sizeof(buf)) < 0)
- return (-1);
+ return -1;
s = buf;
while ((t = strchr(s, ':')) != NULL) {
s = nextc + 1;
}
- return (0);
+ return 0;
} /* void mbmon_read */
/* module_register
--- /dev/null
+/*-
+ * collectd - src/mcelog.c
+ * MIT License
+ *
+ * Copyright(c) 2016-2017 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+
+ * Authors:
+ * Maryam Tahhan <maryam.tahhan@intel.com>
+ * Volodymyr Mytnyk <volodymyrx.mytnyk@intel.com>
+ * Taras Chornyi <tarasx.chornyi@intel.com>
+ * Krzysztof Matczak <krzysztofx.matczak@intel.com>
+ */
+
+#include "collectd.h"
+
+#include "common.h"
+#include "utils_llist.h"
+
+#include <poll.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#define MCELOG_PLUGIN "mcelog"
+#define MCELOG_BUFF_SIZE 1024
+#define MCELOG_POLL_TIMEOUT 1000 /* ms */
+#define MCELOG_SOCKET_STR "SOCKET"
+#define MCELOG_DIMM_NAME "DMI_NAME"
+#define MCELOG_CORRECTED_ERR "corrected memory errors"
+#define MCELOG_UNCORRECTED_ERR "uncorrected memory errors"
+#define MCELOG_CORRECTED_ERR_TIMED "corrected memory timed errors"
+#define MCELOG_UNCORRECTED_ERR_TIMED "uncorrected memory timed errors"
+#define MCELOG_CORRECTED_ERR_TYPE_INS "corrected_memory_errors"
+#define MCELOG_UNCORRECTED_ERR_TYPE_INS "uncorrected_memory_errors"
+
+typedef struct mcelog_config_s {
+ char logfile[PATH_MAX]; /* mcelog logfile */
+ pthread_t tid; /* poll thread id */
+ llist_t *dimms_list; /* DIMMs list */
+ pthread_mutex_t dimms_lock; /* lock for dimms cache */
+ _Bool persist;
+} 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 / 2];
+ int uncorrected_err_total; /* x total*/
+ int uncorrected_err_timed; /* x in 24h*/
+ char uncorrected_err_timed_period[DATA_MAX_NAME_LEN / 2];
+ char location[DATA_MAX_NAME_LEN / 2]; /* SOCKET x CHANNEL x DIMM x*/
+ char dimm_name[DATA_MAX_NAME_LEN / 2]; /* 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", .persist = 0,
+};
+
+static socket_adapter_t socket_adapter = {
+ .sock_fd = -1,
+ .unix_sock =
+ {
+ .sun_family = AF_UNIX, .sun_path = "/var/run/mcelog-client",
+ },
+ .lock = PTHREAD_RWLOCK_INITIALIZER,
+ .close = socket_close,
+ .write = socket_write,
+ .reinit = socket_reinit,
+ .receive = socket_receive,
+};
+
+static _Bool mcelog_thread_running;
+static _Bool mcelog_apply_defaults;
+
+static void mcelog_free_dimms_list_records(llist_t *dimms_list) {
+
+ for (llentry_t *e = llist_head(dimms_list); e != NULL; e = e->next) {
+ sfree(e->key);
+ sfree(e->value);
+ }
+}
+
+/* Create or get dimm by dimm name/location */
+static llentry_t *mcelog_dimm(const mcelog_memory_rec_t *rec,
+ llist_t *dimms_list) {
+
+ char dimm_name[DATA_MAX_NAME_LEN];
+
+ if (strlen(rec->dimm_name) > 0) {
+ snprintf(dimm_name, sizeof(dimm_name), "%s_%s", rec->location,
+ rec->dimm_name);
+ } else
+ sstrncpy(dimm_name, rec->location, sizeof(dimm_name));
+
+ llentry_t *dimm_le = llist_search(g_mcelog_config.dimms_list, dimm_name);
+
+ if (dimm_le != NULL)
+ return dimm_le;
+
+ /* allocate new linked list entry */
+ mcelog_memory_rec_t *dimm_mr = calloc(1, sizeof(*dimm_mr));
+ if (dimm_mr == NULL) {
+ ERROR(MCELOG_PLUGIN ": Error allocating dimm memory item");
+ return NULL;
+ }
+ char *p_name = strdup(dimm_name);
+ if (p_name == NULL) {
+ ERROR(MCELOG_PLUGIN ": strdup: error");
+ free(dimm_mr);
+ return NULL;
+ }
+
+ /* add new dimm */
+ dimm_le = llentry_create(p_name, dimm_mr);
+ if (dimm_le == NULL) {
+ ERROR(MCELOG_PLUGIN ": llentry_create(): error");
+ free(dimm_mr);
+ free(p_name);
+ return NULL;
+ }
+ pthread_mutex_lock(&g_mcelog_config.dimms_lock);
+ llist_append(g_mcelog_config.dimms_list, dimm_le);
+ pthread_mutex_unlock(&g_mcelog_config.dimms_lock);
+
+ return dimm_le;
+}
+
+static void mcelog_update_dimm_stats(llentry_t *dimm,
+ const mcelog_memory_rec_t *rec) {
+ pthread_mutex_lock(&g_mcelog_config.dimms_lock);
+ memcpy(dimm->value, rec, sizeof(mcelog_memory_rec_t));
+ pthread_mutex_unlock(&g_mcelog_config.dimms_lock);
+}
+
+static int mcelog_config(oconfig_item_t *ci) {
+ int use_logfile = 0, use_memory = 0;
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *child = ci->children + i;
+ if (strcasecmp("McelogLogfile", child->key) == 0) {
+ use_logfile = 1;
+ if (use_memory) {
+ ERROR(MCELOG_PLUGIN ": Invalid configuration option: \"%s\", Memory "
+ "option is already configured.",
+ child->key);
+ return -1;
+ }
+ 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;
+ }
+ memset(socket_adapter.unix_sock.sun_path, 0,
+ sizeof(socket_adapter.unix_sock.sun_path));
+ } else if (strcasecmp("Memory", child->key) == 0) {
+ if (use_logfile) {
+ ERROR(MCELOG_PLUGIN ": Invalid configuration option: \"%s\", Logfile "
+ "option is already configured.",
+ child->key);
+ return -1;
+ }
+ use_memory = 1;
+ for (int j = 0; j < child->children_num; j++) {
+ oconfig_item_t *mem_child = child->children + j;
+ if (strcasecmp("McelogClientSocket", mem_child->key) == 0) {
+ if (cf_util_get_string_buffer(
+ mem_child, socket_adapter.unix_sock.sun_path,
+ sizeof(socket_adapter.unix_sock.sun_path)) < 0) {
+ ERROR(MCELOG_PLUGIN ": Invalid configuration option: \"%s\".",
+ mem_child->key);
+ return -1;
+ }
+ } else if (strcasecmp("PersistentNotification", mem_child->key) == 0) {
+ if (cf_util_get_boolean(mem_child, &g_mcelog_config.persist) < 0) {
+ ERROR(MCELOG_PLUGIN ": Invalid configuration option: \"%s\".",
+ mem_child->key);
+ return -1;
+ }
+ } else {
+ ERROR(MCELOG_PLUGIN ": Invalid Memory configuration option: \"%s\".",
+ mem_child->key);
+ return -1;
+ }
+ }
+ memset(g_mcelog_config.logfile, 0, sizeof(g_mcelog_config.logfile));
+ } else {
+ ERROR(MCELOG_PLUGIN ": Invalid configuration option: \"%s\".",
+ child->key);
+ return -1;
+ }
+ }
+
+ if (!use_logfile && !use_memory)
+ mcelog_apply_defaults = 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_dispatch_mem_notifications(const mcelog_memory_rec_t *mr) {
+ notification_t n = {.severity = NOTIF_WARNING,
+ .time = cdtime(),
+ .plugin = MCELOG_PLUGIN,
+ .type = "errors"};
+
+ int dispatch_corrected_notifs = 0, dispatch_uncorrected_notifs = 0;
+
+ if (mr == NULL)
+ return -1;
+
+ llentry_t *dimm = mcelog_dimm(mr, g_mcelog_config.dimms_list);
+ if (dimm == NULL) {
+ ERROR(MCELOG_PLUGIN
+ ": Error adding/getting dimm memory item to/from cache");
+ return -1;
+ }
+ mcelog_memory_rec_t *mr_old = dimm->value;
+ if (!g_mcelog_config.persist) {
+
+ if (mr_old->corrected_err_total != mr->corrected_err_total ||
+ mr_old->corrected_err_timed != mr->corrected_err_timed)
+ dispatch_corrected_notifs = 1;
+
+ if (mr_old->uncorrected_err_total != mr->uncorrected_err_total ||
+ mr_old->uncorrected_err_timed != mr->uncorrected_err_timed)
+ dispatch_uncorrected_notifs = 1;
+
+ if (!dispatch_corrected_notifs && !dispatch_uncorrected_notifs) {
+ DEBUG("%s: No new notifications to dispatch", MCELOG_PLUGIN);
+ return 0;
+ }
+ } else {
+ dispatch_corrected_notifs = 1;
+ dispatch_uncorrected_notifs = 1;
+ }
+
+ sstrncpy(n.host, hostname_g, sizeof(n.host));
+
+ if (mr->dimm_name[0] != '\0')
+ snprintf(n.plugin_instance, sizeof(n.plugin_instance), "%s_%s",
+ mr->location, mr->dimm_name);
+ else
+ sstrncpy(n.plugin_instance, mr->location, sizeof(n.plugin_instance));
+
+ if (dispatch_corrected_notifs &&
+ (mr->corrected_err_total > 0 || mr->corrected_err_timed > 0)) {
+ /* Corrected Error Notifications */
+ plugin_notification_meta_add_signed_int(&n, MCELOG_CORRECTED_ERR,
+ mr->corrected_err_total);
+ plugin_notification_meta_add_signed_int(&n, MCELOG_CORRECTED_ERR_TIMED,
+ mr->corrected_err_timed);
+ snprintf(n.message, sizeof(n.message), MCELOG_CORRECTED_ERR);
+ sstrncpy(n.type_instance, MCELOG_CORRECTED_ERR_TYPE_INS,
+ sizeof(n.type_instance));
+ plugin_dispatch_notification(&n);
+ if (n.meta)
+ plugin_notification_meta_free(n.meta);
+ n.meta = NULL;
+ }
+
+ if (dispatch_uncorrected_notifs &&
+ (mr->uncorrected_err_total > 0 || mr->uncorrected_err_timed > 0)) {
+ /* Uncorrected Error Notifications */
+ plugin_notification_meta_add_signed_int(&n, MCELOG_UNCORRECTED_ERR,
+ mr->uncorrected_err_total);
+ plugin_notification_meta_add_signed_int(&n, MCELOG_UNCORRECTED_ERR_TIMED,
+ mr->uncorrected_err_timed);
+ snprintf(n.message, sizeof(n.message), MCELOG_UNCORRECTED_ERR);
+ sstrncpy(n.type_instance, MCELOG_UNCORRECTED_ERR_TYPE_INS,
+ sizeof(n.type_instance));
+ n.severity = NOTIF_FAILURE;
+ plugin_dispatch_notification(&n);
+ if (n.meta)
+ plugin_notification_meta_free(n.meta);
+ n.meta = NULL;
+ }
+
+ return 0;
+}
+
+static int mcelog_submit(const mcelog_memory_rec_t *mr) {
+
+ if (!mr) {
+ ERROR(MCELOG_PLUGIN ": %s: NULL pointer", __FUNCTION__);
+ return -1;
+ }
+
+ llentry_t *dimm = mcelog_dimm(mr, g_mcelog_config.dimms_list);
+ if (dimm == NULL) {
+ ERROR(MCELOG_PLUGIN
+ ": Error adding/getting dimm memory item to/from cache");
+ 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 = MCELOG_CORRECTED_ERR_TYPE_INS};
+
+ mcelog_update_dimm_stats(dimm, mr);
+
+ if (mr->dimm_name[0] != '\0')
+ snprintf(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);
+
+ snprintf(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, MCELOG_UNCORRECTED_ERR_TYPE_INS,
+ sizeof(vl.type_instance));
+ vl.values = &(value_t){.derive = (derive_t)mr->uncorrected_err_total};
+ plugin_dispatch_values(&vl);
+
+ snprintf(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;
+ }
+
+ if (mcelog_dispatch_mem_notifications(&memory_record) != 0)
+ ERROR(MCELOG_PLUGIN ": Failed to submit memory errors notification");
+ 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 (mcelog_apply_defaults) {
+ INFO(MCELOG_PLUGIN
+ ": No configuration selected defaulting to memory errors.");
+ memset(g_mcelog_config.logfile, 0, sizeof(g_mcelog_config.logfile));
+ }
+ g_mcelog_config.dimms_list = llist_create();
+ int err = pthread_mutex_init(&g_mcelog_config.dimms_lock, NULL);
+ if (err < 0) {
+ ERROR(MCELOG_PLUGIN ": plugin: failed to initialize cache lock");
+ return -1;
+ }
+
+ if (socket_adapter.reinit(&socket_adapter) != 0) {
+ ERROR(MCELOG_PLUGIN ": Cannot connect to client socket");
+ return -1;
+ }
+
+ if (strlen(socket_adapter.unix_sock.sun_path)) {
+ 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;
+ }
+ }
+ pthread_mutex_lock(&g_mcelog_config.dimms_lock);
+ mcelog_free_dimms_list_records(g_mcelog_config.dimms_list);
+ llist_destroy(g_mcelog_config.dimms_list);
+ g_mcelog_config.dimms_list = NULL;
+ pthread_mutex_unlock(&g_mcelog_config.dimms_lock);
+ pthread_mutex_destroy(&g_mcelog_config.dimms_lock);
+ 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);
+}
if (ignorelist == NULL)
ignorelist = ignorelist_create(/* invert = */ 1);
if (ignorelist == NULL)
- return (1);
+ return 1;
if (strcasecmp(key, "Device") == 0) {
ignorelist_add(ignorelist, value);
} else if (strcasecmp(key, "IgnoreSelected") == 0) {
ignorelist_set_invert(ignorelist, IS_TRUE(value) ? 0 : 1);
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static void md_submit(const int minor, const char *type_instance,
vl.values = &(value_t){.gauge = value};
vl.values_len = 1;
sstrncpy(vl.plugin, "md", sizeof(vl.plugin));
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", minor);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", minor);
sstrncpy(vl.type, "md_disks", sizeof(vl.type));
sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
char errbuf[1024];
WARNING("md: Unable to open %s: %s", PROC_DISKSTATS,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
/* Iterate md devices */
* major/minor, but that again can be tricky if the filesystem
* with the device file is mounted using the "nodev" option.
*/
- ssnprintf(path, sizeof(path), "%s/%s", DEV_DIR, name);
+ snprintf(path, sizeof(path), "%s/%s", DEV_DIR, name);
md_process(minor, path);
}
fclose(fh);
- return (0);
+ return 0;
} /* int md_read */
void module_register(void) {
typedef struct web_page_s web_page_t;
struct web_page_s /* {{{ */
{
+ char *plugin_name;
char *instance;
char *server;
memcached_free(wp->memc);
wp->memc = NULL;
+ sfree(wp->plugin_name);
sfree(wp->instance);
sfree(wp->server);
sfree(wp->key);
wp->memc = memcached_create(NULL);
if (wp->memc == NULL) {
ERROR("memcachec plugin: memcached_create failed.");
- return (-1);
+ return -1;
}
server = memcached_servers_parse(wp->server);
memcached_server_push(wp->memc, server);
memcached_server_list_free(server);
- return (0);
+ return 0;
} /* }}} int cmc_page_init_memc */
static int cmc_config_add_string(const char *name, char **dest, /* {{{ */
oconfig_item_t *ci) {
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("memcachec plugin: `%s' needs exactly one string argument.", name);
- return (-1);
+ return -1;
}
sfree(*dest);
*dest = strdup(ci->values[0].value.string);
if (*dest == NULL)
- return (-1);
+ return -1;
- return (0);
+ return 0;
} /* }}} int cmc_config_add_string */
static int cmc_config_add_match_dstype(int *dstype_ret, /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("memcachec plugin: `DSType' needs exactly one string argument.");
- return (-1);
+ return -1;
}
if (strncasecmp("Gauge", ci->values[0].value.string, strlen("Gauge")) == 0) {
if (dstype == 0) {
WARNING("memcachec plugin: `%s' is not a valid argument to `DSType'.",
ci->values[0].value.string);
- return (-1);
+ return -1;
}
*dstype_ret = dstype;
- return (0);
+ return 0;
} /* }}} int cmc_config_add_match_dstype */
static int cmc_config_add_match(web_page_t *page, /* {{{ */
match = calloc(1, sizeof(*match));
if (match == NULL) {
ERROR("memcachec plugin: calloc failed.");
- return (-1);
+ return -1;
}
status = 0;
if (status != 0) {
cmc_web_match_free(match);
- return (status);
+ return status;
}
match->match =
if (match->match == NULL) {
ERROR("memcachec plugin: match_create_simple failed.");
cmc_web_match_free(match);
- return (-1);
+ return -1;
} else {
web_match_t *prev;
prev->next = match;
}
- return (0);
+ return 0;
} /* }}} int cmc_config_add_match */
static int cmc_config_add_page(oconfig_item_t *ci) /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING(
"memcachec plugin: `Page' blocks need exactly one string argument.");
- return (-1);
+ return -1;
}
page = calloc(1, sizeof(*page));
if (page == NULL) {
ERROR("memcachec plugin: calloc failed.");
- return (-1);
+ return -1;
}
page->server = NULL;
page->key = NULL;
if (page->instance == NULL) {
ERROR("memcachec plugin: strdup failed.");
sfree(page);
- return (-1);
+ return -1;
}
/* Process all children */
status = cmc_config_add_string("Server", &page->server, child);
else if (strcasecmp("Key", child->key) == 0)
status = cmc_config_add_string("Key", &page->key, child);
+ else if (strcasecmp("Plugin", child->key) == 0)
+ status = cmc_config_add_string("Plugin", &page->plugin_name, child);
else if (strcasecmp("Match", child->key) == 0)
/* Be liberal with failing matches => don't set `status'. */
cmc_config_add_match(page, child);
if (status != 0) {
cmc_web_page_free(page);
- return (status);
+ return status;
}
/* Add the new page to the linked list */
prev->next = page;
}
- return (0);
+ return 0;
} /* }}} int cmc_config_add_page */
static int cmc_config(oconfig_item_t *ci) /* {{{ */
if ((success == 0) && (errors > 0)) {
ERROR("memcachec plugin: All statements failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cmc_config */
static int cmc_init(void) /* {{{ */
{
if (pages_g == NULL) {
INFO("memcachec plugin: No pages have been defined.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cmc_init */
static void cmc_submit(const web_page_t *wp, const web_match_t *wm, /* {{{ */
vl.values = &value;
vl.values_len = 1;
- sstrncpy(vl.plugin, "memcachec", sizeof(vl.plugin));
+ sstrncpy(vl.plugin, (wp->plugin_name != NULL) ? wp->plugin_name : "memcachec",
+ sizeof (vl.plugin));
sstrncpy(vl.plugin_instance, wp->instance, sizeof(vl.plugin_instance));
sstrncpy(vl.type, wm->type, sizeof(vl.type));
sstrncpy(vl.type_instance, wm->instance, sizeof(vl.type_instance));
int status;
if (wp->memc == NULL)
- return (-1);
+ return -1;
wp->buffer = memcached_get(wp->memc, wp->key, strlen(wp->key), &string_length,
&flags, &rc);
if (rc != MEMCACHED_SUCCESS) {
ERROR("memcachec plugin: memcached_get failed: %s",
memcached_strerror(wp->memc, rc));
- return (-1);
+ return -1;
}
for (web_match_t *wm = wp->matches; wm != NULL; wm = wm->next) {
sfree(wp->buffer);
- return (0);
+ return 0;
} /* }}} int cmc_read_page */
static int cmc_read(void) /* {{{ */
for (web_page_t *wp = pages_g; wp != NULL; wp = wp->next)
cmc_read_page(wp);
- return (0);
+ return 0;
} /* }}} int cmc_read */
static int cmc_shutdown(void) /* {{{ */
cmc_web_page_free(pages_g);
pages_g = NULL;
- return (0);
+ return 0;
} /* }}} int cmc_shutdown */
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 : */
* Copyright (C) 2009 Doug MacEachern
* Copyright (C) 2009 Franck Lombardi
* Copyright (C) 2012 Nicolas Szalay
+ * Copyright (C) 2017 Pavel Rochnyak
*
* 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
* Doug MacEachern <dougm at hyperic.com>
* Franck Lombardi
* Nicolas Szalay
+ * Pavel Rochnyak <pavel2000 ngs.ru>
**/
#include "collectd.h"
#include <netinet/tcp.h>
#include <sys/un.h>
+#include <poll.h>
+
#define MEMCACHED_DEF_HOST "127.0.0.1"
#define MEMCACHED_DEF_PORT "11211"
+#define MEMCACHED_CONNECT_TIMEOUT 10000
+#define MEMCACHED_IO_TIMEOUT 5000
+
+struct prev_s {
+ derive_t hits;
+ derive_t gets;
+ derive_t incr_hits;
+ derive_t incr_misses;
+ derive_t decr_hits;
+ derive_t decr_misses;
+};
+
+typedef struct prev_s prev_t;
struct memcached_s {
char *name;
char *socket;
char *connhost;
char *connport;
+ int fd;
+ prev_t prev;
};
typedef struct memcached_s memcached_t;
if (st == NULL)
return;
+ if (st->fd >= 0) {
+ shutdown(st->fd, SHUT_RDWR);
+ close(st->fd);
+ st->fd = -1;
+ }
+
sfree(st->name);
sfree(st->host);
sfree(st->socket);
static int memcached_connect_unix(memcached_t *st) {
struct sockaddr_un serv_addr = {0};
- int fd;
serv_addr.sun_family = AF_UNIX;
sstrncpy(serv_addr.sun_path, st->socket, sizeof(serv_addr.sun_path));
/* create our socket descriptor */
- fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
char errbuf[1024];
ERROR("memcached plugin: memcached_connect_unix: socket(2) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
/* connect to the memcached daemon */
if (status != 0) {
shutdown(fd, SHUT_RDWR);
close(fd);
- fd = -1;
+ return -1;
+ }
+
+ /* switch to non-blocking mode */
+ int flags = fcntl(fd, F_GETFL);
+ status = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+ if (status != 0) {
+ close(fd);
+ return -1;
}
- return (fd);
+ return fd;
} /* int memcached_connect_unix */
static int memcached_connect_inet(memcached_t *st) {
struct addrinfo *ai_list;
- int status;
int fd = -1;
struct addrinfo ai_hints = {.ai_family = AF_UNSPEC,
.ai_flags = AI_ADDRCONFIG,
.ai_socktype = SOCK_STREAM};
- status = getaddrinfo(st->connhost, st->connport, &ai_hints, &ai_list);
+ int status = getaddrinfo(st->connhost, st->connport, &ai_hints, &ai_list);
if (status != 0) {
char errbuf[1024];
ERROR("memcached plugin: memcached_connect_inet: "
st->connhost, st->connport,
(status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
: gai_strerror(status));
- return (-1);
+ return -1;
}
for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
continue;
}
+ /* switch socket to non-blocking mode */
+ int flags = fcntl(fd, F_GETFL);
+ status = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+ if (status != 0) {
+ close(fd);
+ fd = -1;
+ continue;
+ }
+
/* connect to the memcached daemon */
status = (int)connect(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
- if (status != 0) {
+ if (status != 0 && errno != EINPROGRESS) {
shutdown(fd, SHUT_RDWR);
close(fd);
fd = -1;
continue;
}
- /* A socket could be opened and connecting succeeded. We're done. */
+ /* Wait until connection establishes */
+ struct pollfd pollfd = {
+ .fd = fd, .events = POLLOUT,
+ };
+ do
+ status = poll(&pollfd, 1, MEMCACHED_CONNECT_TIMEOUT);
+ while (status < 0 && errno == EINTR);
+ if (status <= 0) {
+ close(fd);
+ fd = -1;
+ continue;
+ }
+
+ /* Check if all is good */
+ int socket_error;
+ status = getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&socket_error,
+ &(socklen_t){sizeof(socket_error)});
+ if (status != 0 || socket_error != 0) {
+ close(fd);
+ fd = -1;
+ continue;
+ }
+ /* A socket is opened and connection succeeded. We're done. */
break;
}
freeaddrinfo(ai_list);
- return (fd);
+ return fd;
} /* int memcached_connect_inet */
-static int memcached_connect(memcached_t *st) {
+static void memcached_connect(memcached_t *st) {
+ if (st->fd >= 0)
+ return;
+
if (st->socket != NULL)
- return (memcached_connect_unix(st));
+ st->fd = memcached_connect_unix(st);
else
- return (memcached_connect_inet(st));
+ st->fd = memcached_connect_inet(st);
+
+ if (st->fd >= 0)
+ INFO("memcached plugin: Instance \"%s\": connection established.",
+ st->name);
}
static int memcached_query_daemon(char *buffer, size_t buffer_size,
memcached_t *st) {
- int fd, status;
+ int status;
size_t buffer_fill;
- fd = memcached_connect(st);
- if (fd < 0) {
+ memcached_connect(st);
+ if (st->fd < 0) {
ERROR("memcached plugin: Instance \"%s\" could not connect to daemon.",
st->name);
return -1;
}
- status = (int)swrite(fd, "stats\r\n", strlen("stats\r\n"));
+ struct pollfd pollfd = {
+ .fd = st->fd, .events = POLLOUT,
+ };
+
+ do
+ status = poll(&pollfd, 1, MEMCACHED_IO_TIMEOUT);
+ while (status < 0 && errno == EINTR);
+
+ if (status <= 0) {
+ ERROR("memcached plugin: poll() failed for write() call.");
+ close(st->fd);
+ st->fd = -1;
+ return -1;
+ }
+
+ status = (int)swrite(st->fd, "stats\r\n", strlen("stats\r\n"));
if (status != 0) {
char errbuf[1024];
- ERROR("memcached plugin: write(2) failed: %s",
+ ERROR("memcached plugin: Instance \"%s\": write(2) failed: %s", st->name,
sstrerror(errno, errbuf, sizeof(errbuf)));
- shutdown(fd, SHUT_RDWR);
- close(fd);
- return (-1);
+ shutdown(st->fd, SHUT_RDWR);
+ close(st->fd);
+ st->fd = -1;
+ return -1;
}
/* receive data from the memcached daemon */
memset(buffer, 0, buffer_size);
buffer_fill = 0;
- while ((status = (int)recv(fd, buffer + buffer_fill,
- buffer_size - buffer_fill, /* flags = */ 0)) !=
- 0) {
+ pollfd.events = POLLIN;
+ while (1) {
+ do
+ status = poll(&pollfd, 1, MEMCACHED_IO_TIMEOUT);
+ while (status < 0 && errno == EINTR);
+
+ if (status <= 0) {
+ ERROR("memcached plugin: Instance \"%s\": Timeout reading from socket",
+ st->name);
+ close(st->fd);
+ st->fd = -1;
+ return -1;
+ }
+
+ do
+ status = (int)recv(st->fd, buffer + buffer_fill,
+ buffer_size - buffer_fill, /* flags = */ 0);
+ while (status < 0 && errno == EINTR);
+
char const end_token[5] = {'E', 'N', 'D', '\r', '\n'};
if (status < 0) {
char errbuf[1024];
- if ((errno == EAGAIN) || (errno == EINTR))
+ if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
continue;
- ERROR("memcached: Error reading from socket: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
- shutdown(fd, SHUT_RDWR);
- close(fd);
- return (-1);
+ ERROR("memcached plugin: Instance \"%s\": Error reading from socket: %s",
+ st->name, sstrerror(errno, errbuf, sizeof(errbuf)));
+ shutdown(st->fd, SHUT_RDWR);
+ close(st->fd);
+ st->fd = -1;
+ return -1;
}
buffer_fill += (size_t)status;
if (buffer_fill > buffer_size) {
buffer_fill = buffer_size;
- WARNING("memcached plugin: Message was truncated.");
+ WARNING("memcached plugin: Instance \"%s\": Message was truncated.",
+ st->name);
+ shutdown(st->fd, SHUT_RDWR);
+ close(st->fd);
+ st->fd = -1;
break;
}
status = 0;
if (buffer_fill == 0) {
- WARNING("memcached plugin: No data returned by memcached.");
+ WARNING("memcached plugin: Instance \"%s\": No data returned by memcached.",
+ st->name);
status = -1;
}
- shutdown(fd, SHUT_RDWR);
- close(fd);
- return (status);
+ return status;
} /* int memcached_query_daemon */
static void memcached_init_vl(value_list_t *vl, memcached_t const *st) {
plugin_dispatch_values(&vl);
}
+static gauge_t calculate_ratio_percent(derive_t part, derive_t total,
+ derive_t *prev_part,
+ derive_t *prev_total) {
+ if ((*prev_part == 0) || (*prev_total == 0) || (part < *prev_part) ||
+ (total < *prev_total)) {
+ *prev_part = part;
+ *prev_total = total;
+ return NAN;
+ }
+
+ derive_t num = part - *prev_part;
+ derive_t denom = total - *prev_total;
+
+ *prev_part = part;
+ *prev_total = total;
+
+ if (denom == 0)
+ return NAN;
+
+ if (num == 0)
+ return 0;
+
+ return 100.0 * (gauge_t)num / (gauge_t)denom;
+}
+
+static gauge_t calculate_ratio_percent2(derive_t part1, derive_t part2,
+ derive_t *prev1, derive_t *prev2) {
+ if ((*prev1 == 0) || (*prev2 == 0) || (part1 < *prev1) || (part2 < *prev2)) {
+ *prev1 = part1;
+ *prev2 = part2;
+ return NAN;
+ }
+
+ derive_t num = part1 - *prev1;
+ derive_t denom = part2 - *prev2 + num;
+
+ *prev1 = part1;
+ *prev2 = part2;
+
+ if (denom == 0)
+ return NAN;
+
+ if (num == 0)
+ return 0;
+
+ return 100.0 * (gauge_t)num / (gauge_t)denom;
+}
+
static int memcached_read(user_data_t *user_data) {
char buf[4096];
char *fields[3];
- char *ptr;
char *line;
- char *saveptr;
- int fields_num;
-
- gauge_t bytes_used = NAN;
- gauge_t bytes_total = NAN;
- gauge_t hits = NAN;
- gauge_t gets = NAN;
- gauge_t incr_hits = NAN;
- derive_t incr = 0;
- gauge_t decr_hits = NAN;
- derive_t decr = 0;
+
+ derive_t bytes_used = 0;
+ derive_t bytes_total = 0;
+ derive_t get_hits = 0;
+ derive_t cmd_get = 0;
+ derive_t incr_hits = 0;
+ derive_t incr_misses = 0;
+ derive_t decr_hits = 0;
+ derive_t decr_misses = 0;
derive_t rusage_user = 0;
derive_t rusage_syst = 0;
derive_t octets_rx = 0;
derive_t octets_tx = 0;
- memcached_t *st;
- st = user_data->data;
+ memcached_t *st = user_data->data;
+ prev_t *prev = &st->prev;
/* get data from daemon */
if (memcached_query_daemon(buf, sizeof(buf), st) < 0) {
#define FIELD_IS(cnst) \
(((sizeof(cnst) - 1) == name_len) && (strcmp(cnst, fields[1]) == 0))
- ptr = buf;
- saveptr = NULL;
+ char *ptr = buf;
+ char *saveptr = NULL;
while ((line = strtok_r(ptr, "\n\r", &saveptr)) != NULL) {
- int name_len;
-
ptr = NULL;
- fields_num = strsplit(line, fields, 3);
- if (fields_num != 3)
+ if (strsplit(line, fields, 3) != 3)
continue;
- name_len = strlen(fields[1]);
+ int name_len = strlen(fields[1]);
if (name_len == 0)
continue;
* Number of bytes used and available (total - used)
*/
else if (FIELD_IS("bytes")) {
- bytes_used = atof(fields[2]);
+ bytes_used = atoll(fields[2]);
} else if (FIELD_IS("limit_maxbytes")) {
- bytes_total = atof(fields[2]);
+ bytes_total = atoll(fields[2]);
}
/*
else if (FIELD_IS("curr_connections")) {
submit_gauge("memcached_connections", "current", atof(fields[2]), st);
} else if (FIELD_IS("listen_disabled_num")) {
- submit_derive("connections", "listen_disabled", atof(fields[2]), st);
+ submit_derive("total_events", "listen_disabled", atoll(fields[2]), st);
+ }
+ /*
+ * Total number of connections opened since the server started running
+ * Report this as connection rate.
+ */
+ else if (FIELD_IS("total_connections")) {
+ submit_derive("connections", "opened", atoll(fields[2]), st);
}
/*
const char *name = fields[1] + 4;
submit_derive("memcached_command", name, atoll(fields[2]), st);
if (strcmp(name, "get") == 0)
- gets = atof(fields[2]);
+ cmd_get = atoll(fields[2]);
}
/*
* Increment/Decrement
*/
else if (FIELD_IS("incr_misses")) {
- derive_t incr_count = atoll(fields[2]);
- submit_derive("memcached_ops", "incr_misses", incr_count, st);
- incr += incr_count;
+ incr_misses = atoll(fields[2]);
+ submit_derive("memcached_ops", "incr_misses", incr_misses, st);
} else if (FIELD_IS("incr_hits")) {
- derive_t incr_count = atoll(fields[2]);
- submit_derive("memcached_ops", "incr_hits", incr_count, st);
- incr_hits = atof(fields[2]);
- incr += incr_count;
+ incr_hits = atoll(fields[2]);
+ submit_derive("memcached_ops", "incr_hits", incr_hits, st);
} else if (FIELD_IS("decr_misses")) {
- derive_t decr_count = atoll(fields[2]);
- submit_derive("memcached_ops", "decr_misses", decr_count, st);
- decr += decr_count;
+ decr_misses = atoll(fields[2]);
+ submit_derive("memcached_ops", "decr_misses", decr_misses, st);
} else if (FIELD_IS("decr_hits")) {
- derive_t decr_count = atoll(fields[2]);
- submit_derive("memcached_ops", "decr_hits", decr_count, st);
- decr_hits = atof(fields[2]);
- decr += decr_count;
+ decr_hits = atoll(fields[2]);
+ submit_derive("memcached_ops", "decr_hits", decr_hits, st);
}
/*
- * Operations on the cache, i. e. cache hits, cache misses and evictions of
- * items
+ * Operations on the cache:
+ * - get hits/misses
+ * - delete hits/misses
+ * - evictions
*/
else if (FIELD_IS("get_hits")) {
- submit_derive("memcached_ops", "hits", atoll(fields[2]), st);
- hits = atof(fields[2]);
+ get_hits = atoll(fields[2]);
+ submit_derive("memcached_ops", "hits", get_hits, st);
} else if (FIELD_IS("get_misses")) {
submit_derive("memcached_ops", "misses", atoll(fields[2]), st);
} else if (FIELD_IS("evictions")) {
submit_derive("memcached_ops", "evictions", atoll(fields[2]), st);
+ } else if (FIELD_IS("delete_hits")) {
+ submit_derive("memcached_ops", "delete_hits", atoll(fields[2]), st);
+ } else if (FIELD_IS("delete_misses")) {
+ submit_derive("memcached_ops", "delete_misses", atoll(fields[2]), st);
}
/*
}
} /* while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL) */
- if (!isnan(bytes_used) && !isnan(bytes_total) && (bytes_used <= bytes_total))
+ if ((bytes_total > 0) && (bytes_used <= bytes_total))
submit_gauge2("df", "cache", bytes_used, bytes_total - bytes_used, st);
if ((rusage_user != 0) || (rusage_syst != 0))
if ((octets_rx != 0) || (octets_tx != 0))
submit_derive2("memcached_octets", NULL, octets_rx, octets_tx, st);
- if (!isnan(gets) && !isnan(hits)) {
- gauge_t rate = NAN;
-
- if (gets != 0.0)
- rate = 100.0 * hits / gets;
-
- submit_gauge("percent", "hitratio", rate, st);
+ if ((cmd_get != 0) && (get_hits != 0)) {
+ gauge_t ratio =
+ calculate_ratio_percent(get_hits, cmd_get, &prev->hits, &prev->gets);
+ submit_gauge("percent", "hitratio", ratio, st);
}
- if (!isnan(incr_hits) && incr != 0) {
- gauge_t incr_rate = 100.0 * incr_hits / incr;
- submit_gauge("percent", "incr_hitratio", incr_rate, st);
- submit_derive("memcached_ops", "incr", incr, st);
+ if ((incr_hits != 0) && (incr_misses != 0)) {
+ gauge_t ratio = calculate_ratio_percent2(
+ incr_hits, incr_misses, &prev->incr_hits, &prev->incr_misses);
+ submit_gauge("percent", "incr_hitratio", ratio, st);
+ submit_derive("memcached_ops", "incr", incr_hits + incr_misses, st);
}
- if (!isnan(decr_hits) && decr != 0) {
- gauge_t decr_rate = 100.0 * decr_hits / decr;
- submit_gauge("percent", "decr_hitratio", decr_rate, st);
- submit_derive("memcached_ops", "decr", decr, st);
+ if ((decr_hits != 0) && (decr_misses != 0)) {
+ gauge_t ratio = calculate_ratio_percent2(
+ decr_hits, decr_misses, &prev->decr_hits, &prev->decr_misses);
+ submit_gauge("percent", "decr_hitratio", ratio, st);
+ submit_derive("memcached_ops", "decr", decr_hits + decr_misses, st);
}
return 0;
} /* int memcached_read */
-static int memcached_add_read_callback(memcached_t *st) {
- char callback_name[3 * DATA_MAX_NAME_LEN];
- int status;
-
- ssnprintf(callback_name, sizeof(callback_name), "memcached/%s",
- (st->name != NULL) ? st->name : "__legacy__");
-
+static int memcached_set_defaults(memcached_t *st) {
/* If no <Address> used then:
* - Connect to the destination specified by <Host>, if present.
* If not, use the default address.
if (st->host) {
st->connhost = strdup(st->host);
if (st->connhost == NULL)
- return (ENOMEM);
+ return ENOMEM;
if ((strcmp("127.0.0.1", st->host) == 0) ||
(strcmp("localhost", st->host) == 0))
} else {
st->connhost = strdup(MEMCACHED_DEF_HOST);
if (st->connhost == NULL)
- return (ENOMEM);
+ return ENOMEM;
}
}
if (st->connport == NULL) {
st->connport = strdup(MEMCACHED_DEF_PORT);
if (st->connport == NULL)
- return (ENOMEM);
+ return ENOMEM;
}
assert(st->connhost != NULL);
assert(st->connport != NULL);
- status = plugin_register_complex_read(
+ st->prev.hits = 0;
+ st->prev.gets = 0;
+ st->prev.incr_hits = 0;
+ st->prev.incr_misses = 0;
+ st->prev.decr_hits = 0;
+ st->prev.decr_misses = 0;
+
+ return 0;
+} /* int memcached_set_defaults */
+
+static int memcached_add_read_callback(memcached_t *st) {
+ char callback_name[3 * DATA_MAX_NAME_LEN];
+
+ if (memcached_set_defaults(st) != 0) {
+ memcached_free(st);
+ return -1;
+ }
+
+ snprintf(callback_name, sizeof(callback_name), "memcached/%s",
+ (st->name != NULL) ? st->name : "__legacy__");
+
+ return plugin_register_complex_read(
/* group = */ "memcached",
/* name = */ callback_name,
/* callback = */ memcached_read,
- /* interval = */ 0, &(user_data_t){
- .data = st, .free_func = memcached_free,
- });
-
- return (status);
+ /* interval = */ 0,
+ &(user_data_t){
+ .data = st, .free_func = memcached_free,
+ });
} /* int memcached_add_read_callback */
/* Configuration handling functiions
* </Plugin>
*/
static int config_add_instance(oconfig_item_t *ci) {
- memcached_t *st;
int status = 0;
/* Disable automatic generation of default instance in the init callback. */
memcached_have_instances = 1;
- st = calloc(1, sizeof(*st));
+ memcached_t *st = calloc(1, sizeof(*st));
if (st == NULL) {
ERROR("memcached plugin: calloc failed.");
- return (ENOMEM);
+ return ENOMEM;
}
st->name = NULL;
st->connhost = NULL;
st->connport = NULL;
+ st->fd = -1;
+
if (strcasecmp(ci->key, "Instance") == 0)
status = cf_util_get_string(ci, &st->name);
if (status != 0) {
sfree(st);
- return (status);
+ return status;
}
for (int i = 0; i < ci->children_num; i++) {
break;
}
- if (status == 0)
- status = memcached_add_read_callback(st);
-
if (status != 0) {
memcached_free(st);
- return (-1);
+ return -1;
}
- return (0);
-}
+ return memcached_add_read_callback(st);
+} /* int config_add_instance */
static int memcached_config(oconfig_item_t *ci) {
- int status = 0;
_Bool have_instance_block = 0;
for (int i = 0; i < ci->children_num; i++) {
} else if (!have_instance_block) {
/* Non-instance option: Assume legacy configuration (without <Instance />
* blocks) and call config_add_instance() with the <Plugin /> block. */
- return (config_add_instance(ci));
+ return config_add_instance(ci);
} else
WARNING("memcached plugin: The configuration option "
"\"%s\" is not allowed here. Did you "
child->key);
} /* for (ci->children) */
- return (status);
-}
+ return 0;
+} /* int memcached_config */
static int memcached_init(void) {
- memcached_t *st;
- int status;
if (memcached_have_instances)
- return (0);
+ return 0;
/* No instances were configured, lets start a default instance. */
- st = calloc(1, sizeof(*st));
+ memcached_t *st = calloc(1, sizeof(*st));
if (st == NULL)
- return (ENOMEM);
+ return ENOMEM;
st->name = NULL;
st->host = NULL;
st->socket = NULL;
st->connhost = NULL;
st->connport = NULL;
- status = memcached_add_read_callback(st);
+ st->fd = -1;
+
+ int status = memcached_add_read_callback(st);
if (status == 0)
memcached_have_instances = 1;
- else
- memcached_free(st);
- return (status);
+ return status;
} /* int memcached_init */
void module_register(void) {
child->key);
}
- return (0);
+ return 0;
} /* }}} int memory_config */
static int memory_init(void) {
pagesize = getpagesize();
if (get_kstat(&ksp, "unix", 0, "system_pages") != 0) {
ksp = NULL;
- return (-1);
+ return -1;
}
if (get_kstat(&ksz, "zfs", 0, "arcstats") != 0) {
ksz = NULL;
- return (-1);
+ return -1;
}
/* #endif HAVE_LIBKSTAT */
pagesize = getpagesize();
if (pagesize <= 0) {
ERROR("memory plugin: Invalid pagesize: %i", pagesize);
- return (-1);
+ return -1;
}
/* #endif HAVE_SYSCTL */
#elif HAVE_PERFSTAT
pagesize = getpagesize();
#endif /* HAVE_PERFSTAT */
- return (0);
+ return 0;
} /* int memory_init */
#define MEMORY_SUBMIT(...) \
gauge_t free;
if (!port_host || !pagesize)
- return (-1);
+ return -1;
vm_data_len = sizeof(vm_data) / sizeof(natural_t);
if ((status = host_statistics(port_host, HOST_VM_INFO, (host_info_t)&vm_data,
&vm_data_len)) != KERN_SUCCESS) {
ERROR("memory-plugin: host_statistics failed and returned the value %i",
(int)status);
- return (-1);
+ return -1;
}
/*
if ((fh = fopen("/proc/meminfo", "r")) == NULL) {
char errbuf[1024];
WARNING("memory: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
}
if (mem_total < (mem_free + mem_buffered + mem_cached + mem_slab_total))
- return (-1);
+ return -1;
mem_used =
mem_total - (mem_free + mem_buffered + mem_cached + mem_slab_total);
long long availrmem;
if (ksp == NULL)
- return (-1);
+ return -1;
if (ksz == NULL)
- return (-1);
+ return -1;
mem_used = get_kstat_value(ksp, "pagestotal");
mem_free = get_kstat_value(ksp, "pagesfree");
if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL)) {
WARNING("memory plugin: one of used, free or locked is negative.");
- return (-1);
+ return -1;
}
mem_unus = physmem - mem_used;
char errbuf[1024];
WARNING("memory plugin: sysctl failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
assert(pagesize > 0);
ios = sg_get_mem_stats();
if (ios == NULL)
- return (-1);
+ return -1;
MEMORY_SUBMIT("used", (gauge_t)ios->used, "cached", (gauge_t)ios->cache,
"free", (gauge_t)ios->free);
char errbuf[1024];
WARNING("memory plugin: perfstat_memory_total failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
/* Unfortunately, the AIX documentation is not very clear on how these
(gauge_t)(pmemory.real_process * pagesize));
#endif /* HAVE_PERFSTAT */
- return (0);
+ return 0;
} /* }}} int memory_read_internal */
static int memory_read(void) /* {{{ */
sstrncpy(vl.type, "memory", sizeof(vl.type));
vl.time = cdtime();
- return (memory_read_internal(&vl));
+ return memory_read_internal(&vl);
} /* }}} int memory_read */
void module_register(void) {
U32 mic_count;
if (mic_handle)
- return (0);
+ return 0;
mic_count = (U32)STATIC_ARRAY_SIZE(mics);
ret = MicInitAPI(&mic_handle, eTARGET_SCIF_DRIVER, mics, &mic_count);
if (mic_count < 0 || mic_count >= MAX_MICS) {
ERROR("mic plugin: No Intel MICs in system");
- return (1);
+ return 1;
} else {
num_mics = mic_count;
- return (0);
+ return 0;
}
}
if (power_ignore == NULL)
power_ignore = ignorelist_create(1);
if (temp_ignore == NULL || power_ignore == NULL)
- return (1);
+ return 1;
if (strcasecmp("ShowCPU", key) == 0) {
show_cpu = IS_TRUE(value);
invert = 0;
ignorelist_set_invert(power_ignore, invert);
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static void mic_submit_memory_use(int micnumber, const char *type_instance,
vl.values_len = 1;
strncpy(vl.plugin, "mic", sizeof(vl.plugin));
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
strncpy(vl.type, "memory", sizeof(vl.type));
strncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
if (ret != MIC_ACCESS_API_SUCCESS) {
ERROR("mic plugin: Problem getting Memory Utilization: %s",
MicGetErrorString(ret));
- return (1);
+ return 1;
}
mic_submit_memory_use(mic, "free", mem_free);
mic_submit_memory_use(mic, "used", mem_total - mem_free - mem_bufs);
mic_submit_memory_use(mic, "buffered", mem_bufs);
DEBUG("mic plugin: Memory Read: %u %u %u", mem_total, mem_free, mem_bufs);
- return (0);
+ return 0;
}
static void mic_submit_temp(int micnumber, const char *type, gauge_t value) {
vl.values = &(value_t){.gauge = value};
vl.values_len = 1;
- strncpy(vl.host, hostname_g, sizeof(vl.host));
strncpy(vl.plugin, "mic", sizeof(vl.plugin));
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
strncpy(vl.type, "temperature", sizeof(vl.type));
strncpy(vl.type_instance, type, sizeof(vl.type_instance));
ERROR("mic plugin: Error reading temperature \"%s\": "
"%s",
name, MicGetErrorString(status));
- return (1);
+ return 1;
}
mic_submit_temp(mic, name, temp_buffer);
}
- return (0);
+ return 0;
}
static void mic_submit_cpu(int micnumber, const char *type_instance, int core,
vl.values = &(value_t){.derive = value};
vl.values_len = 1;
- strncpy(vl.host, hostname_g, sizeof(vl.host));
strncpy(vl.plugin, "mic", sizeof(vl.plugin));
if (core < 0) /* global aggregation */
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
else /* per-core statistics */
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i-cpu-%i",
- micnumber, core);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i-cpu-%i",
+ micnumber, core);
strncpy(vl.type, "cpu", sizeof(vl.type));
strncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
if (status != MIC_ACCESS_API_SUCCESS) {
ERROR("mic plugin: Problem getting CPU utilization: %s",
MicGetErrorString(status));
- return (-1);
+ return -1;
}
if (show_cpu) {
mic_submit_cpu(mic, "idle", j, core_jiffs[j].idle);
}
}
- return (0);
+ return 0;
}
static void mic_submit_power(int micnumber, const char *type,
vl.values = &(value_t){.gauge = value};
vl.values_len = 1;
- strncpy(vl.host, hostname_g, sizeof(vl.host));
strncpy(vl.plugin, "mic", sizeof(vl.plugin));
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
strncpy(vl.type, type, sizeof(vl.type));
strncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
if (ret != MIC_ACCESS_API_SUCCESS) {
ERROR("mic plugin: Problem getting Power Usage: %s",
MicGetErrorString(ret));
- return (1);
+ return 1;
}
/* power is in uWatts, current in mA, voltage in uVolts.. convert to
SUB_VOLTS(vddg);
SUB_VOLTS(vddq);
- return (0);
+ return 0;
}
static int mic_read(void) {
MicCloseAPI(&mic_handle);
mic_handle = NULL;
- return (0);
+ return 0;
}
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 :
- */
static mb_data_t *data_get_by_name(mb_data_t *src, /* {{{ */
const char *name) {
if (name == NULL)
- return (NULL);
+ return NULL;
for (mb_data_t *ptr = src; ptr != NULL; ptr = ptr->next)
if (strcasecmp(ptr->name, name) == 0)
- return (ptr);
+ return ptr;
- return (NULL);
+ return NULL;
} /* }}} mb_data_t *data_get_by_name */
static int data_append(mb_data_t **dst, mb_data_t *src) /* {{{ */
mb_data_t *ptr;
if ((dst == NULL) || (src == NULL))
- return (EINVAL);
+ return EINVAL;
ptr = *dst;
if (ptr == NULL) {
*dst = src;
- return (0);
+ return 0;
}
while (ptr->next != NULL)
ptr->next = src;
- return (0);
+ return 0;
} /* }}} int data_append */
/* Copy a single mb_data_t and append it to another list. */
int status;
if ((dst == NULL) || (src == NULL))
- return (EINVAL);
+ return EINVAL;
tmp = malloc(sizeof(*tmp));
if (tmp == NULL)
- return (ENOMEM);
+ return ENOMEM;
memcpy(tmp, src, sizeof(*tmp));
tmp->name = NULL;
tmp->next = NULL;
tmp->name = strdup(src->name);
if (tmp->name == NULL) {
sfree(tmp);
- return (ENOMEM);
+ return ENOMEM;
}
status = data_append(dst, tmp);
if (status != 0) {
sfree(tmp->name);
sfree(tmp);
- return (status);
+ return status;
}
- return (0);
+ return 0;
} /* }}} int data_copy */
/* Lookup a single mb_data_t instance, copy it and append the copy to another
mb_data_t *ptr;
if ((dst == NULL) || (src == NULL) || (name == NULL))
- return (EINVAL);
+ return EINVAL;
ptr = data_get_by_name(src, name);
if (ptr == NULL)
- return (ENOENT);
+ return ENOENT;
- return (data_copy(dst, ptr));
+ return data_copy(dst, ptr);
} /* }}} int data_copy_by_name */
/* Read functions */
value_list_t vl = VALUE_LIST_INIT;
if ((host == NULL) || (slave == NULL) || (data == NULL))
- return (EINVAL);
+ return EINVAL;
if (host->interval == 0)
host->interval = plugin_get_interval();
if (slave->instance[0] == 0)
- ssnprintf(slave->instance, sizeof(slave->instance), "slave_%i", slave->id);
+ snprintf(slave->instance, sizeof(slave->instance), "slave_%i", slave->id);
vl.values = &value;
vl.values_len = 1;
sstrncpy(vl.type, data->type, sizeof(vl.type));
sstrncpy(vl.type_instance, data->instance, sizeof(vl.type_instance));
- return (plugin_dispatch_values(&vl));
+ return plugin_dispatch_values(&vl);
} /* }}} int mb_submit */
static float mb_register_to_float(uint16_t hi, uint16_t lo) /* {{{ */
conv.b[0] = (hi >> 8) & 0x00ff;
#endif
- return (conv.f);
+ return conv.f;
} /* }}} float mb_register_to_float */
#if LEGACY_LIBMODBUS
int status;
if (host == NULL)
- return (EINVAL);
+ return EINVAL;
#if COLLECT_DEBUG
modbus_set_debug(&host->connection, 1);
if (status != 0) {
ERROR("Modbus plugin: modbus_connect (%s, %i) failed with status %i.",
host->node, host->port ? host->port : host->baudrate, status);
- return (status);
+ return status;
}
host->is_connected = 1;
- return (0);
+ return 0;
} /* }}} int mb_init_connection */
/* #endif LEGACY_LIBMODBUS */
int status;
if (host == NULL)
- return (EINVAL);
+ return EINVAL;
if (host->connection != NULL)
- return (0);
+ return 0;
if (host->conntype == MBCONN_TCP) {
if ((host->port < 1) || (host->port > 65535))
host->connection = modbus_new_tcp(host->node, host->port);
if (host->connection == NULL) {
ERROR("Modbus plugin: Creating new Modbus/TCP object failed.");
- return (-1);
+ return -1;
}
} else {
DEBUG("Modbus plugin: Trying to connect to \"%s\", baudrate %i.",
host->connection = modbus_new_rtu(host->node, host->baudrate, 'N', 8, 1);
if (host->connection == NULL) {
ERROR("Modbus plugin: Creating new Modbus/RTU object failed.");
- return (-1);
+ return -1;
}
}
host->node, host->port ? host->port : host->baudrate, status);
modbus_free(host->connection);
host->connection = NULL;
- return (status);
+ return status;
}
- return (0);
+ return 0;
} /* }}} int mb_init_connection */
#endif /* !LEGACY_LIBMODBUS */
int status = 0;
if ((host == NULL) || (slave == NULL) || (data == NULL))
- return (EINVAL);
+ return EINVAL;
ds = plugin_get_ds(data->type);
if (ds == NULL) {
ERROR("Modbus plugin: Type \"%s\" is not defined.", data->type);
- return (-1);
+ return -1;
}
if (ds->ds_num != 1) {
ERROR("Modbus plugin: The type \"%s\" has %zu data sources. "
"I can only handle data sets with only one data source.",
data->type, ds->ds_num);
- return (-1);
+ return -1;
}
if ((ds->ds[0].type != DS_TYPE_GAUGE) &&
host->node);
host->is_connected = 0;
host->connection = NULL;
- return (-1);
+ return -1;
}
} else if (status != 0) {
#if LEGACY_LIBMODBUS
if (status != 0) {
ERROR("Modbus plugin: modbus_set_slave (%i) failed with status %i.",
slave->id, status);
- return (-1);
+ return -1;
}
#endif
if (data->modbus_register_type == MREG_INPUT) {
modbus_free(host->connection);
#endif
host->connection = NULL;
- return (-1);
+ return -1;
}
DEBUG("Modbus plugin: mb_read_data: Success! "
mb_submit(host, slave, data, vt);
}
- return (0);
+ return 0;
} /* }}} int mb_read_data */
static int mb_read_slave(mb_host_t *host, mb_slave_t *slave) /* {{{ */
int status;
if ((host == NULL) || (slave == NULL))
- return (EINVAL);
+ return EINVAL;
success = 0;
for (mb_data_t *data = slave->collect; data != NULL; data = data->next) {
}
if (success == 0)
- return (-1);
+ return -1;
else
- return (0);
+ return 0;
} /* }}} int mb_read_slave */
static int mb_read(user_data_t *user_data) /* {{{ */
int status;
if ((user_data == NULL) || (user_data->data == NULL))
- return (EINVAL);
+ return EINVAL;
host = user_data->data;
}
if (success == 0)
- return (-1);
+ return -1;
else
- return (0);
+ return 0;
} /* }}} int mb_read */
/* Free functions */
status = cf_util_get_string(ci, &data.name);
if (status != 0)
- return (status);
+ return status;
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
sfree(data.name);
- return (status);
+ return status;
} /* }}} int mb_config_add_data */
static int mb_config_set_host_address(mb_host_t *host, /* {{{ */
int status;
if ((host == NULL) || (address == NULL))
- return (EINVAL);
+ return EINVAL;
struct addrinfo ai_hints = {
/* XXX: libmodbus can only handle IPv4 addresses. */
ERROR("Modbus plugin: getaddrinfo failed: %s",
(status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
: gai_strerror(status));
- return (status);
+ return status;
}
for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
host->node);
}
- return (status);
+ return status;
} /* }}} int mb_config_set_host_address */
static int mb_config_add_slave(mb_host_t *host, oconfig_item_t *ci) /* {{{ */
int status;
if ((host == NULL) || (ci == NULL))
- return (EINVAL);
+ return EINVAL;
slave = realloc(host->slaves, sizeof(*slave) * (host->slaves_num + 1));
if (slave == NULL)
- return (ENOMEM);
+ return ENOMEM;
host->slaves = slave;
slave = host->slaves + host->slaves_num;
memset(slave, 0, sizeof(*slave));
status = cf_util_get_int(ci, &slave->id);
if (status != 0)
- return (status);
+ return status;
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
else /* if (status != 0) */
data_free_all(slave->collect);
- return (status);
+ return status;
} /* }}} int mb_config_add_slave */
static int mb_config_add_host(oconfig_item_t *ci) /* {{{ */
host = calloc(1, sizeof(*host));
if (host == NULL)
- return (ENOMEM);
+ return ENOMEM;
host->slaves = NULL;
status = cf_util_get_string_buffer(ci, host->host, sizeof(host->host));
if (status != 0) {
sfree(host);
- return (status);
+ return status;
}
if (host->host[0] == 0) {
sfree(host);
- return (EINVAL);
+ return EINVAL;
}
for (int i = 0; i < ci->children_num; i++) {
if (status == 0) {
char name[1024];
- ssnprintf(name, sizeof(name), "modbus-%s", host->host);
+ snprintf(name, sizeof(name), "modbus-%s", host->host);
plugin_register_complex_read(/* group = */ NULL, name,
/* callback = */ mb_read,
host_free(host);
}
- return (status);
+ return status;
} /* }}} int mb_config_add_host */
static int mb_config(oconfig_item_t *ci) /* {{{ */
{
if (ci == NULL)
- return (EINVAL);
+ return EINVAL;
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
ERROR("Modbus plugin: Unknown configuration option: %s", child->key);
}
- return (0);
+ return 0;
} /* }}} int mb_config */
/* ========= */
data_free_all(data_definitions);
data_definitions = NULL;
- return (0);
+ return 0;
} /* }}} int mb_shutdown */
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 : */
num++;
if (num < 2)
- return (NULL);
+ return NULL;
while (num > 2) {
char *tmp = strchr(topic, '/');
if (tmp == NULL)
- return (NULL);
+ return NULL;
topic = tmp + 1;
num--;
}
- return (topic);
+ return topic;
}
static void on_message(
int status;
if (conf->connected)
- return (0);
+ return 0;
status = mosquitto_reconnect(conf->mosq);
if (status != MOSQ_ERR_SUCCESS) {
ERROR("mqtt_connect_broker: mosquitto_connect failed: %s",
(status == MOSQ_ERR_ERRNO) ? sstrerror(errno, errbuf, sizeof(errbuf))
: mosquitto_strerror(status));
- return (-1);
+ return -1;
}
conf->connected = 1;
"mqtt plugin: successfully reconnected to broker \"%s:%d\"",
conf->host, conf->port);
- return (0);
+ return 0;
} /* mqtt_reconnect */
/* must hold conf->lock when calling. */
#endif
if (conf->mosq == NULL) {
ERROR("mqtt plugin: mosquitto_new failed");
- return (-1);
+ return -1;
}
#if LIBMOSQUITTO_MAJOR != 0
mosquitto_strerror(status));
mosquitto_destroy(conf->mosq);
conf->mosq = NULL;
- return (-1);
+ return -1;
}
status = mosquitto_tls_opts_set(conf->mosq, SSL_VERIFY_PEER,
mosquitto_strerror(status));
mosquitto_destroy(conf->mosq);
conf->mosq = NULL;
- return (-1);
+ return -1;
}
status = mosquitto_tls_insecure_set(conf->mosq, false);
mosquitto_strerror(status));
mosquitto_destroy(conf->mosq);
conf->mosq = NULL;
- return (-1);
+ return -1;
}
}
#endif
mosquitto_destroy(conf->mosq);
conf->mosq = NULL;
- return (-1);
+ return -1;
}
}
mosquitto_destroy(conf->mosq);
conf->mosq = NULL;
- return (-1);
+ return -1;
}
if (!conf->publish) {
mosquitto_disconnect(conf->mosq);
mosquitto_destroy(conf->mosq);
conf->mosq = NULL;
- return (-1);
+ return -1;
}
}
conf->connected = 1;
- return (0);
+ return 0;
} /* mqtt_connect */
static void *subscribers_thread(void *arg) {
if (status != 0) {
pthread_mutex_unlock(&conf->lock);
ERROR("mqtt plugin: unable to reconnect to broker");
- return (status);
+ return status;
}
status = mosquitto_publish(conf->mosq, /* message_id */ NULL, topic,
mosquitto_disconnect(conf->mosq);
pthread_mutex_unlock(&conf->lock);
- return (-1);
+ return -1;
}
pthread_mutex_unlock(&conf->lock);
- return (0);
+ return 0;
} /* int publish */
static int format_topic(char *buf, size_t buf_len, data_set_t const *ds,
char *c;
if ((conf->topic_prefix == NULL) || (conf->topic_prefix[0] == 0))
- return (FORMAT_VL(buf, buf_len, vl));
+ return FORMAT_VL(buf, buf_len, vl);
status = FORMAT_VL(name, sizeof(name), vl);
if (status != 0)
- return (status);
+ return status;
- status = ssnprintf(buf, buf_len, "%s/%s", conf->topic_prefix, name);
+ status = snprintf(buf, buf_len, "%s/%s", conf->topic_prefix, name);
if ((status < 0) || (((size_t)status) >= buf_len))
- return (ENOMEM);
+ return ENOMEM;
- while((c = strchr(buf, '#')) || (c = strchr(buf, '+'))) {
- *c = '_';
+ while ((c = strchr(buf, '#')) || (c = strchr(buf, '+'))) {
+ *c = '_';
}
- return (0);
+ return 0;
} /* int format_topic */
static int mqtt_write(const data_set_t *ds, const value_list_t *vl,
int status = 0;
if ((user_data == NULL) || (user_data->data == NULL))
- return (EINVAL);
+ return EINVAL;
conf = user_data->data;
status = format_topic(topic, sizeof(topic), ds, vl, conf);
if (status != 0) {
ERROR("mqtt plugin: format_topic failed with status %d.", status);
- return (status);
+ return status;
}
status = format_values(payload, sizeof(payload), ds, vl, conf->store_rates);
if (status != 0) {
ERROR("mqtt plugin: format_values failed with status %d.", status);
- return (status);
+ return status;
}
status = publish(conf, topic, payload, strlen(payload) + 1);
if (status != 0) {
ERROR("mqtt plugin: publish failed: %s", mosquitto_strerror(status));
- return (status);
+ return status;
}
- return (status);
+ return status;
} /* mqtt_write */
/*
* StoreRates true
* Retain false
* QoS 0
- * CACert "ca.pem" Enables TLS if set
- * CertificateFile "client-cert.pem" optional
- * CertificateKeyFile "client-key.pem" optional
- * TLSProtocol "tlsv1.2" optional
+ * CACert "ca.pem" Enables TLS if set
+ * CertificateFile "client-cert.pem" optional
+ * CertificateKeyFile "client-key.pem" optional
+ * TLSProtocol "tlsv1.2" optional
* </Publish>
*/
static int mqtt_config_publisher(oconfig_item_t *ci) {
conf = calloc(1, sizeof(*conf));
if (conf == NULL) {
ERROR("mqtt plugin: calloc failed.");
- return (-1);
+ return -1;
}
conf->publish = 1;
status = cf_util_get_string(ci, &conf->name);
if (status != 0) {
mqtt_free(conf);
- return (status);
+ return status;
}
conf->host = strdup(MQTT_DEFAULT_HOST);
status = pthread_mutex_init(&conf->lock, NULL);
if (status != 0) {
mqtt_free(conf);
- return (status);
+ return status;
}
C_COMPLAIN_INIT(&conf->complaint_cantpublish);
ERROR("mqtt plugin: Unknown config option: %s", child->key);
}
- ssnprintf(cb_name, sizeof(cb_name), "mqtt/%s", conf->name);
- plugin_register_write(cb_name, mqtt_write, &(user_data_t){
- .data = conf,
- });
- return (0);
+ snprintf(cb_name, sizeof(cb_name), "mqtt/%s", conf->name);
+ plugin_register_write(cb_name, mqtt_write,
+ &(user_data_t){
+ .data = conf,
+ });
+ return 0;
} /* mqtt_config_publisher */
/*
* User "guest"
* Password "secret"
* Topic "collectd/#"
+ * CACert "ca.pem" Enables TLS if set
+ * CertificateFile "client-cert.pem" optional
+ * CertificateKeyFile "client-key.pem" optional
+ * TLSProtocol "tlsv1.2" optional
* </Subscribe>
*/
static int mqtt_config_subscriber(oconfig_item_t *ci) {
conf = calloc(1, sizeof(*conf));
if (conf == NULL) {
ERROR("mqtt plugin: calloc failed.");
- return (-1);
+ return -1;
}
conf->publish = 0;
status = cf_util_get_string(ci, &conf->name);
if (status != 0) {
mqtt_free(conf);
- return (status);
+ return status;
}
conf->host = strdup(MQTT_DEFAULT_HOST);
status = pthread_mutex_init(&conf->lock, NULL);
if (status != 0) {
mqtt_free(conf);
- return (status);
+ return status;
}
C_COMPLAIN_INIT(&conf->complaint_cantpublish);
cf_util_get_string(child, &conf->topic);
else if (strcasecmp("CleanSession", child->key) == 0)
cf_util_get_boolean(child, &conf->clean_session);
+ else if (strcasecmp("CACert", child->key) == 0)
+ cf_util_get_string(child, &conf->cacertificatefile);
+ else if (strcasecmp("CertificateFile", child->key) == 0)
+ cf_util_get_string(child, &conf->certificatefile);
+ else if (strcasecmp("CertificateKeyFile", child->key) == 0)
+ cf_util_get_string(child, &conf->certificatekeyfile);
+ else if (strcasecmp("TLSProtocol", child->key) == 0)
+ cf_util_get_string(child, &conf->tlsprotocol);
+ else if (strcasecmp("CipherSuite", child->key) == 0)
+ cf_util_get_string(child, &conf->ciphersuite);
else
ERROR("mqtt plugin: Unknown config option: %s", child->key);
}
if (tmp == NULL) {
ERROR("mqtt plugin: realloc failed.");
mqtt_free(conf);
- return (-1);
+ return -1;
}
subscribers = tmp;
subscribers[subscribers_num] = conf;
subscribers_num++;
- return (0);
+ return 0;
} /* mqtt_config_subscriber */
/*
ERROR("mqtt plugin: Unknown config option: %s", child->key);
}
- return (0);
+ return 0;
} /* int mqtt_config */
static int mqtt_init(void) {
}
}
- return (0);
+ return 0;
} /* mqtt_init */
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 : */
/* Intel MSRs. Some also available on other CPUs */
/* C-state Residency Counters */
-#define MSR_PKG_C3_RESIDENCY 0x000003f8
-#define MSR_PKG_C6_RESIDENCY 0x000003f9
-#define MSR_ATOM_PKG_C6_RESIDENCY 0x000003fa
-#define MSR_PKG_C7_RESIDENCY 0x000003fa
-#define MSR_CORE_C3_RESIDENCY 0x000003fc
-#define MSR_CORE_C6_RESIDENCY 0x000003fd
-#define MSR_CORE_C7_RESIDENCY 0x000003fe
-#define MSR_KNL_CORE_C6_RESIDENCY 0x000003ff
-#define MSR_PKG_C2_RESIDENCY 0x0000060d
-#define MSR_PKG_C8_RESIDENCY 0x00000630
-#define MSR_PKG_C9_RESIDENCY 0x00000631
-#define MSR_PKG_C10_RESIDENCY 0x00000632
+#define MSR_PKG_C3_RESIDENCY 0x000003f8
+#define MSR_PKG_C6_RESIDENCY 0x000003f9
+#define MSR_ATOM_PKG_C6_RESIDENCY 0x000003fa
+#define MSR_PKG_C7_RESIDENCY 0x000003fa
+#define MSR_CORE_C3_RESIDENCY 0x000003fc
+#define MSR_CORE_C6_RESIDENCY 0x000003fd
+#define MSR_CORE_C7_RESIDENCY 0x000003fe
+#define MSR_KNL_CORE_C6_RESIDENCY 0x000003ff
+#define MSR_PKG_C2_RESIDENCY 0x0000060d
+#define MSR_PKG_C8_RESIDENCY 0x00000630
+#define MSR_PKG_C9_RESIDENCY 0x00000631
+#define MSR_PKG_C10_RESIDENCY 0x00000632
/* Run Time Average Power Limiting (RAPL) Interface */
-#define MSR_RAPL_POWER_UNIT 0x00000606
+#define MSR_RAPL_POWER_UNIT 0x00000606
-#define MSR_PKG_POWER_LIMIT 0x00000610
-#define MSR_PKG_ENERGY_STATUS 0x00000611
-#define MSR_PKG_PERF_STATUS 0x00000613
-#define MSR_PKG_POWER_INFO 0x00000614
+#define MSR_PKG_POWER_LIMIT 0x00000610
+#define MSR_PKG_ENERGY_STATUS 0x00000611
+#define MSR_PKG_PERF_STATUS 0x00000613
+#define MSR_PKG_POWER_INFO 0x00000614
-#define MSR_DRAM_POWER_LIMIT 0x00000618
-#define MSR_DRAM_ENERGY_STATUS 0x00000619
-#define MSR_DRAM_PERF_STATUS 0x0000061b
-#define MSR_DRAM_POWER_INFO 0x0000061c
+#define MSR_DRAM_POWER_LIMIT 0x00000618
+#define MSR_DRAM_ENERGY_STATUS 0x00000619
+#define MSR_DRAM_PERF_STATUS 0x0000061b
+#define MSR_DRAM_POWER_INFO 0x0000061c
+
+#define MSR_PP0_POWER_LIMIT 0x00000638
+#define MSR_PP0_ENERGY_STATUS 0x00000639
+#define MSR_PP0_POLICY 0x0000063a
+#define MSR_PP0_PERF_STATUS 0x0000063b
+
+#define MSR_PP1_POWER_LIMIT 0x00000640
+#define MSR_PP1_ENERGY_STATUS 0x00000641
+#define MSR_PP1_POLICY 0x00000642
-#define MSR_PP0_POWER_LIMIT 0x00000638
-#define MSR_PP0_ENERGY_STATUS 0x00000639
-#define MSR_PP0_POLICY 0x0000063a
-#define MSR_PP0_PERF_STATUS 0x0000063b
-#define MSR_PP1_POWER_LIMIT 0x00000640
-#define MSR_PP1_ENERGY_STATUS 0x00000641
-#define MSR_PP1_POLICY 0x00000642
/* Intel defined MSRs. */
-#define MSR_IA32_TSC 0x00000010
-#define MSR_SMI_COUNT 0x00000034
+#define MSR_IA32_TSC 0x00000010
+#define MSR_SMI_COUNT 0x00000034
+
+#define MSR_IA32_MPERF 0x000000e7
+#define MSR_IA32_APERF 0x000000e8
-#define MSR_IA32_MPERF 0x000000e7
-#define MSR_IA32_APERF 0x000000e8
+#define MSR_IA32_THERM_STATUS 0x0000019c
-#define MSR_IA32_THERM_STATUS 0x0000019c
+#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
-#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
+#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1
-#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1
#endif /* _ASM_X86_MSR_INDEX_H */
#include "common.h"
#include "plugin.h"
-#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H && HAVE_MATH_H
-#include <math.h>
+#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#include <termios.h>
#else
char errbuf[1024];
ERROR("multimeter plugin: gettimeofday failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
time_end.tv_sec++;
struct timeval time_now;
status = swrite(fd, "D", 1);
- if (status < 0) {
+ if (status != 0) {
ERROR("multimeter plugin: swrite failed.");
- return (-1);
+ return -1;
}
FD_ZERO(&rfds);
ERROR("multimeter plugin: "
"gettimeofday failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
if (timeval_cmp(time_end, time_now, &timeout) < 0)
break;
break;
}
} else
- return (-1); /* Overflow */
+ return -1; /* Overflow */
- return (0); /* value received */
+ return 0; /* value received */
} else
break;
} else if (!status) /* Timeout */
}
} while (--retry);
- return (-2); /* no value received */
+ return -2; /* no value received */
} /* int multimeter_read_value */
static int multimeter_init(void) {
INFO("multimeter plugin: Device "
"found at %s",
device);
- return (0);
+ return 0;
}
}
}
ERROR("multimeter plugin: No device found");
- return (-1);
+ return -1;
}
#undef LINE_LENGTH
double value;
if (fd < 0)
- return (-1);
+ return -1;
if (multimeter_read_value(&value) != 0)
- return (-1);
+ return -1;
multimeter_submit(value);
- return (0);
+ return 0;
} /* int multimeter_read */
static int multimeter_shutdown(void) {
fd = -1;
}
- return (0);
+ return 0;
}
void module_register(void) {
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("mysql plugin: The `Database' block "
"needs exactly one string argument.");
- return (-1);
+ return -1;
}
db = calloc(1, sizeof(*db));
if (db == NULL) {
ERROR("mysql plugin: calloc failed.");
- return (-1);
+ return -1;
}
/* initialize all the pointers */
status = cf_util_get_string(ci, &db->instance);
if (status != 0) {
sfree(db);
- return (status);
+ return status;
}
assert(db->instance != NULL);
(db->database != NULL) ? db->database : "<default>");
if (db->instance != NULL)
- ssnprintf(cb_name, sizeof(cb_name), "mysql-%s", db->instance);
+ snprintf(cb_name, sizeof(cb_name), "mysql-%s", db->instance);
else
sstrncpy(cb_name, "mysql", sizeof(cb_name));
});
} else {
mysql_database_free(db);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int mysql_config_database */
static int mysql_config(oconfig_item_t *ci) /* {{{ */
{
if (ci == NULL)
- return (EINVAL);
+ return EINVAL;
/* Fill the `mysql_database_t' structure.. */
for (int i = 0; i < ci->children_num; i++) {
WARNING("mysql plugin: Option \"%s\" not allowed here.", child->key);
}
- return (0);
+ return 0;
} /* }}} int mysql_config */
/* }}} End of configuration handling functions */
status = mysql_ping(db->con);
if (status == 0)
- return (db->con);
+ return db->con;
WARNING("mysql plugin: Lost connection to instance \"%s\": %s",
db->instance, mysql_error(db->con));
db->con = mysql_init(NULL);
if (db->con == NULL) {
ERROR("mysql plugin: mysql_init failed: %s", mysql_error(db->con));
- return (NULL);
+ return NULL;
}
}
"at server %s: %s",
(db->database != NULL) ? db->database : "<none>",
(db->host != NULL) ? db->host : "localhost", mysql_error(db->con));
- return (NULL);
+ return NULL;
}
cipher = mysql_get_ssl_cipher(db->con);
mysql_get_server_info(db->con), mysql_get_proto_info(db->con));
db->is_connected = 1;
- return (db->con);
+ return db->con;
} /* static MYSQL *getconnection (mysql_database_t *db) */
static void set_host(mysql_database_t *db, char *buf, size_t buflen) {
if (mysql_real_query(con, query, query_len)) {
ERROR("mysql plugin: Failed to execute query: %s", mysql_error(con));
INFO("mysql plugin: SQL query was: %s", query);
- return (NULL);
+ return NULL;
}
res = mysql_store_result(con);
if (res == NULL) {
ERROR("mysql plugin: Failed to store query result: %s", mysql_error(con));
INFO("mysql plugin: SQL query was: %s", query);
- return (NULL);
+ return NULL;
}
- return (res);
+ return res;
} /* exec_query */
static int mysql_read_master_stats(mysql_database_t *db, MYSQL *con) {
res = exec_query(con, query);
if (res == NULL)
- return (-1);
+ return -1;
row = mysql_fetch_row(res);
if (row == NULL) {
"`%s' did not return any rows.",
query);
mysql_free_result(res);
- return (-1);
+ return -1;
}
field_num = mysql_num_fields(res);
"`%s' returned less than two columns.",
query);
mysql_free_result(res);
- return (-1);
+ return -1;
}
position = atoll(row[1]);
mysql_free_result(res);
- return (0);
+ return 0;
} /* mysql_read_master_stats */
static int mysql_read_slave_stats(mysql_database_t *db, MYSQL *con) {
res = exec_query(con, query);
if (res == NULL)
- return (-1);
+ return -1;
row = mysql_fetch_row(res);
if (row == NULL) {
"`%s' did not return any rows.",
query);
mysql_free_result(res);
- return (-1);
+ return -1;
}
field_num = mysql_num_fields(res);
"`%s' returned less than 33 columns.",
query);
mysql_free_result(res);
- return (-1);
+ return -1;
}
if (db->slave_stats) {
if (((io == NULL) || (strcasecmp(io, "yes") != 0)) &&
(db->slave_io_running)) {
n.severity = NOTIF_WARNING;
- ssnprintf(n.message, sizeof(n.message),
- "slave I/O thread not started or not connected to master");
+ snprintf(n.message, sizeof(n.message),
+ "slave I/O thread not started or not connected to master");
plugin_dispatch_notification(&n);
db->slave_io_running = 0;
} else if (((io != NULL) && (strcasecmp(io, "yes") == 0)) &&
(!db->slave_io_running)) {
n.severity = NOTIF_OKAY;
- ssnprintf(n.message, sizeof(n.message),
- "slave I/O thread started and connected to master");
+ snprintf(n.message, sizeof(n.message),
+ "slave I/O thread started and connected to master");
plugin_dispatch_notification(&n);
db->slave_io_running = 1;
}
if (((sql == NULL) || (strcasecmp(sql, "yes") != 0)) &&
(db->slave_sql_running)) {
n.severity = NOTIF_WARNING;
- ssnprintf(n.message, sizeof(n.message), "slave SQL thread not started");
+ snprintf(n.message, sizeof(n.message), "slave SQL thread not started");
plugin_dispatch_notification(&n);
db->slave_sql_running = 0;
} else if (((sql != NULL) && (strcasecmp(sql, "yes") == 0)) &&
(!db->slave_sql_running)) {
n.severity = NOTIF_OKAY;
- ssnprintf(n.message, sizeof(n.message), "slave SQL thread started");
+ snprintf(n.message, sizeof(n.message), "slave SQL thread started");
plugin_dispatch_notification(&n);
db->slave_sql_running = 1;
}
mysql_free_result(res);
- return (0);
+ return 0;
} /* mysql_read_slave_stats */
static int mysql_read_innodb_stats(mysql_database_t *db, MYSQL *con) {
res = exec_query(con, query);
if (res == NULL)
- return (-1);
+ return -1;
while ((row = mysql_fetch_row(res))) {
int i;
}
mysql_free_result(res);
- return (0);
+ return 0;
}
static int mysql_read_wsrep_stats(mysql_database_t *db, MYSQL *con) {
res = exec_query(con, query);
if (res == NULL)
- return (-1);
+ return -1;
row = mysql_fetch_row(res);
if (row == NULL) {
"`%s' did not return any rows.",
query);
mysql_free_result(res);
- return (-1);
+ return -1;
}
while ((row = mysql_fetch_row(res))) {
}
mysql_free_result(res);
- return (0);
+ return 0;
} /* mysql_read_wsrep_stats */
static int mysql_read(user_data_t *ud) {
if ((ud == NULL) || (ud->data == NULL)) {
ERROR("mysql plugin: mysql_database_read: Invalid user data.");
- return (-1);
+ return -1;
}
db = (mysql_database_t *)ud->data;
/* An error message will have been printed in this case */
if ((con = getconnection(db)) == NULL)
- return (-1);
+ return -1;
mysql_version = mysql_get_server_version(con);
res = exec_query(con, query);
if (res == NULL)
- return (-1);
+ return -1;
while ((row = mysql_fetch_row(res))) {
char *key;
if (db->wsrep_stats)
mysql_read_wsrep_stats(db, con);
- return (0);
+ return 0;
} /* int mysql_read */
void module_register(void) {
disk_t *d;
if ((cd == NULL) || (name == NULL))
- return (NULL);
+ return NULL;
for (d = cd->disks; d != NULL; d = d->next) {
if (strcmp(d->name, name) == 0)
d = calloc(1, sizeof(*d));
if (d == NULL)
- return (NULL);
+ return NULL;
d->next = NULL;
d->name = strdup(name);
if (d->name == NULL) {
sfree(d);
- return (NULL);
+ return NULL;
}
d->next = cd->disks;
int ignore_snapshot = 0;
if ((cvu == NULL) || (name == NULL))
- return (NULL);
+ return NULL;
last = cvu->volumes;
while (last != NULL) {
if (strcmp(last->name, name) == 0)
- return (last);
+ return last;
if (last->next == NULL)
break;
ignore_capacity = ignorelist_match(cvu->il_capacity, name);
ignore_snapshot = ignorelist_match(cvu->il_snapshot, name);
if ((ignore_capacity != 0) && (ignore_snapshot != 0))
- return (NULL);
+ return NULL;
/* Not found: allocate. */
new = calloc(1, sizeof(*new));
if (new == NULL)
- return (NULL);
+ return NULL;
new->next = NULL;
new->name = strdup(name);
if (new->name == NULL) {
sfree(new);
- return (NULL);
+ return NULL;
}
if (ignore_capacity == 0)
else
last->next = new;
- return (new);
+ return new;
} /* }}} data_volume_usage_t *get_volume_usage */
static data_volume_perf_t *get_volume_perf(cfg_volume_perf_t *cvp, /* {{{ */
int ignore_latency = 0;
if ((cvp == NULL) || (name == NULL))
- return (NULL);
+ return NULL;
last = cvp->volumes;
while (last != NULL) {
if (strcmp(last->name, name) == 0)
- return (last);
+ return last;
if (last->next == NULL)
break;
ignore_operations = ignorelist_match(cvp->il_operations, name);
ignore_latency = ignorelist_match(cvp->il_latency, name);
if ((ignore_octets != 0) || (ignore_operations != 0) || (ignore_latency != 0))
- return (NULL);
+ return NULL;
/* Not found: allocate. */
new = calloc(1, sizeof(*new));
if (new == NULL)
- return (NULL);
+ return NULL;
new->next = NULL;
new->name = strdup(name);
if (new->name == NULL) {
sfree(new);
- return (NULL);
+ return NULL;
}
if (ignore_octets == 0)
else
last->next = new;
- return (new);
+ return new;
} /* }}} data_volume_perf_t *get_volume_perf */
/*
if (type_inst != NULL)
sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance));
- return (plugin_dispatch_values(&vl));
+ return plugin_dispatch_values(&vl);
} /* }}} int submit_uint64 */
static int submit_two_derive(const char *host,
{.derive = val0}, {.derive = val1},
};
- return (submit_values(host, plugin_inst, type, type_inst, values,
- STATIC_ARRAY_SIZE(values), timestamp, interval));
+ return submit_values(host, plugin_inst, type, type_inst, values,
+ STATIC_ARRAY_SIZE(values), timestamp, interval);
} /* }}} int submit_two_derive */
static int submit_derive(const char *host, const char *plugin_inst, /* {{{ */
const char *type, const char *type_inst,
derive_t counter, cdtime_t timestamp,
cdtime_t interval) {
- return (submit_values(host, plugin_inst, type, type_inst,
- &(value_t){.derive = counter}, 1, timestamp, interval));
+ return submit_values(host, plugin_inst, type, type_inst,
+ &(value_t){
+ .derive = counter,
+ },
+ 1, timestamp, interval);
} /* }}} int submit_derive */
static int submit_two_gauge(const char *host, const char *plugin_inst, /* {{{ */
{.gauge = val0}, {.gauge = val1},
};
- return (submit_values(host, plugin_inst, type, type_inst, values,
- STATIC_ARRAY_SIZE(values), timestamp, interval));
+ return submit_values(host, plugin_inst, type, type_inst, values,
+ STATIC_ARRAY_SIZE(values), timestamp, interval);
} /* }}} int submit_two_gauge */
static int submit_double(const char *host, const char *plugin_inst, /* {{{ */
const char *type, const char *type_inst, double d,
cdtime_t timestamp, cdtime_t interval) {
- return (submit_values(host, plugin_inst, type, type_inst,
- &(value_t){.gauge = d}, 1, timestamp, interval));
+ return submit_values(host, plugin_inst, type, type_inst,
+ &(value_t){
+ .gauge = d,
+ },
+ 1, timestamp, interval);
} /* }}} int submit_uint64 */
/* Calculate hit ratio from old and new counters and submit the resulting
v.gauge = 100.0 * ((gauge_t)hits) / ((gauge_t)(hits + misses));
}
- return (submit_values(host, plugin_inst, "cache_ratio", type_inst, &v, 1,
- timestamp, interval));
+ return submit_values(host, plugin_inst, "cache_ratio", type_inst, &v, 1,
+ timestamp, interval);
} /* }}} int submit_cache_ratio */
/* Submits all the caches used by WAFL. Uses "submit_cache_ratio". */
/* Copy HAVE_* flags */
old_data->flags |= (new_data->flags & HAVE_WAFL_ALL);
- return (0);
+ return 0;
} /* }}} int submit_wafl_data */
/* Submits volume performance data to the daemon, taking care to honor and
char plugin_instance[DATA_MAX_NAME_LEN];
if ((hostname == NULL) || (old_data == NULL) || (new_data == NULL))
- return (-1);
+ return -1;
- ssnprintf(plugin_instance, sizeof(plugin_instance), "volume-%s",
- old_data->name);
+ snprintf(plugin_instance, sizeof(plugin_instance), "volume-%s",
+ old_data->name);
/* Check for and submit disk-octet values */
if (HAS_ALL_FLAGS(old_data->flags, CFG_VOLUME_PERF_IO) &&
- HAS_ALL_FLAGS(new_data->flags, HAVE_VOLUME_PERF_BYTES_READ |
- HAVE_VOLUME_PERF_BYTES_WRITE)) {
+ HAS_ALL_FLAGS(new_data->flags,
+ HAVE_VOLUME_PERF_BYTES_READ |
+ HAVE_VOLUME_PERF_BYTES_WRITE)) {
submit_two_derive(
hostname, plugin_instance, "disk_octets", /* type instance = */ NULL,
(derive_t)new_data->read_bytes, (derive_t)new_data->write_bytes,
}
/* Check for, calculate and submit disk-latency values */
- if (HAS_ALL_FLAGS(old_data->flags, CFG_VOLUME_PERF_LATENCY |
- HAVE_VOLUME_PERF_OPS_READ |
- HAVE_VOLUME_PERF_OPS_WRITE |
- HAVE_VOLUME_PERF_LATENCY_READ |
- HAVE_VOLUME_PERF_LATENCY_WRITE) &&
- HAS_ALL_FLAGS(new_data->flags, HAVE_VOLUME_PERF_OPS_READ |
- HAVE_VOLUME_PERF_OPS_WRITE |
- HAVE_VOLUME_PERF_LATENCY_READ |
- HAVE_VOLUME_PERF_LATENCY_WRITE)) {
+ if (HAS_ALL_FLAGS(old_data->flags,
+ CFG_VOLUME_PERF_LATENCY | HAVE_VOLUME_PERF_OPS_READ |
+ HAVE_VOLUME_PERF_OPS_WRITE |
+ HAVE_VOLUME_PERF_LATENCY_READ |
+ HAVE_VOLUME_PERF_LATENCY_WRITE) &&
+ HAS_ALL_FLAGS(new_data->flags,
+ HAVE_VOLUME_PERF_OPS_READ | HAVE_VOLUME_PERF_OPS_WRITE |
+ HAVE_VOLUME_PERF_LATENCY_READ |
+ HAVE_VOLUME_PERF_LATENCY_WRITE)) {
gauge_t latency_per_op_read;
gauge_t latency_per_op_write;
/* Copy the HAVE_* flags */
old_data->flags |= (new_data->flags & HAVE_VOLUME_PERF_ALL);
- return (0);
+ return 0;
} /* }}} int submit_volume_perf_data */
static cdtime_t cna_child_get_cdtime(na_elem_t *data) /* {{{ */
t = (time_t)na_child_get_uint64(data, "timestamp", /* default = */ 0);
- return (TIME_T_TO_CDTIME_T(t));
+ return TIME_T_TO_CDTIME_T(t);
} /* }}} cdtime_t cna_child_get_cdtime */
/*
"na_elem_child (\"instances\") failed "
"for host %s.",
hostname);
- return (-1);
+ return -1;
}
plugin_inst = na_child_get_string(instances, "name");
"na_child_get_string (\"name\") failed "
"for host %s.",
hostname);
- return (-1);
+ return -1;
}
/* Iterate over all counters */
}
}
- return (
- submit_wafl_data(hostname, plugin_inst, cfg_wafl, &perf_data, interval));
+ return submit_wafl_data(hostname, plugin_inst, cfg_wafl, &perf_data,
+ interval);
} /* }}} void cna_handle_wafl_data */
static int cna_setup_wafl(cfg_wafl_t *cw) /* {{{ */
na_elem_t *e;
if (cw == NULL)
- return (EINVAL);
+ return EINVAL;
if (cw->query != NULL)
- return (0);
+ return 0;
cw->query = na_elem_new("perf-object-get-instances");
if (cw->query == NULL) {
ERROR("netapp plugin: na_elem_new failed.");
- return (-1);
+ return -1;
}
na_child_add_string(cw->query, "objectname", "wafl");
na_elem_free(cw->query);
cw->query = NULL;
ERROR("netapp plugin: na_elem_new failed.");
- return (-1);
+ return -1;
}
na_child_add_string(e, "counter", "name_cache_hit");
na_child_add_string(e, "counter", "name_cache_miss");
na_child_add(cw->query, e);
- return (0);
+ return 0;
} /* }}} int cna_setup_wafl */
static int cna_query_wafl(host_config_t *host) /* {{{ */
cdtime_t now;
if (host == NULL)
- return (EINVAL);
+ return EINVAL;
/* If WAFL was not configured, return without doing anything. */
if (host->cfg_wafl == NULL)
- return (0);
+ return 0;
now = cdtime();
if ((host->cfg_wafl->interval.interval + host->cfg_wafl->interval.last_read) >
now)
- return (0);
+ return 0;
status = cna_setup_wafl(host->cfg_wafl);
if (status != 0)
- return (status);
+ return status;
assert(host->cfg_wafl->query != NULL);
data = na_server_invoke_elem(host->srv, host->cfg_wafl->query);
"host %s: %s",
host->name, na_results_reason(data));
na_elem_free(data);
- return (-1);
+ return -1;
}
status = cna_handle_wafl_data(host->name, host->cfg_wafl, data,
host->cfg_wafl->interval.last_read = now;
na_elem_free(data);
- return (status);
+ return status;
} /* }}} int cna_query_wafl */
/* Data corresponding to <Disks /> */
disk_t *worst_disk = NULL;
if ((cfg_disk == NULL) || (data == NULL))
- return (EINVAL);
+ return EINVAL;
timestamp = cna_child_get_cdtime(data);
"na_elem_child (\"instances\") failed "
"for host %s.",
hostname);
- return (-1);
+ return -1;
}
/* Iterate over all children */
submit_double(hostname, "system", "percent", "disk_busy",
worst_disk->disk_busy_percent, timestamp, interval);
- return (0);
+ return 0;
} /* }}} int cna_handle_disk_data */
static int cna_setup_disk(cfg_disk_t *cd) /* {{{ */
na_elem_t *e;
if (cd == NULL)
- return (EINVAL);
+ return EINVAL;
if (cd->query != NULL)
- return (0);
+ return 0;
cd->query = na_elem_new("perf-object-get-instances");
if (cd->query == NULL) {
ERROR("netapp plugin: na_elem_new failed.");
- return (-1);
+ return -1;
}
na_child_add_string(cd->query, "objectname", "disk");
na_elem_free(cd->query);
cd->query = NULL;
ERROR("netapp plugin: na_elem_new failed.");
- return (-1);
+ return -1;
}
na_child_add_string(e, "counter", "disk_busy");
na_child_add_string(e, "counter", "base_for_disk_busy");
na_child_add(cd->query, e);
- return (0);
+ return 0;
} /* }}} int cna_setup_disk */
static int cna_query_disk(host_config_t *host) /* {{{ */
cdtime_t now;
if (host == NULL)
- return (EINVAL);
+ return EINVAL;
/* If the user did not configure disk statistics, return without doing
* anything. */
if (host->cfg_disk == NULL)
- return (0);
+ return 0;
now = cdtime();
if ((host->cfg_disk->interval.interval + host->cfg_disk->interval.last_read) >
now)
- return (0);
+ return 0;
status = cna_setup_disk(host->cfg_disk);
if (status != 0)
- return (status);
+ return status;
assert(host->cfg_disk->query != NULL);
data = na_server_invoke_elem(host->srv, host->cfg_disk->query);
"host %s: %s",
host->name, na_results_reason(data));
na_elem_free(data);
- return (-1);
+ return -1;
}
status = cna_handle_disk_data(host->name, host->cfg_disk, data,
host->cfg_disk->interval.last_read = now;
na_elem_free(data);
- return (status);
+ return status;
} /* }}} int cna_query_disk */
/* Data corresponding to <VolumePerf /> */
"na_elem_child (\"instances\") failed "
"for host %s.",
hostname);
- return (-1);
+ return -1;
}
iter_instances = na_child_iterator(elem_instances);
submit_volume_perf_data(hostname, v, &perf_data, interval);
} /* for (volume) */
- return (0);
+ return 0;
} /* }}} int cna_handle_volume_perf_data */
static int cna_setup_volume_perf(cfg_volume_perf_t *cd) /* {{{ */
na_elem_t *e;
if (cd == NULL)
- return (EINVAL);
+ return EINVAL;
if (cd->query != NULL)
- return (0);
+ return 0;
cd->query = na_elem_new("perf-object-get-instances");
if (cd->query == NULL) {
ERROR("netapp plugin: na_elem_new failed.");
- return (-1);
+ return -1;
}
na_child_add_string(cd->query, "objectname", "volume");
na_elem_free(cd->query);
cd->query = NULL;
ERROR("netapp plugin: na_elem_new failed.");
- return (-1);
+ return -1;
}
na_child_add_string(e, "counter", "read_ops");
na_child_add_string(e, "counter", "write_ops");
na_child_add_string(e, "counter", "write_latency");
na_child_add(cd->query, e);
- return (0);
+ return 0;
} /* }}} int cna_setup_volume_perf */
static int cna_query_volume_perf(host_config_t *host) /* {{{ */
cdtime_t now;
if (host == NULL)
- return (EINVAL);
+ return EINVAL;
/* If the user did not configure volume performance statistics, return
* without doing anything. */
if (host->cfg_volume_perf == NULL)
- return (0);
+ return 0;
now = cdtime();
if ((host->cfg_volume_perf->interval.interval +
host->cfg_volume_perf->interval.last_read) > now)
- return (0);
+ return 0;
status = cna_setup_volume_perf(host->cfg_volume_perf);
if (status != 0)
- return (status);
+ return status;
assert(host->cfg_volume_perf->query != NULL);
data = na_server_invoke_elem(host->srv, host->cfg_volume_perf->query);
"for host %s: %s",
host->name, na_results_reason(data));
na_elem_free(data);
- return (-1);
+ return -1;
}
status =
host->cfg_volume_perf->interval.last_read = now;
na_elem_free(data);
- return (status);
+ return status;
} /* }}} int cna_query_volume_perf */
/* Data corresponding to <VolumeUsage /> */
uint64_t snap_reserve_free = v->snap_reserved;
uint64_t snap_norm_used = v->snap_used;
- ssnprintf(plugin_instance, sizeof(plugin_instance), "volume-%s", v->name);
+ snprintf(plugin_instance, sizeof(plugin_instance), "volume-%s", v->name);
- if (HAS_ALL_FLAGS(v->flags, HAVE_VOLUME_USAGE_SNAP_USED |
- HAVE_VOLUME_USAGE_SNAP_RSVD)) {
+ if (HAS_ALL_FLAGS(v->flags,
+ HAVE_VOLUME_USAGE_SNAP_USED |
+ HAVE_VOLUME_USAGE_SNAP_RSVD)) {
if (v->snap_reserved > v->snap_used) {
snap_reserve_free = v->snap_reserved - v->snap_used;
snap_reserve_used = v->snap_used;
/* The space used by snapshots but not reserved for them is included in
* both, norm_used and snap_norm_used. If possible, subtract this here. */
- if (HAS_ALL_FLAGS(v->flags, HAVE_VOLUME_USAGE_NORM_USED |
- HAVE_VOLUME_USAGE_SNAP_USED)) {
+ if (HAS_ALL_FLAGS(v->flags,
+ HAVE_VOLUME_USAGE_NORM_USED |
+ HAVE_VOLUME_USAGE_SNAP_USED)) {
if (norm_used >= snap_norm_used)
norm_used -= snap_norm_used;
else {
"df_complex", "snap_reserved", (double)snap_reserve_free,
/* timestamp = */ 0, interval);
- if (HAS_ALL_FLAGS(v->flags, HAVE_VOLUME_USAGE_SNAP_USED |
- HAVE_VOLUME_USAGE_SNAP_RSVD))
+ if (HAS_ALL_FLAGS(v->flags,
+ HAVE_VOLUME_USAGE_SNAP_USED |
+ HAVE_VOLUME_USAGE_SNAP_RSVD))
submit_double(hostname, /* plugin instance = */ plugin_instance,
"df_complex", "snap_reserve_used",
(double)snap_reserve_used, /* timestamp = */ 0, interval);
v->flags &= ~HAVE_VOLUME_USAGE_ALL;
} /* for (v = cfg_volume->volumes) */
- return (0);
+ return 0;
} /* }}} int cna_submit_volume_usage_data */
/* Switch the state of a volume between online and offline and send out a
if ((v->flags & IS_VOLUME_USAGE_OFFLINE) != 0) {
n.severity = NOTIF_OKAY;
- ssnprintf(n.message, sizeof(n.message), "Volume %s is now online.",
- v->name);
+ snprintf(n.message, sizeof(n.message), "Volume %s is now online.", v->name);
v->flags &= ~IS_VOLUME_USAGE_OFFLINE;
} else {
n.severity = NOTIF_WARNING;
- ssnprintf(n.message, sizeof(n.message), "Volume %s is now offline.",
- v->name);
+ snprintf(n.message, sizeof(n.message), "Volume %s is now offline.",
+ v->name);
v->flags |= IS_VOLUME_USAGE_OFFLINE;
}
- return (plugin_dispatch_notification(&n));
+ return plugin_dispatch_notification(&n);
} /* }}} int cna_change_volume_status */
static void cna_handle_volume_snap_usage(const host_config_t *host, /* {{{ */
"na_elem_child (\"volumes\") failed "
"for host %s.",
host->name);
- return (-1);
+ return -1;
}
iter_volume = na_child_iterator(elem_volumes);
}
} /* for (elem_volume) */
- return (cna_submit_volume_usage_data(
- host->name, cfg_volume, host->cfg_volume_usage->interval.interval));
+ return cna_submit_volume_usage_data(
+ host->name, cfg_volume, host->cfg_volume_usage->interval.interval);
} /* }}} int cna_handle_volume_usage_data */
static int cna_setup_volume_usage(cfg_volume_usage_t *cvu) /* {{{ */
{
if (cvu == NULL)
- return (EINVAL);
+ return EINVAL;
if (cvu->query != NULL)
- return (0);
+ return 0;
cvu->query = na_elem_new("volume-list-info");
if (cvu->query == NULL) {
ERROR("netapp plugin: na_elem_new failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cna_setup_volume_usage */
static int cna_query_volume_usage(host_config_t *host) /* {{{ */
cdtime_t now;
if (host == NULL)
- return (EINVAL);
+ return EINVAL;
/* If the user did not configure volume_usage statistics, return without
* doing anything. */
if (host->cfg_volume_usage == NULL)
- return (0);
+ return 0;
now = cdtime();
if ((host->cfg_volume_usage->interval.interval +
host->cfg_volume_usage->interval.last_read) > now)
- return (0);
+ return 0;
status = cna_setup_volume_usage(host->cfg_volume_usage);
if (status != 0)
- return (status);
+ return status;
assert(host->cfg_volume_usage->query != NULL);
data = na_server_invoke_elem(host->srv, host->cfg_volume_usage->query);
"for host %s: %s",
host->name, na_results_reason(data));
na_elem_free(data);
- return (-1);
+ return -1;
}
status = cna_handle_volume_usage_data(host, host->cfg_volume_usage, data);
host->cfg_volume_usage->interval.last_read = now;
na_elem_free(data);
- return (status);
+ return status;
} /* }}} int cna_query_volume_usage */
/* Data corresponding to <Quota /> */
"na_elem_child (\"quotas\") failed "
"for host %s.",
host->name);
- return (-1);
+ return -1;
}
iter_quota = na_child_iterator(elem_quotas);
if (volume_name == NULL)
continue;
- ssnprintf(plugin_instance, sizeof(plugin_instance), "quota-%s-%s",
- volume_name, tree_name);
+ snprintf(plugin_instance, sizeof(plugin_instance), "quota-%s-%s",
+ volume_name, tree_name);
value = na_child_get_uint64(elem_quota, "disk-used", UINT64_MAX);
if (value != UINT64_MAX) {
}
} /* for (elem_quota) */
- return (0);
+ return 0;
} /* }}} int cna_handle_volume_usage_data */
static int cna_setup_quota(cfg_quota_t *cq) /* {{{ */
{
if (cq == NULL)
- return (EINVAL);
+ return EINVAL;
if (cq->query != NULL)
- return (0);
+ return 0;
cq->query = na_elem_new("quota-report");
if (cq->query == NULL) {
ERROR("netapp plugin: na_elem_new failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cna_setup_quota */
static int cna_query_quota(host_config_t *host) /* {{{ */
cdtime_t now;
if (host == NULL)
- return (EINVAL);
+ return EINVAL;
/* If the user did not configure quota statistics, return without
* doing anything. */
if (host->cfg_quota == NULL)
- return (0);
+ return 0;
now = cdtime();
if ((host->cfg_quota->interval.interval +
host->cfg_quota->interval.last_read) > now)
- return (0);
+ return 0;
status = cna_setup_quota(host->cfg_quota);
if (status != 0)
- return (status);
+ return status;
assert(host->cfg_quota->query != NULL);
data = na_server_invoke_elem(host->srv, host->cfg_quota->query);
"host %s: %s",
host->name, na_results_reason(data));
na_elem_free(data);
- return (-1);
+ return -1;
}
status = cna_handle_quota_data(host, host->cfg_quota, data);
host->cfg_quota->interval.last_read = now;
na_elem_free(data);
- return (status);
+ return status;
} /* }}} int cna_query_quota */
/* Data corresponding to <SnapVault /> */
na_elem_t *status_list = na_elem_child(data, "status-list");
if (status_list == NULL) {
ERROR("netapp plugin: SnapVault status record missing status-list");
- return (0);
+ return 0;
}
na_elem_iter_t status_iter = na_child_iterator(status_list);
continue;
/* possible TODO: make plugin instance configurable */
- ssnprintf(plugin_instance, sizeof(plugin_instance), "snapvault-%s",
- dest_path);
+ snprintf(plugin_instance, sizeof(plugin_instance), "snapvault-%s",
+ dest_path);
submit_double(hostname, plugin_instance, /* type = */ "delay", NULL,
(double)value, /* timestamp = */ 0, interval);
}
} /* for (status) */
- return (0);
+ return 0;
} /* }}} int cna_handle_snapvault_data */
static int cna_handle_snapvault_iter(host_config_t *host, /* {{{ */
"na_server_invoke failed for host %s: %s",
host->name, na_results_reason(data));
na_elem_free(elem);
- return (-1);
+ return -1;
}
cna_handle_snapvault_data(host->name, host->cfg_snapvault, elem,
na_elem_free(na_server_invoke(
host->srv, "snapvault-secondary-relationship-status-list-iter-end", "tag",
tag, NULL));
- return (0);
+ return 0;
} /* }}} int cna_handle_snapvault_iter */
static int cna_setup_snapvault(cfg_snapvault_t *sv) /* {{{ */
{
if (sv == NULL)
- return (EINVAL);
+ return EINVAL;
if (sv->query != NULL)
- return (0);
+ return 0;
sv->query =
na_elem_new("snapvault-secondary-relationship-status-list-iter-start");
if (sv->query == NULL) {
ERROR("netapp plugin: na_elem_new failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int cna_setup_snapvault */
static int cna_query_snapvault(host_config_t *host) /* {{{ */
now = cdtime();
if ((host->cfg_snapvault->interval.interval +
host->cfg_snapvault->interval.last_read) > now)
- return (0);
+ return 0;
status = cna_setup_snapvault(host->cfg_snapvault);
if (status != 0)
- return (status);
+ return status;
assert(host->cfg_snapvault->query != NULL);
data = na_server_invoke_elem(host->srv, host->cfg_snapvault->query);
"for host %s: %s",
host->name, na_results_reason(data));
na_elem_free(data);
- return (-1);
+ return -1;
}
status = cna_handle_snapvault_iter(host, data);
host->cfg_snapvault->interval.last_read = now;
na_elem_free(data);
- return (status);
+ return status;
} /* }}} int cna_query_snapvault */
/* Data corresponding to <System /> */
"na_elem_child (\"instances\") failed "
"for host %s.",
hostname);
- return (-1);
+ return -1;
}
instance = na_child_get_string(instances, "name");
"na_child_get_string (\"name\") failed "
"for host %s.",
hostname);
- return (-1);
+ return -1;
}
counter_iter = na_child_iterator(na_elem_child(instances, "counters"));
timestamp, interval);
}
- return (0);
+ return 0;
} /* }}} int cna_handle_system_data */
static int cna_setup_system(cfg_system_t *cs) /* {{{ */
{
if (cs == NULL)
- return (EINVAL);
+ return EINVAL;
if (cs->query != NULL)
- return (0);
+ return 0;
cs->query = na_elem_new("perf-object-get-instances");
if (cs->query == NULL) {
ERROR("netapp plugin: na_elem_new failed.");
- return (-1);
+ return -1;
}
na_child_add_string(cs->query, "objectname", "system");
- return (0);
+ return 0;
} /* }}} int cna_setup_system */
static int cna_query_system(host_config_t *host) /* {{{ */
cdtime_t now;
if (host == NULL)
- return (EINVAL);
+ return EINVAL;
/* If system statistics were not configured, return without doing anything. */
if (host->cfg_system == NULL)
- return (0);
+ return 0;
now = cdtime();
if ((host->cfg_system->interval.interval +
host->cfg_system->interval.last_read) > now)
- return (0);
+ return 0;
status = cna_setup_system(host->cfg_system);
if (status != 0)
- return (status);
+ return status;
assert(host->cfg_system->query != NULL);
data = na_server_invoke_elem(host->srv, host->cfg_system->query);
"host %s: %s",
host->name, na_results_reason(data));
na_elem_free(data);
- return (-1);
+ return -1;
}
status = cna_handle_system_data(host->name, host->cfg_system, data,
host->cfg_system->interval.last_read = now;
na_elem_free(data);
- return (status);
+ return status;
} /* }}} int cna_query_system */
/*
static int cna_config_bool_to_flag(const oconfig_item_t *ci, /* {{{ */
uint32_t *flags, uint32_t flag) {
if ((ci == NULL) || (flags == NULL))
- return (EINVAL);
+ return EINVAL;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) {
WARNING("netapp plugin: The %s option needs exactly one boolean argument.",
ci->key);
- return (-1);
+ return -1;
}
if (ci->values[0].value.boolean)
else
*flags &= ~flag;
- return (0);
+ return 0;
} /* }}} int cna_config_bool_to_flag */
/* Handling of the "Interval" option which is allowed in every block. */
status = cf_util_get_cdtime(ci, &tmp);
if (status != 0)
- return (status);
+ return status;
out_interval->interval = tmp;
out_interval->last_read = 0;
- return (0);
+ return 0;
} /* }}} int cna_config_get_interval */
/* Handling of the "GetIO", "GetOps" and "GetLatency" options within a
cfg_volume_perf_t *cfg_volume_perf;
if ((host == NULL) || (ci == NULL))
- return (EINVAL);
+ return EINVAL;
if (host->cfg_volume_perf == NULL) {
cfg_volume_perf = calloc(1, sizeof(*cfg_volume_perf));
if (cfg_volume_perf == NULL)
- return (ENOMEM);
+ return ENOMEM;
/* Set default flags */
cfg_volume_perf->query = NULL;
cfg_volume_perf->il_octets = ignorelist_create(/* invert = */ 1);
if (cfg_volume_perf->il_octets == NULL) {
sfree(cfg_volume_perf);
- return (ENOMEM);
+ return ENOMEM;
}
cfg_volume_perf->il_operations = ignorelist_create(/* invert = */ 1);
if (cfg_volume_perf->il_operations == NULL) {
ignorelist_free(cfg_volume_perf->il_octets);
sfree(cfg_volume_perf);
- return (ENOMEM);
+ return ENOMEM;
}
cfg_volume_perf->il_latency = ignorelist_create(/* invert = */ 1);
ignorelist_free(cfg_volume_perf->il_octets);
ignorelist_free(cfg_volume_perf->il_operations);
sfree(cfg_volume_perf);
- return (ENOMEM);
+ return ENOMEM;
}
host->cfg_volume_perf = cfg_volume_perf;
item->key);
}
- return (0);
+ return 0;
} /* }}} int cna_config_volume_performance */
/* Handling of the "GetCapacity" and "GetSnapshot" options within a
cfg_quota_t *cfg_quota;
if ((host == NULL) || (ci == NULL))
- return (EINVAL);
+ return EINVAL;
if (host->cfg_quota == NULL) {
cfg_quota = calloc(1, sizeof(*cfg_quota));
if (cfg_quota == NULL)
- return (ENOMEM);
+ return ENOMEM;
cfg_quota->query = NULL;
host->cfg_quota = cfg_quota;
item->key);
}
- return (0);
+ return 0;
} /* }}} int cna_config_quota */
/* Corresponds to a <Disks /> block */
cfg_disk_t *cfg_disk;
if ((host == NULL) || (ci == NULL))
- return (EINVAL);
+ return EINVAL;
if (host->cfg_disk == NULL) {
cfg_disk = calloc(1, sizeof(*cfg_disk));
if (cfg_disk == NULL)
- return (ENOMEM);
+ return ENOMEM;
/* Set default flags */
cfg_disk->flags = CFG_DISK_ALL;
host->cfg_disk = NULL;
}
- return (0);
+ return 0;
} /* }}} int cna_config_disk */
/* Corresponds to a <WAFL /> block */
cfg_wafl_t *cfg_wafl;
if ((host == NULL) || (ci == NULL))
- return (EINVAL);
+ return EINVAL;
if (host->cfg_wafl == NULL) {
cfg_wafl = calloc(1, sizeof(*cfg_wafl));
if (cfg_wafl == NULL)
- return (ENOMEM);
+ return ENOMEM;
/* Set default flags */
cfg_wafl->flags = CFG_WAFL_ALL;
host->cfg_wafl = NULL;
}
- return (0);
+ return 0;
} /* }}} int cna_config_wafl */
/*
cfg_volume_usage_t *cfg_volume_usage;
if ((host == NULL) || (ci == NULL))
- return (EINVAL);
+ return EINVAL;
if (host->cfg_volume_usage == NULL) {
cfg_volume_usage = calloc(1, sizeof(*cfg_volume_usage));
if (cfg_volume_usage == NULL)
- return (ENOMEM);
+ return ENOMEM;
/* Set default flags */
cfg_volume_usage->query = NULL;
cfg_volume_usage->il_capacity = ignorelist_create(/* invert = */ 1);
if (cfg_volume_usage->il_capacity == NULL) {
sfree(cfg_volume_usage);
- return (ENOMEM);
+ return ENOMEM;
}
cfg_volume_usage->il_snapshot = ignorelist_create(/* invert = */ 1);
if (cfg_volume_usage->il_snapshot == NULL) {
ignorelist_free(cfg_volume_usage->il_capacity);
sfree(cfg_volume_usage);
- return (ENOMEM);
+ return ENOMEM;
}
host->cfg_volume_usage = cfg_volume_usage;
item->key);
}
- return (0);
+ return 0;
} /* }}} int cna_config_volume_usage */
/* Corresponds to a <SnapVault /> block */
cfg_system_t *cfg_system;
if ((host == NULL) || (ci == NULL))
- return (EINVAL);
+ return EINVAL;
if (host->cfg_system == NULL) {
cfg_system = calloc(1, sizeof(*cfg_system));
if (cfg_system == NULL)
- return (ENOMEM);
+ return ENOMEM;
/* Set default flags */
cfg_system->flags = CFG_SYSTEM_ALL;
host->cfg_system = NULL;
}
- return (0);
+ return 0;
} /* }}} int cna_config_system */
/* Corresponds to a <Host /> block. */
host = calloc(1, sizeof(*host));
if (host == NULL)
- return (NULL);
+ return NULL;
host->name = NULL;
host->protocol = NA_SERVER_TRANSPORT_HTTPS;
host->cfg_snapvault = NULL;
host->cfg_system = NULL;
- return (host);
+ return host;
} /* }}} host_config_t *cna_alloc_host */
static host_config_t *cna_shallow_clone_host(host_config_t *host) /* {{{ */
host_config_t *clone;
if (host == NULL)
- return (NULL);
+ return NULL;
clone = cna_alloc_host();
if (clone == NULL)
- return (NULL);
+ return NULL;
if (host->name != NULL) {
clone->name = strdup(host->name);
clone->interval = host->interval;
- return (clone);
+ return clone;
} /* }}} host_config_t *cna_shallow_clone_host */
static int cna_read(user_data_t *ud);
char cb_name[256];
if (host->vfiler)
- ssnprintf(cb_name, sizeof(cb_name), "netapp-%s-%s", host->name,
- host->vfiler);
+ snprintf(cb_name, sizeof(cb_name), "netapp-%s-%s", host->name,
+ host->vfiler);
else
- ssnprintf(cb_name, sizeof(cb_name), "netapp-%s", host->name);
+ snprintf(cb_name, sizeof(cb_name), "netapp-%s", host->name);
plugin_register_complex_read(
/* group = */ NULL, cb_name,
.data = host, .free_func = (void *)free_host_config,
});
- return (0);
+ return 0;
} /* }}} int cna_register_host */
static int cna_config_host(host_config_t *host, /* {{{ */
WARNING("netapp plugin: \"%s\" needs exactly one string argument. Ignoring "
"host block.",
ci->key);
- return (1);
+ return 1;
}
status = cf_util_get_string(ci, &host->name);
if (status != 0)
- return (1);
+ return 1;
for (int i = 0; i < ci->children_num; ++i) {
item = ci->children + i;
WARNING("netapp plugin: \"Protocol\" needs to be either \"http\" or "
"\"https\". Ignoring host block \"%s\".",
ci->values[0].value.string);
- return (1);
+ return 1;
}
if (!strcasecmp(item->values[0].value.string, "http"))
host->protocol = NA_SERVER_TRANSPORT_HTTP;
if (status != 0)
return status;
- return (0);
+ return 0;
} /* }}} host_config_t *cna_config_host */
/*
int major_version = 1, minor_version = 1;
if (host == NULL)
- return (EINVAL);
+ return EINVAL;
if (host->srv != NULL)
- return (0);
+ return 0;
if (host->vfiler != NULL) /* Request version 1.7 of the ONTAP API */
minor_version = 7;
host->srv = na_server_open(host->host, major_version, minor_version);
if (host->srv == NULL) {
ERROR("netapp plugin: na_server_open (%s) failed.", host->host);
- return (-1);
+ return -1;
}
na_server_set_transport_type(host->srv, host->protocol,
if (!na_server_set_vfiler(host->srv, host->vfiler)) {
ERROR("netapp plugin: Failed to connect to VFiler '%s' on host '%s'.",
host->vfiler, host->host);
- return (-1);
+ return -1;
} else {
INFO("netapp plugin: Connected to VFiler '%s' on host '%s'.",
host->vfiler, host->host);
}
}
- return (0);
+ return 0;
} /* }}} int cna_init_host */
static int cna_init(void) /* {{{ */
return 1;
}
- return (0);
+ return 0;
} /* }}} cna_init */
static int cna_read_internal(host_config_t *host) { /* {{{ */
status = cna_query_wafl(host);
if (status != 0)
- return (status);
+ return status;
status = cna_query_disk(host);
if (status != 0)
- return (status);
+ return status;
status = cna_query_volume_perf(host);
if (status != 0)
- return (status);
+ return status;
status = cna_query_volume_usage(host);
if (status != 0)
- return (status);
+ return status;
status = cna_query_quota(host);
if (status != 0)
- return (status);
+ return status;
status = cna_query_snapvault(host);
if (status != 0)
- return (status);
+ return status;
status = cna_query_system(host);
if (status != 0)
- return (status);
+ return status;
return 0;
} /* }}} int cna_read_internal */
int status;
if ((ud == NULL) || (ud->data == NULL))
- return (-1);
+ return -1;
host = ud->data;
status = cna_init_host(host);
if (status != 0)
- return (status);
+ return status;
status = cna_read_internal(host);
if (status != 0) {
/* Clean up system resources and stuff. */
na_shutdown();
- return (0);
+ return 0;
} /* }}} int cna_shutdown */
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 : */
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;
entry = calloc(1, sizeof(*entry));
if (entry == NULL)
- return (-1);
+ return -1;
if (strcasecmp(dev, "All") != 0) {
entry->device = strdup(dev);
if (entry->device == NULL) {
sfree(entry);
- return (-1);
+ return -1;
}
}
if (entry->type == NULL) {
sfree(entry->device);
sfree(entry);
- return (-1);
+ return -1;
}
if (inst != NULL) {
sfree(entry->type);
sfree(entry->device);
sfree(entry);
- return (-1);
+ return -1;
}
}
entry->next = ir_ignorelist_head;
ir_ignorelist_head = entry;
- return (0);
+ return 0;
} /* int add_ignorelist */
/*
assert((dev != NULL) && (type != NULL));
if (ir_ignorelist_head == NULL)
- return (ir_ignorelist_invert ? 0 : 1);
+ return ir_ignorelist_invert ? 0 : 1;
for (ir_ignorelist_t *i = ir_ignorelist_head; i != NULL; i = i->next) {
/* i->device == NULL => match all devices */
i->device == NULL ? "(nil)" : i->device, i->type,
i->inst == NULL ? "(nil)" : i->inst);
- return (ir_ignorelist_invert ? 0 : 1);
+ return ir_ignorelist_invert ? 0 : 1;
} /* for i */
- return (ir_ignorelist_invert);
+ return ir_ignorelist_invert;
} /* int check_ignorelist */
static void submit_one(const char *dev, const char *type,
temp = realloc(iflist, (msg->ifi_index + 1) * sizeof(char *));
if (temp == NULL) {
ERROR("netlink plugin: update_iflist: realloc failed.");
- return (-1);
+ return -1;
}
memset(temp + iflist_len, '\0',
iflist[msg->ifi_index] = strdup(dev);
}
- return (0);
+ return 0;
} /* int update_iflist */
static void check_ignorelist_and_submit(const char *dev,
#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) {
char errbuf[1024];
ERROR("netlink plugin: qos_attr_cb: TCA_STATS_BASIC mnl_attr_validate2 "
"failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
return MNL_CB_ERROR;
}
- *bs = mnl_attr_get_payload(attr);
- return MNL_CB_STOP;
+ q_stats->bs = mnl_attr_get_payload(attr);
+ return MNL_CB_OK;
+ }
+
+ if (mnl_attr_get_type(attr) == TCA_STATS_QUEUE) {
+ if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC, sizeof(*q_stats->qs)) < 0) {
+ ERROR("netlink plugin: qos_attr_cb: TCA_STATS_QUEUE mnl_attr_validate2 "
+ "failed.");
+ return MNL_CB_ERROR;
+ }
+ q_stats->qs = mnl_attr_get_payload(attr);
+ return MNL_CB_OK;
}
return MNL_CB_OK;
if (kind == NULL) {
ERROR("netlink plugin: qos_filter_cb: kind == NULL");
- return (-1);
+ return -1;
}
{ /* The ID */
if (strcmp(tc_type, "filter") == 0)
numberic_id = tm->tcm_parent;
- ssnprintf(tc_inst, sizeof(tc_inst), "%s-%x:%x", kind, numberic_id >> 16,
- numberic_id & 0x0000FFFF);
+ snprintf(tc_inst, sizeof(tc_inst), "%s-%x:%x", kind, numberic_id >> 16,
+ numberic_id & 0x0000FFFF);
}
DEBUG("netlink plugin: qos_filter_cb: got %s for %s (%i).", tc_type, dev,
#if HAVE_TCA_STATS2
mnl_attr_for_each(attr, nlh, sizeof(*tm)) {
- struct gnet_stats_basic *bs = NULL;
+ struct qos_stats q_stats;
+
+ memset(&q_stats, 0x0, sizeof(q_stats));
if (mnl_attr_get_type(attr) != TCA_STATS2)
continue;
return MNL_CB_ERROR;
}
- mnl_attr_parse_nested(attr, qos_attr_cb, &bs);
+ mnl_attr_parse_nested(attr, qos_attr_cb, &q_stats);
- if (bs != NULL) {
+ if (q_stats.bs != NULL || q_stats.qs != NULL) {
char type_instance[DATA_MAX_NAME_LEN];
stats_submitted = 1;
- ssnprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type,
- tc_inst);
+ snprintf(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;
if (!stats_submitted && ts != NULL) {
char type_instance[DATA_MAX_NAME_LEN];
- ssnprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type,
- tc_inst);
+ snprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type, tc_inst);
submit_one(dev, "ipt_bytes", type_instance, ts->bytes);
submit_one(dev, "ipt_packets", type_instance, ts->packets);
new_val = strdup(value);
if (new_val == NULL)
- return (-1);
+ return -1;
fields_num = strsplit(new_val, fields, STATIC_ARRAY_SIZE(fields));
if ((fields_num < 1) || (fields_num > 8)) {
sfree(new_val);
- return (-1);
+ return -1;
}
if ((strcasecmp(key, "Interface") == 0) ||
ERROR("netlink plugin: Invalid number of fields for option "
"`%s'. Got %i, expected 1 or 2.",
key, fields_num);
- return (-1);
+ return -1;
} else {
add_ignorelist(fields[0], key, (fields_num == 2) ? fields[1] : NULL);
status = 0;
sfree(new_val);
- return (status);
+ return status;
} /* int ir_config */
static int ir_init(void) {
nl = mnl_socket_open(NETLINK_ROUTE);
if (nl == NULL) {
ERROR("netlink plugin: ir_init: mnl_socket_open failed.");
- return (-1);
+ return -1;
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
ERROR("netlink plugin: ir_init: mnl_socket_bind failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int ir_init */
static int ir_read(void) {
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
ERROR("netlink plugin: ir_read: rtnl_wilddump_request failed.");
- return (-1);
+ return -1;
}
ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
} /* for (type_index) */
} /* for (if_index) */
- return (0);
+ return 0;
} /* int ir_read */
static int ir_shutdown(void) {
nl = NULL;
}
- return (0);
+ return 0;
} /* int ir_shutdown */
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 :
- */
#include <net/if.h>
#endif
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
#if defined __APPLE__
/* default xcode compiler throws warnings even when deprecated functionality
* is not used. -Werror breaks the build because of erroneous warnings.
* 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
int fd;
struct sockaddr_storage *addr;
socklen_t addrlen;
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
int security_level;
char *username;
char *password;
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;
/* This is a value we already sent. Don't allow it to be received again in
* order to avoid looping. */
if ((status == 0) && (time_sent >= ((uint64_t)vl->time)))
- return (0);
+ return 0;
- return (1);
+ return 1;
} /* }}} _Bool check_receive_okay */
static _Bool check_send_okay(const value_list_t *vl) /* {{{ */
int status;
if (network_config_forward)
- return (1);
+ return 1;
if (vl->meta == NULL)
- return (1);
+ return 1;
status = meta_data_get_boolean(vl->meta, "network:received", &received);
if (status == -ENOENT)
- return (1);
+ return 1;
else if (status != 0) {
ERROR("network plugin: check_send_okay: meta_data_get_boolean failed "
"with status %i.",
status);
- return (1);
+ return 1;
}
/* By default, only *send* value lists that were not *received* by the
* network plugin. */
- return (!received);
+ return !received;
} /* }}} _Bool check_send_okay */
static _Bool check_notify_received(const notification_t *n) /* {{{ */
for (notification_meta_t *ptr = n->meta; ptr != NULL; ptr = ptr->next)
if ((strcmp("network:received", ptr->name) == 0) &&
(ptr->type == NM_TYPE_BOOLEAN))
- return ((_Bool)ptr->nm_value.nm_boolean);
+ return (_Bool)ptr->nm_value.nm_boolean;
- return (0);
+ return 0;
} /* }}} _Bool check_notify_received */
static _Bool check_send_notify_okay(const notification_t *n) /* {{{ */
_Bool received = 0;
if (n->meta == NULL)
- return (1);
+ return 1;
received = check_notify_received(n);
/* By default, only *send* value lists that were not *received* by the
* network plugin. */
- return (!received);
+ return !received;
} /* }}} _Bool check_send_notify_okay */
static int network_dispatch_values(value_list_t *vl, /* {{{ */
if ((vl->time == 0) || (strlen(vl->host) == 0) || (strlen(vl->plugin) == 0) ||
(strlen(vl->type) == 0))
- return (-EINVAL);
+ return -EINVAL;
if (!check_receive_okay(vl)) {
#if COLLECT_DEBUG
name);
#endif
stats_values_not_dispatched++;
- return (0);
+ return 0;
}
assert(vl->meta == NULL);
vl->meta = meta_data_create();
if (vl->meta == NULL) {
ERROR("network plugin: meta_data_create failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
status = meta_data_add_boolean(vl->meta, "network:received", 1);
ERROR("network plugin: meta_data_add_boolean failed.");
meta_data_destroy(vl->meta);
vl->meta = NULL;
- return (status);
+ return status;
}
if (username != NULL) {
ERROR("network plugin: meta_data_add_string failed.");
meta_data_destroy(vl->meta);
vl->meta = NULL;
- return (status);
+ return status;
}
}
meta_data_destroy(vl->meta);
vl->meta = NULL;
- return (0);
+ return 0;
} /* }}} int network_dispatch_values */
static int network_dispatch_notification(notification_t *n) /* {{{ */
ERROR("network plugin: plugin_notification_meta_add_boolean failed.");
plugin_notification_meta_free(n->meta);
n->meta = NULL;
- return (status);
+ return status;
}
status = plugin_dispatch_notification(n);
plugin_notification_meta_free(n->meta);
n->meta = NULL;
- return (status);
+ return status;
} /* }}} int network_dispatch_notification */
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
static int network_init_gcrypt(void) /* {{{ */
{
gcry_error_t err;
* Because you can't know in a library whether another library has
* already initialized the library */
if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P))
- return (0);
+ return 0;
/* http://www.gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
* To ensure thread-safety, it's important to set GCRYCTL_SET_THREAD_CBS
if (err) {
ERROR("network plugin: gcry_control (GCRYCTL_SET_THREAD_CBS) failed: %s",
gcry_strerror(err));
- return (-1);
+ return -1;
}
#endif
if (err) {
ERROR("network plugin: gcry_control (GCRYCTL_INIT_SECMEM) failed: %s",
gcry_strerror(err));
- return (-1);
+ return -1;
}
gcry_control(GCRYCTL_INITIALIZATION_FINISHED);
- return (0);
+ return 0;
} /* }}} int network_init_gcrypt */
static gcry_cipher_hd_t network_get_aes256_cypher(sockent_t *se, /* {{{ */
cyper_ptr = &se->data.server.cypher;
if (username == NULL)
- return (NULL);
+ return NULL;
secret = fbh_get(se->data.server.userdb, username);
if (secret == NULL)
- return (NULL);
+ return NULL;
gcry_md_hash_buffer(GCRY_MD_SHA256, password_hash, secret, strlen(secret));
ERROR("network plugin: gcry_cipher_open returned: %s",
gcry_strerror(err));
*cyper_ptr = NULL;
- return (NULL);
+ return NULL;
}
} else {
gcry_cipher_reset(*cyper_ptr);
gcry_strerror(err));
gcry_cipher_close(*cyper_ptr);
*cyper_ptr = NULL;
- return (NULL);
+ return NULL;
}
err = gcry_cipher_setiv(*cyper_ptr, iv, iv_size);
gcry_strerror(err));
gcry_cipher_close(*cyper_ptr);
*cyper_ptr = NULL;
- return (NULL);
+ return NULL;
}
- return (*cyper_ptr);
+ 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) {
(num_values * sizeof(uint8_t)) + (num_values * sizeof(value_t));
if (*ret_buffer_len < packet_len)
- return (-1);
+ return -1;
pkg_values_types = malloc(num_values * sizeof(*pkg_values_types));
if (pkg_values_types == NULL) {
ERROR("network plugin: write_part_values: malloc failed.");
- return (-1);
+ return -1;
}
pkg_values = malloc(num_values * sizeof(*pkg_values));
if (pkg_values == NULL) {
free(pkg_values_types);
ERROR("network plugin: write_part_values: malloc failed.");
- return (-1);
+ return -1;
}
pkg_ph.type = htons(TYPE_VALUES);
ERROR("network plugin: write_part_values: "
"Unknown data source type: %i",
ds->ds[i].type);
- return (-1);
+ return -1;
} /* switch (ds->ds[i].type) */
} /* for (num_values) */
free(pkg_values_types);
free(pkg_values);
- return (0);
+ return 0;
} /* int write_part_values */
static int write_part_number(char **ret_buffer, size_t *ret_buffer_len,
packet_len = sizeof(pkg_head) + sizeof(pkg_value);
if (*ret_buffer_len < packet_len)
- return (-1);
+ return -1;
pkg_head.type = htons(type);
pkg_head.length = htons(packet_len);
*ret_buffer = packet_ptr + packet_len;
*ret_buffer_len -= packet_len;
- return (0);
+ return 0;
} /* int write_part_number */
static int write_part_string(char **ret_buffer, size_t *ret_buffer_len,
buffer_len = 2 * sizeof(uint16_t) + str_len + 1;
if (*ret_buffer_len < buffer_len)
- return (-1);
+ return -1;
pkg_type = htons(type);
pkg_length = htons(buffer_len);
*ret_buffer = buffer + buffer_len;
*ret_buffer_len -= buffer_len;
- return (0);
+ return 0;
} /* int write_part_string */
static int parse_part_values(void **ret_buffer, size_t *ret_buffer_len,
NOTICE("network plugin: packet is too short: "
"buffer_len = %zu",
buffer_len);
- return (-1);
+ return -1;
}
memcpy((void *)&tmp16, buffer, sizeof(tmp16));
"Chunk of size %zu expected, "
"but buffer has only %zu bytes left.",
exp_size, buffer_len);
- return (-1);
+ return -1;
}
assert(pkg_numval <= ((buffer_len - 6) / 9));
WARNING("network plugin: parse_part_values: "
"Length and number of values "
"in the packet don't match.");
- return (-1);
+ return -1;
}
pkg_types = calloc(pkg_numval, sizeof(*pkg_types));
sfree(pkg_types);
sfree(pkg_values);
ERROR("network plugin: parse_part_values: calloc failed.");
- return (-1);
+ return -1;
}
memcpy(pkg_types, buffer, pkg_numval * sizeof(*pkg_types));
pkg_types[i]);
sfree(pkg_types);
sfree(pkg_values);
- return (-1);
+ return -1;
} /* switch (pkg_types[i]) */
}
sfree(pkg_types);
- return (0);
+ return 0;
} /* int parse_part_values */
static int parse_part_number(void **ret_buffer, size_t *ret_buffer_len,
"Chunk of size %zu expected, "
"but buffer has only %zu bytes left.",
exp_size, buffer_len);
- return (-1);
+ return -1;
}
memcpy((void *)&tmp16, buffer, sizeof(tmp16));
*ret_buffer = buffer;
*ret_buffer_len = buffer_len - pkg_length;
- return (0);
+ return 0;
} /* int parse_part_number */
static int parse_part_string(void **ret_buffer, size_t *ret_buffer_len,
size_t payload_size;
if (output_len == 0)
- return (EINVAL);
+ return EINVAL;
if (buffer_len < header_size) {
WARNING("network plugin: parse_part_string: "
"Chunk of at least size %zu expected, "
"but buffer has only %zu bytes left.",
header_size, buffer_len);
- return (-1);
+ return -1;
}
memcpy((void *)&tmp16, buffer, sizeof(tmp16));
"Chunk of size %" PRIu16 " received, "
"but buffer has only %zu bytes left.",
pkg_length, buffer_len);
- return (-1);
+ return -1;
}
/* Check that pkg_length is in the valid range */
"Header claims this packet is only %hu "
"bytes long.",
pkg_length);
- return (-1);
+ return -1;
}
/* Check that the package data fits into the output buffer.
"which is too small to hold the received "
"%zu byte string.",
output_len, payload_size);
- return (-1);
+ return -1;
}
/* All sanity checks successfull, let's copy the data over */
WARNING("network plugin: parse_part_string: "
"Received string does not end "
"with a NULL-byte.");
- return (-1);
+ return -1;
}
*ret_buffer = buffer;
*ret_buffer_len = buffer_len - pkg_length;
- return (0);
+ return 0;
} /* int parse_part_string */
/* Forward declaration: parse_part_sign_sha256 and parse_part_encr_aes256 call
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) {
/* Check if the buffer has enough data for this structure. */
if (buffer_len <= PART_SIGNATURE_SHA256_SIZE)
- return (-ENOMEM);
+ return -ENOMEM;
/* Read type and length header */
BUFFER_READ(&pss.head.type, sizeof(pss.head.type));
if ((pss_head_length <= PART_SIGNATURE_SHA256_SIZE) ||
(pss_head_length > buffer_len)) {
ERROR("network plugin: HMAC-SHA-256 with invalid length received.");
- return (-1);
+ return -1;
}
if (se->data.server.userdb == NULL) {
*ret_buffer = buffer + pss_head_length;
*ret_buffer_len -= pss_head_length;
- return (0);
+ return 0;
}
/* Copy the hash. */
username_len = pss_head_length - PART_SIGNATURE_SHA256_SIZE;
pss.username = malloc(username_len + 1);
if (pss.username == NULL)
- return (-ENOMEM);
+ return -ENOMEM;
/* Read the username */
BUFFER_READ(pss.username, username_len);
if (secret == NULL) {
ERROR("network plugin: Unknown user: %s", pss.username);
sfree(pss.username);
- return (-ENOENT);
+ return -ENOENT;
}
/* Create a hash device and check the HMAC */
gcry_strerror(err));
sfree(secret);
sfree(pss.username);
- return (-1);
+ return -1;
}
err = gcry_md_setkey(hd, secret, strlen(secret));
gcry_md_close(hd);
sfree(secret);
sfree(pss.username);
- return (-1);
+ return -1;
}
gcry_md_write(hd, buffer + PART_SIGNATURE_SHA256_SIZE,
gcry_md_close(hd);
sfree(secret);
sfree(pss.username);
- return (-1);
+ return -1;
}
memcpy(hash, hash_ptr, sizeof(hash));
*ret_buffer = buffer + buffer_len;
*ret_buffer_len = 0;
- return (0);
+ 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) {
buffer_offset = 0;
if (buffer_size <= PART_SIGNATURE_SHA256_SIZE)
- return (-ENOMEM);
+ return -ENOMEM;
BUFFER_READ(&pss.head.type, sizeof(pss.head.type));
BUFFER_READ(&pss.head.length, sizeof(pss.head.length));
part_len = ntohs(pss.head.length);
if ((part_len <= PART_SIGNATURE_SHA256_SIZE) || (part_len > buffer_size))
- return (-EINVAL);
+ return -EINVAL;
if (warning_has_been_printed == 0) {
WARNING("network plugin: Received signed packet, but the network "
*ret_buffer = buffer + buffer_size;
*ret_buffer_size = 0;
- return (0);
+ 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) {
if (buffer_len <= PART_ENCRYPTION_AES256_SIZE) {
NOTICE("network plugin: parse_part_encr_aes256: "
"Discarding short packet.");
- return (-1);
+ return -1;
}
buffer_offset = 0;
if ((part_size <= PART_ENCRYPTION_AES256_SIZE) || (part_size > buffer_len)) {
NOTICE("network plugin: parse_part_encr_aes256: "
"Discarding part with invalid size.");
- return (-1);
+ return -1;
}
/* Read the username */
(username_len > (part_size - (PART_ENCRYPTION_AES256_SIZE + 1)))) {
NOTICE("network plugin: parse_part_encr_aes256: "
"Discarding part with invalid username length.");
- return (-1);
+ return -1;
}
assert(username_len > 0);
pea.username = malloc(username_len + 1);
if (pea.username == NULL)
- return (-ENOMEM);
+ return -ENOMEM;
BUFFER_READ(pea.username, username_len);
pea.username[username_len] = 0;
if (cypher == NULL) {
ERROR("network plugin: Failed to get cypher. Username: %s", pea.username);
sfree(pea.username);
- return (-1);
+ return -1;
}
payload_len = part_size - (PART_ENCRYPTION_AES256_SIZE + username_len);
ERROR("network plugin: gcry_cipher_decrypt returned: %s. Username: %s",
gcry_strerror(err), pea.username);
sfree(pea.username);
- return (-1);
+ return -1;
}
/* Read the hash */
if (memcmp(hash, pea.hash, sizeof(hash)) != 0) {
ERROR("network plugin: Checksum mismatch. Username: %s", pea.username);
sfree(pea.username);
- return (-1);
+ return -1;
}
parse_packet(se, buffer + buffer_offset, payload_len, flags | PP_ENCRYPTED,
sfree(pea.username);
- return (0);
+ 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) {
if ((ph_length <= PART_ENCRYPTION_AES256_SIZE) || (ph_length > buffer_size)) {
ERROR("network plugin: AES-256 encrypted part "
"with invalid length received.");
- return (-1);
+ return -1;
}
if (warning_has_been_printed == 0) {
*ret_buffer = (void *)(((char *)*ret_buffer) + ph_length);
*ret_buffer_size -= ph_length;
- return (0);
+ return 0;
} /* }}} int parse_part_encr_aes256 */
-#endif /* !HAVE_LIBGCRYPT */
+#endif /* !HAVE_GCRYPT_H */
#undef BUFFER_READ
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;
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) {
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) {
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) {
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);
WARNING("network plugin: parse_packet: Received truncated "
"packet, try increasing `MaxPacketSize'");
- return (status);
+ return status;
} /* }}} int parse_packet */
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)
}
sfree(ses->fd);
-#if HAVE_LIBGCRYPT
+#if HAVE_GCRYPT_H
sfree(ses->auth_file);
fbh_destroy(ses->userdb);
if (ses->cypher != NULL)
assert(se->type == SOCKENT_TYPE_CLIENT);
if ((network_config_ttl < 1) || (network_config_ttl > 255))
- return (-1);
+ return -1;
if (ai->ai_family == AF_INET) {
struct sockaddr_in *addr = (struct sockaddr_in *)ai->ai_addr;
char errbuf[1024];
ERROR("network plugin: setsockopt (ipv4-ttl): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
} else if (ai->ai_family == AF_INET6) {
/* Useful example:
char errbuf[1024];
ERROR("network plugin: setsockopt(ipv6-ttl): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
}
- return (0);
+ return 0;
} /* int network_set_ttl */
static int network_set_interface(const sockent_t *se,
char errbuf[1024];
ERROR("network plugin: setsockopt (ipv4-multicast-if): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
} else if (ai->ai_family == AF_INET6) {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ai->ai_addr;
char errbuf[1024];
ERROR("network plugin: setsockopt (ipv6-multicast-if): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
}
char interface_name[IFNAMSIZ];
if (if_indextoname(se->interface, interface_name) == NULL)
- return (-1);
+ return -1;
DEBUG("network plugin: Binding socket to interface %s", interface_name);
char errbuf[1024];
ERROR("network plugin: setsockopt (bind-if): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
/* #endif HAVE_IF_INDEXTONAME && SO_BINDTODEVICE */
#endif
}
- return (0);
+ return 0;
} /* }}} network_set_interface */
static int network_bind_socket(int fd, const struct addrinfo *ai,
char errbuf[1024];
ERROR("network plugin: setsockopt (reuseaddr): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
DEBUG("fd = %i; calling `bind'", fd);
if (bind(fd, ai->ai_addr, ai->ai_addrlen) == -1) {
char errbuf[1024];
ERROR("bind: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
if (ai->ai_family == AF_INET) {
char errbuf[1024];
ERROR("network plugin: setsockopt (multicast-loop): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) ==
char errbuf[1024];
ERROR("network plugin: setsockopt (add-membership): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
} else if (ai->ai_family == AF_INET6) {
/* Useful example:
char errbuf[1024];
ERROR("network plugin: setsockopt (ipv6-multicast-loop): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
if (setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq,
char errbuf[1024];
ERROR("network plugin: setsockopt (ipv6-add-membership): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
}
char interface_name[IFNAMSIZ];
if (if_indextoname(interface_idx, interface_name) == NULL)
- return (-1);
+ return -1;
DEBUG("fd = %i; Binding socket to interface %s", fd, interface_name);
char errbuf[1024];
ERROR("network plugin: setsockopt (bind-if): %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
}
#endif /* HAVE_IF_INDEXTONAME && SO_BINDTODEVICE */
- return (0);
+ return 0;
} /* int network_bind_socket */
/* Initialize a sockent structure. `type' must be either `SOCKENT_TYPE_CLIENT'
sockent_t *se;
if ((type != SOCKENT_TYPE_CLIENT) && (type != SOCKENT_TYPE_SERVER))
- return (NULL);
+ return NULL;
se = calloc(1, sizeof(*se));
if (se == NULL)
- return (NULL);
+ return NULL;
se->type = type;
se->node = NULL;
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;
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;
#endif
}
- return (se);
+ return se;
} /* }}} sockent_t *sockent_create */
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) {
ERROR("network plugin: Cannot configure client socket with "
"security: Failed to initialize crypto library.");
- return (-1);
+ return -1;
}
if ((se->data.client.username == NULL) ||
ERROR("network plugin: Client socket with "
"security requested, but no "
"credentials are configured.");
- return (-1);
+ return -1;
}
gcry_md_hash_buffer(GCRY_MD_SHA256, se->data.client.password_hash,
se->data.client.password,
(se->data.server.auth_file == NULL)) {
ERROR("network plugin: Server socket with security requested, "
"but no \"AuthFile\" is configured.");
- return (-1);
+ return -1;
}
if (se->data.server.auth_file != NULL) {
if (network_init_gcrypt() < 0) {
ERROR("network plugin: Cannot configure server socket with security: "
"Failed to initialize crypto library.");
- return (-1);
+ return -1;
}
se->data.server.userdb = fbh_create(se->data.server.auth_file);
if (se->data.server.userdb == NULL) {
ERROR("network plugin: Reading password file \"%s\" failed.",
se->data.server.auth_file);
- return (-1);
+ return -1;
}
}
}
-#endif /* }}} HAVE_LIBGCRYPT */
+#endif /* }}} HAVE_GCRYPT_H */
- return (0);
+ return 0;
} /* }}} int sockent_init_crypto */
static int sockent_client_disconnect(sockent_t *se) /* {{{ */
struct sockent_client *client;
if ((se == NULL) || (se->type != SOCKENT_TYPE_CLIENT))
- return (EINVAL);
+ return EINVAL;
client = &se->data.client;
if (client->fd >= 0) /* connected */
sfree(client->addr);
client->addrlen = 0;
- return (0);
+ return 0;
} /* }}} int sockent_client_disconnect */
static int sockent_client_connect(sockent_t *se) /* {{{ */
cdtime_t now;
if ((se == NULL) || (se->type != SOCKENT_TYPE_CLIENT))
- return (EINVAL);
+ return EINVAL;
client = &se->data.client;
}
if (client->fd >= 0 && !reconnect) /* already connected and not stale*/
- return (0);
+ return 0;
struct addrinfo ai_hints = {.ai_family = AF_UNSPEC,
.ai_flags = AI_ADDRCONFIG,
LOG_ERR, &complaint, "network plugin: getaddrinfo (%s, %s) failed: %s",
(se->node == NULL) ? "(null)" : se->node,
(se->service == NULL) ? "(null)" : se->service, gai_strerror(status));
- return (-1);
+ return -1;
} else {
c_release(LOG_NOTICE, &complaint,
"network plugin: Successfully resolved \"%s\".", se->node);
freeaddrinfo(ai_list);
if (client->fd < 0)
- return (-1);
+ return -1;
if (client->resolve_interval > 0)
client->next_resolve_reconnect = now + client->resolve_interval;
- return (0);
+ return 0;
} /* }}} int sockent_client_connect */
/* Open the file descriptors for a initialized sockent structure. */
const char *service;
if (se == NULL)
- return (-1);
+ return -1;
assert(se->data.server.fd == NULL);
assert(se->data.server.fd_num == 0);
ERROR("network plugin: getaddrinfo (%s, %s) failed: %s",
(se->node == NULL) ? "(null)" : se->node,
(se->service == NULL) ? "(null)" : se->service, gai_strerror(status));
- return (-1);
+ return -1;
}
for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
freeaddrinfo(ai_list);
if (se->data.server.fd_num == 0)
- return (-1);
- return (0);
+ return -1;
+ return 0;
} /* }}} int sockent_server_listen */
/* Add a sockent to the global list of sockets */
sockent_t *last_ptr;
if (se == NULL)
- return (-1);
+ return -1;
if (se->type == SOCKENT_TYPE_SERVER) {
struct pollfd *tmp;
sizeof(*tmp) * (listen_sockets_num + se->data.server.fd_num));
if (tmp == NULL) {
ERROR("network plugin: realloc failed.");
- return (-1);
+ return -1;
}
listen_sockets_pollfd = tmp;
tmp = listen_sockets_pollfd + listen_sockets_num;
if (listen_sockets == NULL) {
listen_sockets = se;
- return (0);
+ return 0;
}
last_ptr = listen_sockets;
} else /* if (se->type == SOCKENT_TYPE_CLIENT) */
{
if (sending_sockets == NULL) {
sending_sockets = se;
- return (0);
+ return 0;
}
last_ptr = sending_sockets;
}
last_ptr = last_ptr->next;
last_ptr->next = se;
- return (0);
+ return 0;
} /* }}} int sockent_add */
static void *dispatch_thread(void __attribute__((unused)) * arg) /* {{{ */
sfree(ent);
} /* while (42) */
- return (NULL);
+ return NULL;
} /* }}} void *dispatch_thread */
static int network_receive(void) /* {{{ */
pthread_mutex_unlock(&receive_list_lock);
}
- return (status);
+ return status;
} /* }}} int network_receive */
static void *receive_thread(void __attribute__((unused)) * arg) {
- return (network_receive() ? (void *)1 : (void *)0);
+ return network_receive() ? (void *)1 : (void *)0;
} /* void *receive_thread */
static void network_init_buffer(void) {
} /* 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)); \
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 */
if (strcmp(vl_def->host, vl->host) != 0) {
if (write_part_string(&buffer, &buffer_size, TYPE_HOST, vl->host,
strlen(vl->host)) != 0)
- return (-1);
+ return -1;
sstrncpy(vl_def->host, vl->host, sizeof(vl_def->host));
}
if (vl_def->time != vl->time) {
if (write_part_number(&buffer, &buffer_size, TYPE_TIME_HR,
(uint64_t)vl->time))
- return (-1);
+ return -1;
vl_def->time = vl->time;
}
if (vl_def->interval != vl->interval) {
if (write_part_number(&buffer, &buffer_size, TYPE_INTERVAL_HR,
(uint64_t)vl->interval))
- return (-1);
+ return -1;
vl_def->interval = vl->interval;
}
if (strcmp(vl_def->plugin, vl->plugin) != 0) {
if (write_part_string(&buffer, &buffer_size, TYPE_PLUGIN, vl->plugin,
strlen(vl->plugin)) != 0)
- return (-1);
+ return -1;
sstrncpy(vl_def->plugin, vl->plugin, sizeof(vl_def->plugin));
}
if (write_part_string(&buffer, &buffer_size, TYPE_PLUGIN_INSTANCE,
vl->plugin_instance,
strlen(vl->plugin_instance)) != 0)
- return (-1);
+ return -1;
sstrncpy(vl_def->plugin_instance, vl->plugin_instance,
sizeof(vl_def->plugin_instance));
}
if (strcmp(vl_def->type, vl->type) != 0) {
if (write_part_string(&buffer, &buffer_size, TYPE_TYPE, vl->type,
strlen(vl->type)) != 0)
- return (-1);
+ return -1;
sstrncpy(vl_def->type, ds->type, sizeof(vl_def->type));
}
if (strcmp(vl_def->type_instance, vl->type_instance) != 0) {
if (write_part_string(&buffer, &buffer_size, TYPE_TYPE_INSTANCE,
vl->type_instance, strlen(vl->type_instance)) != 0)
- return (-1);
+ return -1;
sstrncpy(vl_def->type_instance, vl->type_instance,
sizeof(vl_def->type_instance));
}
if (write_part_values(&buffer, &buffer_size, ds, vl) != 0)
- return (-1);
+ return -1;
- return (buffer - buffer_orig);
+ return buffer - buffer_orig;
} /* }}} int add_to_buffer */
static void flush_buffer(void) {
pthread_mutex_lock(&stats_lock);
stats_values_not_sent++;
pthread_mutex_unlock(&stats_lock);
- return (0);
+ return 0;
}
uc_meta_data_add_unsigned_int(vl, "network:time_sent", (uint64_t)vl->time);
pthread_mutex_unlock(&send_buffer_lock);
- return ((status < 0) ? -1 : 0);
+ return (status < 0) ? -1 : 0;
} /* int network_write */
static int network_config_set_ttl(const oconfig_item_t *ci) /* {{{ */
int tmp = 0;
if (cf_util_get_int(ci, &tmp) != 0)
- return (-1);
+ return -1;
else if ((tmp > 0) && (tmp <= 255))
network_config_ttl = tmp;
else {
WARNING("network plugin: The `TimeToLive' must be between 1 and 255.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int network_config_set_ttl */
static int network_config_set_interface(const oconfig_item_t *ci, /* {{{ */
char if_name[256];
if (cf_util_get_string_buffer(ci, if_name, sizeof(if_name)) != 0)
- return (-1);
+ return -1;
*interface = if_nametoindex(if_name);
- return (0);
+ return 0;
} /* }}} int network_config_set_interface */
static int network_config_set_buffer_size(const oconfig_item_t *ci) /* {{{ */
int tmp = 0;
if (cf_util_get_int(ci, &tmp) != 0)
- return (-1);
+ return -1;
else if ((tmp >= 1024) && (tmp <= 65535))
network_config_packet_size = tmp;
else {
WARNING(
"network plugin: The `MaxPacketSize' must be between 1024 and 65535.");
- return (-1);
+ return -1;
}
- return (0);
+ 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;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("network plugin: The `SecurityLevel' config option needs exactly "
"one string argument.");
- return (-1);
+ return -1;
}
str = ci->values[0].value.string;
*retval = SECURITY_LEVEL_NONE;
else {
WARNING("network plugin: Unknown security level: %s.", str);
- return (-1);
+ return -1;
}
- return (0);
+ 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) /* {{{ */
{
ERROR("network plugin: The `%s' config option needs "
"one or two string arguments.",
ci->key);
- return (-1);
+ return -1;
}
se = sockent_create(SOCKENT_TYPE_SERVER);
if (se == NULL) {
ERROR("network plugin: sockent_create failed.");
- return (-1);
+ return -1;
}
se->node = strdup(ci->values[0].value.string);
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 {
}
}
-#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 "
"requested, but no AuthFile option was given. Cowardly refusing to "
"open this socket!");
sockent_destroy(se);
- return (-1);
+ return -1;
}
-#endif /* HAVE_LIBGCRYPT */
+#endif /* HAVE_GCRYPT_H */
status = sockent_init_crypto(se);
if (status != 0) {
ERROR("network plugin: network_config_add_listen: sockent_init_crypto() "
"failed.");
sockent_destroy(se);
- return (-1);
+ return -1;
}
status = sockent_server_listen(se);
ERROR("network plugin: network_config_add_listen: sockent_server_listen "
"failed.");
sockent_destroy(se);
- return (-1);
+ return -1;
}
status = sockent_add(se);
if (status != 0) {
ERROR("network plugin: network_config_add_listen: sockent_add failed.");
sockent_destroy(se);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int network_config_add_listen */
static int network_config_add_server(const oconfig_item_t *ci) /* {{{ */
ERROR("network plugin: The `%s' config option needs "
"one or two string arguments.",
ci->key);
- return (-1);
+ return -1;
}
se = sockent_create(SOCKENT_TYPE_CLIENT);
if (se == NULL) {
ERROR("network plugin: sockent_create failed.");
- return (-1);
+ return -1;
}
se->node = strdup(ci->values[0].value.string);
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)
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)
}
}
-#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))) {
"requested, but no Username or Password option was given. "
"Cowardly refusing to open this socket!");
sockent_destroy(se);
- return (-1);
+ return -1;
}
-#endif /* HAVE_LIBGCRYPT */
+#endif /* HAVE_GCRYPT_H */
status = sockent_init_crypto(se);
if (status != 0) {
ERROR("network plugin: network_config_add_server: sockent_init_crypto() "
"failed.");
sockent_destroy(se);
- return (-1);
+ return -1;
}
/* No call to sockent_client_connect() here -- it is called from
if (status != 0) {
ERROR("network plugin: network_config_add_server: sockent_add failed.");
sockent_destroy(se);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int network_config_add_server */
static int network_config(oconfig_item_t *ci) /* {{{ */
}
}
- return (0);
+ return 0;
} /* }}} int network_config */
static int network_notification(const notification_t *n,
int status;
if (!check_send_notify_okay(n))
- return (0);
+ return 0;
memset(buffer, 0, sizeof(buffer));
status = write_part_number(&buffer_ptr, &buffer_free, TYPE_TIME_HR,
(uint64_t)n->time);
if (status != 0)
- return (-1);
+ return -1;
status = write_part_number(&buffer_ptr, &buffer_free, TYPE_SEVERITY,
(uint64_t)n->severity);
if (status != 0)
- return (-1);
+ return -1;
if (strlen(n->host) > 0) {
status = write_part_string(&buffer_ptr, &buffer_free, TYPE_HOST, n->host,
strlen(n->host));
if (status != 0)
- return (-1);
+ return -1;
}
if (strlen(n->plugin) > 0) {
status = write_part_string(&buffer_ptr, &buffer_free, TYPE_PLUGIN,
n->plugin, strlen(n->plugin));
if (status != 0)
- return (-1);
+ return -1;
}
if (strlen(n->plugin_instance) > 0) {
status = write_part_string(&buffer_ptr, &buffer_free, TYPE_PLUGIN_INSTANCE,
n->plugin_instance, strlen(n->plugin_instance));
if (status != 0)
- return (-1);
+ return -1;
}
if (strlen(n->type) > 0) {
status = write_part_string(&buffer_ptr, &buffer_free, TYPE_TYPE, n->type,
strlen(n->type));
if (status != 0)
- return (-1);
+ return -1;
}
if (strlen(n->type_instance) > 0) {
status = write_part_string(&buffer_ptr, &buffer_free, TYPE_TYPE_INSTANCE,
n->type_instance, strlen(n->type_instance));
if (status != 0)
- return (-1);
+ return -1;
}
status = write_part_string(&buffer_ptr, &buffer_free, TYPE_MESSAGE,
n->message, strlen(n->message));
if (status != 0)
- return (-1);
+ return -1;
network_send_buffer(buffer, sizeof(buffer) - buffer_free);
- return (0);
+ return 0;
} /* int network_notification */
static int network_shutdown(void) {
plugin_unregister_write("network");
plugin_unregister_shutdown("network");
- return (0);
+ return 0;
} /* int network_shutdown */
static int network_stats_read(void) /* {{{ */
vl.type_instance[0] = 0;
plugin_dispatch_values(&vl);
- return (0);
+ return 0;
} /* }}} int network_stats_read */
static int network_init(void) {
/* Check if we were already initialized. If so, just return - there's
* nothing more to do (for now, that is). */
if (have_init)
- return (0);
+ return 0;
have_init = 1;
if (network_config_stats)
send_buffer = malloc(network_config_packet_size);
if (send_buffer == NULL) {
ERROR("network plugin: malloc failed.");
- return (-1);
+ return -1;
}
network_init_buffer();
/* If no threads need to be started, return here. */
if ((listen_sockets_num == 0) ||
((dispatch_thread_running != 0) && (receive_thread_running != 0)))
- return (0);
+ return 0;
if (dispatch_thread_running == 0) {
int status;
}
}
- return (0);
+ return 0;
} /* int network_init */
/*
cdtime_t now = cdtime();
if ((send_buffer_last_update + timeout) > now) {
pthread_mutex_unlock(&send_buffer_lock);
- return (0);
+ return 0;
}
}
flush_buffer();
}
pthread_mutex_unlock(&send_buffer_lock);
- return (0);
+ return 0;
} /* int network_flush */
void module_register(void) {
plugin_register_flush("network", network_flush,
/* user_data = */ NULL);
} /* void module_register */
-
-/* vim: set fdm=marker : */
#include <kstat.h>
#endif
+static const char *config_keys[] = {"ReportV2", "ReportV3", "ReportV4"};
+static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
+static _Bool report_v2 = 1;
+static _Bool report_v3 = 1;
+static _Bool report_v4 = 1;
+
/*
see /proc/net/rpc/nfs
see http://www.missioncriticallinux.com/orph/NFS-Statistics
static size_t nfs4_server40_procedures_names_num =
STATIC_ARRAY_SIZE(nfs4_server40_procedures_names);
-static const char *nfs4_server41_procedures_names[] = {
- "backchannel_ctl",
- "bind_conn_to_session",
- "exchange_id",
- "create_session",
- "destroy_session",
- "free_stateid",
- "get_dir_delegation",
- "getdeviceinfo",
- "getdevicelist",
- "layoutcommit",
- "layoutget",
- "layoutreturn",
- "secinfo_no_name",
- "sequence",
- "set_ssv",
- "test_stateid",
- "want_delegation",
- "destroy_clientid",
- "reclaim_complete",
+static const char *nfs4_server4x_procedures_names[] = {
+ /* NFS 4.1 */
+ "backchannel_ctl", "bind_conn_to_session", "exchange_id", "create_session",
+ "destroy_session", "free_stateid", "get_dir_delegation", "getdeviceinfo",
+ "getdevicelist", "layoutcommit", "layoutget", "layoutreturn",
+ "secinfo_no_name", "sequence", "set_ssv", "test_stateid", "want_delegation",
+ "destroy_clientid", "reclaim_complete",
+ /* NFS 4.2 */
+ "allocate", /* 3.18 */
+ "copy", /* 3.18 */
+ "copy_notify", /* 3.18 */
+ "deallocate", /* 3.18 */
+ "ioadvise", /* 3.18 */
+ "layouterror", /* 3.18 */
+ "layoutstats", /* 3.18 */
+ "offloadcancel", /* 3.18 */
+ "offloadstatus", /* 3.18 */
+ "readplus", /* 3.18 */
+ "seek", /* 3.18 */
+ "write_same", /* 3.18 */
+ "clone" /* 4.5 */
};
-static size_t nfs4_server41_procedures_names_num =
- STATIC_ARRAY_SIZE(nfs4_server41_procedures_names);
-
#define NFS4_SERVER40_NUM_PROC \
(STATIC_ARRAY_SIZE(nfs4_server40_procedures_names))
-#define NFS4_SERVER41_NUM_PROC \
+#define NFS4_SERVER4X_NUM_PROC \
(STATIC_ARRAY_SIZE(nfs4_server40_procedures_names) + \
- STATIC_ARRAY_SIZE(nfs4_server41_procedures_names))
+ STATIC_ARRAY_SIZE(nfs4_server4x_procedures_names))
-#define NFS4_SERVER_MAX_PROC (NFS4_SERVER41_NUM_PROC)
+#define NFS4_SERVER_MAX_PROC (NFS4_SERVER4X_NUM_PROC)
static const char *nfs4_client40_procedures_names[] = {
"null",
"fsid_present" /* |54| 3.13 */
};
-static const char *nfs4_client41_procedures_names[] = {
+static const char *nfs4_client4x_procedures_names[] = {
+ /* NFS 4.1 */
"exchange_id", /* |40| 2.6.30 */
"create_session", /* |40| 2.6.30 */
"destroy_session", /* |40| 2.6.30 */
"free_stateid", /* |51| 3.1 */
"getdevicelist", /* |51| 3.1 */
"bind_conn_to_session", /* |53| 3.5 */
- "destroy_clientid" /* |53| 3.5 */
+ "destroy_clientid", /* |53| 3.5 */
+ /* NFS 4.2 */
+ "seek", /* |55| 3.18 */
+ "allocate", /* |57| 3.19 */
+ "deallocate", /* |57| 3.19 */
+ "layoutstats", /* |58| 4.2 */
+ "clone", /* |59| 4.4 */
+ "copy" /* |60| 4.7 */
};
#define NFS4_CLIENT40_NUM_PROC \
(STATIC_ARRAY_SIZE(nfs4_client40_procedures_names))
-#define NFS4_CLIENT41_NUM_PROC \
+#define NFS4_CLIENT4X_NUM_PROC \
(STATIC_ARRAY_SIZE(nfs4_client40_procedures_names) + \
- STATIC_ARRAY_SIZE(nfs4_client41_procedures_names))
+ STATIC_ARRAY_SIZE(nfs4_client4x_procedures_names))
-#define NFS4_CLIENT_MAX_PROC (NFS4_CLIENT41_NUM_PROC)
+#define NFS4_CLIENT_MAX_PROC (NFS4_CLIENT4X_NUM_PROC)
#endif
static kstat_t *nfs4_ksp_server;
#endif
+static int nfs_config(const char *key, const char *value) {
+ if (strcasecmp(key, "ReportV2") == 0)
+ report_v2 = IS_TRUE(value);
+ else if (strcasecmp(key, "ReportV3") == 0)
+ report_v3 = IS_TRUE(value);
+ else if (strcasecmp(key, "ReportV4") == 0)
+ report_v4 = IS_TRUE(value);
+ else
+ return -1;
+
+ return 0;
+}
+
#if KERNEL_LINUX
-static int nfs_init(void) { return (0); }
+static int nfs_init(void) { return 0; }
/* #endif KERNEL_LINUX */
#elif HAVE_LIBKSTAT
nfs4_ksp_server = NULL;
if (kc == NULL)
- return (-1);
+ return -1;
for (kstat_t *ksp_chain = kc->kc_chain; ksp_chain != NULL;
ksp_chain = ksp_chain->ks_next) {
nfs4_ksp_client = ksp_chain;
}
- return (0);
+ return 0;
} /* int nfs_init */
#endif
char plugin_instance[DATA_MAX_NAME_LEN];
value_t values[fields_num];
- ssnprintf(plugin_instance, sizeof(plugin_instance), "v%i%s", nfs_version,
- instance);
+ snprintf(plugin_instance, sizeof(plugin_instance), "v%i%s", nfs_version,
+ instance);
for (size_t i = 0; i < fields_num; i++)
(void)parse_value(fields[i], &values[i], DS_TYPE_DERIVE);
WARNING("nfs plugin: Wrong number of fields for "
"NFSv%i %s statistics. Expected %zu, got %zu.",
nfs_version, instance, proc_names_num, fields_num);
- return (EINVAL);
+ return EINVAL;
}
nfs_submit_fields(nfs_version, instance, fields, fields_num, proc_names);
- return (0);
+ return 0;
}
static int nfs_submit_nfs4_server(const char *instance, char **fields,
size_t fields_num) {
static int suppress_warning = 0;
+ size_t proc4x_names_num;
- if (fields_num != NFS4_SERVER40_NUM_PROC &&
- fields_num != NFS4_SERVER41_NUM_PROC) {
+ switch (fields_num) {
+ case NFS4_SERVER40_NUM_PROC:
+ case NFS4_SERVER40_NUM_PROC + 19: /* NFS 4.1 */
+ case NFS4_SERVER40_NUM_PROC + 31: /* NFS 4.2 */
+ case NFS4_SERVER40_NUM_PROC + 32: /* NFS 4.2 */
+ break;
+ default:
if (!suppress_warning) {
WARNING("nfs plugin: Unexpected number of fields for "
"NFSv4 %s statistics: %zu. ",
fields_num = NFS4_SERVER_MAX_PROC;
suppress_warning = 1;
} else {
- return (EINVAL);
+ return EINVAL;
}
}
nfs_submit_fields(4, instance, fields, nfs4_server40_procedures_names_num,
nfs4_server40_procedures_names);
- if (fields_num >= NFS4_SERVER41_NUM_PROC) {
+ if (fields_num > nfs4_server40_procedures_names_num) {
+ proc4x_names_num = fields_num - nfs4_server40_procedures_names_num;
fields += nfs4_server40_procedures_names_num;
- nfs_submit_fields(4, instance, fields, nfs4_server41_procedures_names_num,
- nfs4_server41_procedures_names);
+ nfs_submit_fields(4, instance, fields, proc4x_names_num,
+ nfs4_server4x_procedures_names);
}
- return (0);
+ return 0;
}
static int nfs_submit_nfs4_client(const char *instance, char **fields,
size_t fields_num) {
- size_t proc40_names_num, proc41_names_num;
+ size_t proc40_names_num, proc4x_names_num;
static int suppress_warning = 0;
proc40_names_num = 37;
break;
case 54:
+ case 55:
+ case 57:
+ case 58:
+ case 59:
+ case 60:
proc40_names_num = 38;
break;
default:
suppress_warning = 1;
} else {
- return (EINVAL);
+ return EINVAL;
}
}
nfs4_client40_procedures_names);
if (fields_num > proc40_names_num) {
- proc41_names_num = fields_num - proc40_names_num;
+ proc4x_names_num = fields_num - proc40_names_num;
fields += proc40_names_num;
- nfs_submit_fields(4, instance, fields, proc41_names_num,
- nfs4_client41_procedures_names);
+ nfs_submit_fields(4, instance, fields, proc4x_names_num,
+ nfs4_client4x_procedures_names);
}
- return (0);
+ return 0;
}
static void nfs_read_linux(FILE *fh, const char *inst) {
if (fields_num < 3)
continue;
- if (strcmp(fields[0], "proc2") == 0) {
+ if (strcmp(fields[0], "proc2") == 0 && report_v2) {
nfs_submit_fields_safe(/* version = */ 2, inst, fields + 2,
(size_t)(fields_num - 2), nfs2_procedures_names,
nfs2_procedures_names_num);
- } else if (strncmp(fields[0], "proc3", 5) == 0) {
+ } else if (strncmp(fields[0], "proc3", 5) == 0 && report_v3) {
nfs_submit_fields_safe(/* version = */ 3, inst, fields + 2,
(size_t)(fields_num - 2), nfs3_procedures_names,
nfs3_procedures_names_num);
- } else if (strcmp(fields[0], "proc4ops") == 0) {
+ } else if (strcmp(fields[0], "proc4ops") == 0 && report_v4) {
if (inst[0] == 's')
nfs_submit_nfs4_server(inst, fields + 2, (size_t)(fields_num - 2));
- } else if (strcmp(fields[0], "proc4") == 0) {
+ } else if (strcmp(fields[0], "proc4") == 0 && report_v4) {
if (inst[0] == 'c')
nfs_submit_nfs4_client(inst, fields + 2, (size_t)(fields_num - 2));
}
value_t values[proc_names_num];
if (ksp == NULL)
- return (EINVAL);
+ return EINVAL;
- ssnprintf(plugin_instance, sizeof(plugin_instance), "v%i%s", nfs_version,
- inst);
+ snprintf(plugin_instance, sizeof(plugin_instance), "v%i%s", nfs_version,
+ inst);
kstat_read(kc, ksp, NULL);
for (size_t i = 0; i < proc_names_num; i++) {
}
nfs_procedures_submit(plugin_instance, proc_names, values, proc_names_num);
- return (0);
+ return 0;
}
#endif
fclose(fh);
}
- return (0);
+ return 0;
}
/* #endif KERNEL_LINUX */
#elif HAVE_LIBKSTAT
static int nfs_read(void) {
- nfs_read_kstat(nfs2_ksp_client, /* version = */ 2, "client",
- nfs2_procedures_names, nfs2_procedures_names_num);
- nfs_read_kstat(nfs2_ksp_server, /* version = */ 2, "server",
- nfs2_procedures_names, nfs2_procedures_names_num);
- nfs_read_kstat(nfs3_ksp_client, /* version = */ 3, "client",
- nfs3_procedures_names, nfs3_procedures_names_num);
- nfs_read_kstat(nfs3_ksp_server, /* version = */ 3, "server",
- nfs3_procedures_names, nfs3_procedures_names_num);
- nfs_read_kstat(nfs4_ksp_client, /* version = */ 4, "client",
- nfs4_procedures_names, nfs4_procedures_names_num);
- nfs_read_kstat(nfs4_ksp_server, /* version = */ 4, "server",
- nfs4_procedures_names, nfs4_procedures_names_num);
-
- return (0);
+ if (report_v2) {
+ nfs_read_kstat(nfs2_ksp_client, /* version = */ 2, "client",
+ nfs2_procedures_names, nfs2_procedures_names_num);
+ nfs_read_kstat(nfs2_ksp_server, /* version = */ 2, "server",
+ nfs2_procedures_names, nfs2_procedures_names_num);
+ }
+ if (report_v3) {
+ nfs_read_kstat(nfs3_ksp_client, /* version = */ 3, "client",
+ nfs3_procedures_names, nfs3_procedures_names_num);
+ nfs_read_kstat(nfs3_ksp_server, /* version = */ 3, "server",
+ nfs3_procedures_names, nfs3_procedures_names_num);
+ }
+ if (report_v4) {
+ nfs_read_kstat(nfs4_ksp_client, /* version = */ 4, "client",
+ nfs4_procedures_names, nfs4_procedures_names_num);
+ nfs_read_kstat(nfs4_ksp_server, /* version = */ 4, "server",
+ nfs4_procedures_names, nfs4_procedures_names_num);
+ }
+
+ return 0;
}
#endif /* HAVE_LIBKSTAT */
void module_register(void) {
+ plugin_register_config("nfs", nfs_config, config_keys, config_keys_num);
plugin_register_init("nfs", nfs_init);
plugin_register_read("nfs", nfs_read);
} /* void module_register */
}
if (len == 0)
- return (len);
+ return len;
memcpy(&nginx_buffer[nginx_buffer_len], buf, len);
nginx_buffer_len += len;
nginx_buffer[nginx_buffer_len] = 0;
- return (len);
+ return len;
}
static int config_set(char **var, const char *value) {
}
if ((*var = strdup(value)) == NULL)
- return (1);
+ return 1;
else
- return (0);
+ return 0;
}
static int config(const char *key, const char *value) {
if (strcasecmp(key, "url") == 0)
- return (config_set(&url, value));
+ return config_set(&url, value);
else if (strcasecmp(key, "user") == 0)
- return (config_set(&user, value));
+ return config_set(&user, value);
else if (strcasecmp(key, "password") == 0)
- return (config_set(&pass, value));
+ return config_set(&pass, value);
else if (strcasecmp(key, "verifypeer") == 0)
- return (config_set(&verify_peer, value));
+ return config_set(&verify_peer, value);
else if (strcasecmp(key, "verifyhost") == 0)
- return (config_set(&verify_host, value));
+ return config_set(&verify_host, value);
else if (strcasecmp(key, "cacert") == 0)
- return (config_set(&cacert, value));
+ return config_set(&cacert, value);
else if (strcasecmp(key, "timeout") == 0)
- return (config_set(&timeout, value));
+ return config_set(&timeout, value);
else
- return (-1);
+ return -1;
} /* int config */
static int init(void) {
if ((curl = curl_easy_init()) == NULL) {
ERROR("nginx plugin: curl_easy_init failed.");
- return (-1);
+ return -1;
}
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(curl, CURLOPT_PASSWORD, (pass == NULL) ? "" : pass);
#else
static char credentials[1024];
- int status = ssnprintf(credentials, sizeof(credentials), "%s:%s", user,
- pass == NULL ? "" : pass);
+ int status = snprintf(credentials, sizeof(credentials), "%s:%s", user,
+ pass == NULL ? "" : pass);
if ((status < 0) || ((size_t)status >= sizeof(credentials))) {
ERROR("nginx plugin: Credentials would have been truncated.");
- return (-1);
+ return -1;
}
curl_easy_setopt(curl, CURLOPT_USERPWD, credentials);
}
#endif
- return (0);
+ return 0;
} /* void init */
static void submit(const char *type, const char *inst, long long value) {
int fields_num;
if (curl == NULL)
- return (-1);
+ return -1;
if (url == NULL)
- return (-1);
+ return -1;
nginx_buffer_len = 0;
if (curl_easy_perform(curl) != CURLE_OK) {
WARNING("nginx plugin: curl_easy_perform failed: %s", nginx_curl_error);
- return (-1);
+ return -1;
}
ptr = nginx_buffer;
nginx_buffer_len = 0;
- return (0);
+ return 0;
} /* int nginx_read */
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 :
- */
timeout = fail_timeout;
}
- ssnprintf(summary, sizeof(summary), "collectd %s notification",
- (NOTIF_FAILURE == n->severity)
- ? "FAILURE"
- : (NOTIF_WARNING == n->severity)
- ? "WARNING"
- : (NOTIF_OKAY == n->severity) ? "OKAY" : "UNKNOWN");
+ snprintf(summary, sizeof(summary), "collectd %s notification",
+ (NOTIF_FAILURE == n->severity)
+ ? "FAILURE"
+ : (NOTIF_WARNING == n->severity)
+ ? "WARNING"
+ : (NOTIF_OKAY == n->severity) ? "OKAY" : "UNKNOWN");
notification = notify_notification_new(summary, n->message, NULL
#if NOTIFY_CHECK_VERSION(0, 7, 0)
plugin_register_init("notify_desktop", c_notify_init);
return;
} /* module_register */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
static int notify_email_init(void) {
char server[MAXSTRING];
- ssnprintf(server, sizeof(server), "%s:%i",
- (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host, smtp_port);
+ snprintf(server, sizeof(server), "%s:%i",
+ (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host, smtp_port);
pthread_mutex_lock(&session_lock);
if (session == NULL) {
pthread_mutex_unlock(&session_lock);
ERROR("notify_email plugin: cannot create SMTP session");
- return (-1);
+ return -1;
}
smtp_set_monitorcb(session, monitor_cb, NULL, 1);
if (!smtp_auth_set_context(session, authctx)) {
pthread_mutex_unlock(&session_lock);
ERROR("notify_email plugin: cannot set SMTP auth context");
- return (-1);
+ return -1;
}
pthread_mutex_unlock(&session_lock);
- return (0);
+ return 0;
} /* int notify_email_init */
static int notify_email_shutdown(void) {
auth_client_exit();
pthread_mutex_unlock(&session_lock);
- return (0);
+ return 0;
} /* int notify_email_shutdown */
static int notify_email_config(const char *key, const char *value) {
tmp = realloc(recipients, (recipients_len + 1) * sizeof(char *));
if (tmp == NULL) {
ERROR("notify_email: realloc failed.");
- return (-1);
+ return -1;
}
recipients = tmp;
recipients[recipients_len] = strdup(value);
if (recipients[recipients_len] == NULL) {
ERROR("notify_email: strdup failed.");
- return (-1);
+ return -1;
}
recipients_len++;
} else if (0 == strcasecmp(key, "SMTPServer")) {
int port_tmp = atoi(value);
if (port_tmp < 1 || port_tmp > 65535) {
WARNING("notify_email plugin: Invalid SMTP port: %i", port_tmp);
- return (1);
+ return 1;
}
smtp_port = port_tmp;
} else if (0 == strcasecmp(key, "SMTPUser")) {
int buf_len = sizeof(buf);
int i;
- ssnprintf(severity, sizeof(severity), "%s",
- (n->severity == NOTIF_FAILURE)
- ? "FAILURE"
- : ((n->severity == NOTIF_WARNING)
- ? "WARNING"
- : ((n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN")));
+ snprintf(severity, sizeof(severity), "%s",
+ (n->severity == NOTIF_FAILURE)
+ ? "FAILURE"
+ : ((n->severity == NOTIF_WARNING)
+ ? "WARNING"
+ : ((n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN")));
- ssnprintf(subject, sizeof(subject),
- (email_subject == NULL) ? DEFAULT_SMTP_SUBJECT : email_subject,
- severity, n->host);
+ snprintf(subject, sizeof(subject),
+ (email_subject == NULL) ? DEFAULT_SMTP_SUBJECT : email_subject,
+ severity, n->host);
localtime_r(&CDTIME_T_TO_TIME_T(n->time), ×tamp_tm);
strftime(timestamp_str, sizeof(timestamp_str), "%Y-%m-%d %H:%M:%S",
timestamp_str[sizeof(timestamp_str) - 1] = '\0';
/* Let's make RFC822 message text with \r\n EOLs */
- ssnprintf(buf, buf_len, "MIME-Version: 1.0\r\n"
- "Content-Type: text/plain; charset=\"US-ASCII\"\r\n"
- "Content-Transfer-Encoding: 8bit\r\n"
- "Subject: %s\r\n"
- "\r\n"
- "%s - %s@%s\r\n"
- "\r\n"
- "Message: %s",
- subject, timestamp_str, severity, n->host, n->message);
+ snprintf(buf, buf_len, "MIME-Version: 1.0\r\n"
+ "Content-Type: text/plain; charset=\"US-ASCII\"\r\n"
+ "Content-Transfer-Encoding: 8bit\r\n"
+ "Subject: %s\r\n"
+ "\r\n"
+ "%s - %s@%s\r\n"
+ "\r\n"
+ "Message: %s",
+ subject, timestamp_str, severity, n->host, n->message);
pthread_mutex_lock(&session_lock);
if (session == NULL) {
/* Initialization failed or we're in the process of shutting down. */
pthread_mutex_unlock(&session_lock);
- return (-1);
+ return -1;
}
if (!(message = smtp_add_message(session))) {
pthread_mutex_unlock(&session_lock);
ERROR("notify_email plugin: cannot set SMTP message");
- return (-1);
+ return -1;
}
smtp_set_reverse_path(message, email_from);
smtp_set_header(message, "To", NULL, NULL);
ERROR("notify_email plugin: SMTP server problem: %s",
smtp_strerror(smtp_errno(), buf, sizeof buf));
pthread_mutex_unlock(&session_lock);
- return (-1);
+ return -1;
} else {
#if COLLECT_DEBUG
const smtp_status_t *status;
}
pthread_mutex_unlock(&session_lock);
- return (0);
+ return 0;
} /* int notify_email_notification */
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 : */
break;
}
- ssnprintf(buffer, sizeof(buffer),
- "[%.0f] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n",
- CDTIME_T_TO_DOUBLE(n->time), n->host, &svc_description[1], code,
- n->message);
+ snprintf(buffer, sizeof(buffer),
+ "[%.0f] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n",
+ CDTIME_T_TO_DOUBLE(n->time), n->host, &svc_description[1], code,
+ n->message);
return nagios_print(buffer);
} /* }}} int nagios_notify */
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 : */
#include "common.h"
#include "plugin.h"
-#if HAVE_STDINT_H
-#include <stdint.h>
-#endif
#if HAVE_NETDB_H
#include <netdb.h>
#endif
if (ntpd_host != NULL)
free(ntpd_host);
if ((ntpd_host = strdup(value)) == NULL)
- return (1);
+ return 1;
} else if (strcasecmp(key, "Port") == 0) {
int port = (int)(atof(value));
if ((port > 0) && (port <= 65535))
- ssnprintf(ntpd_port, sizeof(ntpd_port), "%i", port);
+ snprintf(ntpd_port, sizeof(ntpd_port), "%i", port);
else
sstrncpy(ntpd_port, value, sizeof(ntpd_port));
} else if (strcasecmp(key, "ReverseLookups") == 0) {
else
include_unit_id = 0;
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static void ntpd_submit(const char *type, const char *type_inst,
int status;
if (sock_descr >= 0)
- return (sock_descr);
+ return sock_descr;
DEBUG("Opening a new socket");
ERROR("ntpd plugin: getaddrinfo (%s, %s): %s", host, port,
(status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
: gai_strerror(status));
- return (-1);
+ return -1;
}
for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
ERROR("ntpd plugin: Unable to connect to server.");
}
- return (sock_descr);
+ return sock_descr;
}
/* For a description of the arguments see `ntpd_do_query' below. */
ssize_t pkt_padding; /* Padding in this packet */
if ((sd = ntpd_connect()) < 0)
- return (-1);
+ return -1;
items = NULL;
items_num = 0;
char errbuf[1024];
ERROR("ntpd plugin: gettimeofday failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
time_end.tv_sec++; /* wait for a most one second */
char errbuf[1024];
ERROR("ntpd plugin: gettimeofday failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
if (timeval_cmp(time_end, time_now, &time_left) <= 0)
char errbuf[1024];
ERROR("ntpd plugin: poll failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
if (status == 0) /* timeout */
DEBUG("Closing socket #%i", sd);
close(sd);
sock_descr = sd = -1;
- return (-1);
+ return -1;
}
DEBUG("recv'd %i bytes", status);
if (INFO_ERR(res.err_nitems) != 0) {
ERROR("ntpd plugin: Received error code %i",
(int)INFO_ERR(res.err_nitems));
- return ((int)INFO_ERR(res.err_nitems));
+ return (int)INFO_ERR(res.err_nitems);
}
/* extract number of items in this packet and the size of these items */
done = 1;
} /* while (done == 0) */
- return (0);
+ return 0;
} /* int ntpd_receive_response */
/* For a description of the arguments see `ntpd_do_query' below. */
assert(req_size >= 0);
if ((sd = ntpd_connect()) < 0)
- return (-1);
+ return -1;
req.rm_vn_mode = RM_VN_MODE(0, 0, 0);
req.auth_seq = AUTH_SEQ(0, 0);
(void *)req_data);
status = swrite(sd, (const char *)&req, REQ_LEN_NOMAC);
- if (status < 0) {
+ if (status != 0) {
DEBUG("`swrite' failed. Closing socket #%i", sd);
close(sd);
sock_descr = sd = -1;
- return (status);
+ return status;
}
- return (0);
+ return 0;
}
/*
status = ntpd_send_request(req_code, req_items, req_size, req_data);
if (status != 0)
- return (status);
+ return status;
status = ntpd_receive_response(res_items, res_size, res_data, res_item_size);
- return (status);
+ return status;
}
static double ntpd_read_fp(int32_t val_int) {
val_int = ntohl(val_int);
val_double = ((double)val_int) / FP_FRAC;
- return (val_double);
+ return val_double;
}
static uint32_t
uint32_t addr = ntohl(peer_info->srcadr);
uint32_t refclock_id = (addr >> 8) & 0x00FF;
- return (refclock_id);
+ return refclock_id;
}
static int ntpd_get_name_from_address(char *buffer, size_t buffer_size,
ERROR("ntpd plugin: getnameinfo failed: %s",
(status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
: gai_strerror(status));
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* ntpd_get_name_from_address */
static int ntpd_get_name_refclock(char *buffer, size_t buffer_size,
uint32_t unit_id = ntohl(peer_info->srcadr) & 0x00FF;
if (((size_t)refclock_id) >= refclock_names_num)
- return (ntpd_get_name_from_address(buffer, buffer_size, peer_info,
- /* do_reverse_lookup = */ 0));
+ return ntpd_get_name_from_address(buffer, buffer_size, peer_info, 0);
if (include_unit_id)
- ssnprintf(buffer, buffer_size, "%s-%" PRIu32, refclock_names[refclock_id],
- unit_id);
+ snprintf(buffer, buffer_size, "%s-%" PRIu32, refclock_names[refclock_id],
+ unit_id);
else
sstrncpy(buffer, refclock_names[refclock_id], buffer_size);
- return (0);
+ return 0;
} /* int ntpd_get_name_refclock */
static int ntpd_get_name(char *buffer, size_t buffer_size,
uint32_t addr = ntohl(peer_info->srcadr);
if (!peer_info->v6_flag && ((addr & REFCLOCK_MASK) == REFCLOCK_ADDR))
- return (ntpd_get_name_refclock(buffer, buffer_size, peer_info));
+ return ntpd_get_name_refclock(buffer, buffer_size, peer_info);
else
- return (ntpd_get_name_from_address(buffer, buffer_size, peer_info,
- do_reverse_lookups));
+ return ntpd_get_name_from_address(buffer, buffer_size, peer_info,
+ do_reverse_lookups);
} /* int ntpd_addr_to_name */
static int ntpd_read(void) {
if (status != 0) {
ERROR("ntpd plugin: ntpd_do_query (REQ_GET_KERNEL) failed with status %i",
status);
- return (status);
+ return status;
} else if ((ik == NULL) || (ik_num == 0) || (ik_size == 0)) {
ERROR("ntpd plugin: ntpd_do_query returned unexpected data. "
"(ik = %p; ik_num = %i; ik_size = %i)",
(void *)ik, ik_num, ik_size);
- return (-1);
+ return -1;
}
if (ntohs(ik->status) & STA_NANO) {
ERROR(
"ntpd plugin: ntpd_do_query (REQ_PEER_LIST_SUM) failed with status %i",
status);
- return (status);
+ return status;
} else if ((ps == NULL) || (ps_num == 0) || (ps_size == 0)) {
ERROR("ntpd plugin: ntpd_do_query returned unexpected data. "
"(ps = %p; ps_num = %i; ps_size = %i)",
(void *)ps, ps_num, ps_size);
- return (-1);
+ return -1;
}
for (int i = 0; i < ps_num; i++) {
free(ps);
ps = NULL;
- return (0);
+ return 0;
} /* int ntpd_read */
void module_register(void) {
vl.values_len = 1;
sstrncpy(vl.plugin, "numa", sizeof(vl.plugin));
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "node%i", node);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "node%i", node);
sstrncpy(vl.type, "vmpage_action", sizeof(vl.type));
sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
int status;
int success;
- ssnprintf(path, sizeof(path), NUMA_ROOT_DIR "/node%i/numastat", node);
+ snprintf(path, sizeof(path), NUMA_ROOT_DIR "/node%i/numastat", node);
fh = fopen(path, "r");
if (fh == NULL) {
char errbuf[1024];
ERROR("numa plugin: Reading node %i failed: open(%s): %s", node, path,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
success = 0;
}
fclose(fh);
- return (success ? 0 : -1);
+ return success ? 0 : -1;
} /* }}} int numa_read_node */
static int numa_read(void) /* {{{ */
if (max_node < 0) {
WARNING("numa plugin: No NUMA nodes were detected.");
- return (-1);
+ return -1;
}
success = 0;
success++;
}
- return (success ? 0 : -1);
+ return success ? 0 : -1;
} /* }}} int numa_read */
static int numa_init(void) /* {{{ */
struct stat statbuf = {0};
int status;
- ssnprintf(path, sizeof(path), NUMA_ROOT_DIR "/node%i", max_node + 1);
+ snprintf(path, sizeof(path), NUMA_ROOT_DIR "/node%i", max_node + 1);
status = stat(path, &statbuf);
if (status == 0) {
char errbuf[1024];
ERROR("numa plugin: stat(%s) failed: %s", path,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
}
DEBUG("numa plugin: Found %i nodes.", max_node + 1);
- return (0);
+ return 0;
} /* }}} int numa_init */
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 : */
*
* Authors:
* Florian octo Forster <octo at collectd.org>
+ * Pavel Rochnyak <pavel2000 ngs.ru>
**/
#include "collectd.h"
nut_ups_t *next;
};
-static nut_ups_t *upslist_head = NULL;
+static const char *config_keys[] = {"UPS", "FORCESSL", "VERIFYPEER", "CAPATH",
+ "CONNECTTIMEOUT"};
+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 int ssl_flags = UPSCLI_CONN_TRYSSL;
+static int connect_timeout = -1;
+static char *ca_path = NULL;
-static pthread_mutex_t read_lock = PTHREAD_MUTEX_INITIALIZER;
-static int read_busy = 0;
+static int nut_read(user_data_t *user_data);
-static const char *config_keys[] = {"UPS"};
-static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
+static void free_nut_ups_t(void *arg) {
+ nut_ups_t *ups = arg;
-static void free_nut_ups_t(nut_ups_t *ups) {
if (ups->conn != NULL) {
upscli_disconnect(ups->conn);
sfree(ups->conn);
static int nut_add_ups(const char *name) {
nut_ups_t *ups;
int status;
+ char *cb_name;
DEBUG("nut plugin: nut_add_ups (name = %s);", name);
ups = calloc(1, sizeof(*ups));
if (ups == NULL) {
ERROR("nut plugin: nut_add_ups: calloc failed.");
- return (1);
+ return 1;
}
status = upscli_splitname(name, &ups->upsname, &ups->hostname, &ups->port);
if (status != 0) {
ERROR("nut plugin: nut_add_ups: upscli_splitname (%s) failed.", name);
free_nut_ups_t(ups);
- return (1);
+ return 1;
}
- if (upslist_head == NULL)
- upslist_head = ups;
- else {
- nut_ups_t *last = upslist_head;
- while (last->next != NULL)
- last = last->next;
- last->next = ups;
+ cb_name = ssnprintf_alloc("nut/%s", name);
+
+ status = plugin_register_complex_read(
+ /* group = */ "nut",
+ /* name = */ cb_name,
+ /* callback = */ nut_read,
+ /* interval = */ 0,
+ /* user_data = */ &(user_data_t){
+ .data = ups, .free_func = free_nut_ups_t,
+ });
+
+ sfree(cb_name);
+
+ if (status == EINVAL) {
+ WARNING("nut plugin: UPS \"%s\" already added. "
+ "Please check your configuration.",
+ name);
+ return -1;
}
- return (0);
+ 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_set_connect_timeout(const char *value) {
+#if HAVE_UPSCLI_TRYCONNECT
+ long ret;
+
+ errno = 0;
+ ret = strtol(value, /* endptr = */ NULL, /* base = */ 10);
+ if (errno == 0)
+ connect_timeout = ret;
+ else
+ WARNING("nut plugin: The ConnectTimeout option requires numeric argument. "
+ "Setting ignored.");
+#else /* #if HAVE_UPSCLI_TRYCONNECT */
+ WARNING("nut plugin: Dependency libupsclient version insufficient (<2.6.2) "
+ "for ConnectTimeout option support. Setting ignored.");
+#endif
+ return 0;
+} /* int nut_set_connect_timeout */
+
static int nut_config(const char *key, const char *value) {
if (strcasecmp(key, "UPS") == 0)
- return (nut_add_ups(value));
+ 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 if (strcasecmp(key, "CONNECTTIMEOUT") == 0)
+ return nut_set_connect_timeout(value);
else
- return (-1);
+ return -1;
} /* int nut_config */
static void nut_submit(nut_ups_t *ups, const char *type,
vl.values = &(value_t){.gauge = value};
vl.values_len = 1;
- sstrncpy(vl.host,
- (strcasecmp(ups->hostname, "localhost") == 0) ? hostname_g
- : ups->hostname,
- sizeof(vl.host));
+ if (strcasecmp(ups->hostname, "localhost") != 0)
+ sstrncpy(vl.host, ups->hostname, sizeof(vl.host));
sstrncpy(vl.plugin, "nut", sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, ups->upsname, sizeof(vl.plugin_instance));
sstrncpy(vl.type, type, sizeof(vl.type));
plugin_dispatch_values(&vl);
} /* void nut_submit */
-static int nut_read_one(nut_ups_t *ups) {
+static int nut_connect(nut_ups_t *ups) {
+ int status, ssl_status;
+
+#if HAVE_UPSCLI_TRYCONNECT
+ struct timeval tv;
+ tv.tv_sec = connect_timeout / 1000;
+ tv.tv_usec = connect_timeout % 1000;
+
+ status =
+ upscli_tryconnect(ups->conn, ups->hostname, ups->port, ssl_flags, &tv);
+#else /* #if HAVE_UPSCLI_TRYCONNECT */
+ status = upscli_connect(ups->conn, ups->hostname, ups->port, ssl_flags);
+#endif
+
+ 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 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);
+ return -1;
+ } /* if (ssl_status == 1 && verify_peer == 1) */
+ return 0;
+}
+
+static int nut_read(user_data_t *user_data) {
+ nut_ups_t *ups = user_data->data;
const char *query[3] = {"VAR", ups->upsname, NULL};
unsigned int query_num = 2;
char **answer;
ups->conn = malloc(sizeof(*ups->conn));
if (ups->conn == NULL) {
ERROR("nut plugin: malloc failed.");
- return (-1);
+ 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
* error */
status = upscli_list_start(ups->conn, query_num, query);
if (status != 0) {
- ERROR("nut plugin: nut_read_one: upscli_list_start (%s) failed: %s",
+ ERROR("nut plugin: nut_read: upscli_list_start (%s) failed: %s",
ups->upsname, upscli_strerror(ups->conn));
upscli_disconnect(ups->conn);
sfree(ups->conn);
- return (-1);
+ return -1;
}
while ((status = upscli_list_next(ups->conn, query_num, query, &answer_num,
}
} /* while (upscli_list_next) */
- return (0);
-} /* int nut_read_one */
+ return 0;
+} /* int nut_read */
-static int nut_read(void) {
- int success = 0;
+static int nut_init(void) {
+#if HAVE_UPSCLI_INIT
+ if (verify_peer == 1 && force_ssl == 0) {
+ WARNING("nut plugin: nut_connect: VerifyPeer true but ForceSSL "
+ "false. Setting ForceSSL to true.");
+ force_ssl = 1;
+ }
- pthread_mutex_lock(&read_lock);
- success = read_busy;
- read_busy = 1;
- pthread_mutex_unlock(&read_lock);
+ if (verify_peer == 1 && ca_path == NULL) {
+ ERROR("nut plugin: nut_connect: VerifyPeer true but missing "
+ "CAPath value.");
+ plugin_unregister_read_group("nut");
+ return -1;
+ }
- if (success != 0)
- return (0);
+ if (verify_peer == 1 || force_ssl == 1) {
+ int status = upscli_init(verify_peer, ca_path, NULL, NULL);
- for (nut_ups_t *ups = upslist_head; ups != NULL; ups = ups->next)
- if (nut_read_one(ups) == 0)
- success++;
+ if (status != 1) {
+ ERROR("nut plugin: upscli_init (%i, %s) failed", verify_peer, ca_path);
+ upscli_cleanup();
+ plugin_unregister_read_group("nut");
+ 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 /* #if HAVE_UPSCLI_INIT */
+ 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.");
+ verify_peer = 0;
+ }
- pthread_mutex_lock(&read_lock);
- read_busy = 0;
- pthread_mutex_unlock(&read_lock);
+ if (force_ssl == 1)
+ ssl_flags = UPSCLI_CONN_REQSSL;
+#endif
- return ((success != 0) ? 0 : -1);
-} /* int nut_read */
+ if (connect_timeout <= 0)
+ connect_timeout = (long)CDTIME_T_TO_MS(plugin_get_interval());
-static int nut_shutdown(void) {
- nut_ups_t *this;
- nut_ups_t *next;
+ return 0;
+} /* int nut_init */
- this = upslist_head;
- while (this != NULL) {
- next = this->next;
- free_nut_ups_t(this);
- this = next;
- }
+static int nut_shutdown(void) {
+#if HAVE_UPSCLI_INIT
+ upscli_cleanup();
+#endif
- return (0);
+ return 0;
} /* int nut_shutdown */
void module_register(void) {
plugin_register_config("nut", nut_config, config_keys, config_keys_num);
- plugin_register_read("nut", nut_read);
+ plugin_register_init("nut", nut_init);
plugin_register_shutdown("nut", nut_shutdown);
} /* void module_register */
-
-/* vim: set sw=2 ts=8 sts=2 tw=78 : */
static const char *olsrd_get_node(void) /* {{{ */
{
if (config_node != NULL)
- return (config_node);
- return (OLSRD_DEFAULT_NODE);
+ return config_node;
+ return OLSRD_DEFAULT_NODE;
} /* }}} const char *olsrd_get_node */
static const char *olsrd_get_service(void) /* {{{ */
{
if (config_service != NULL)
- return (config_service);
- return (OLSRD_DEFAULT_SERVICE);
+ return config_service;
+ return OLSRD_DEFAULT_SERVICE;
} /* }}} const char *olsrd_get_service */
static void olsrd_set_node(const char *node) /* {{{ */
buffer[buffer_len] = 0;
}
- return (buffer_len);
+ return buffer_len;
} /* }}} size_t strchomp */
static size_t strtabsplit(char *string, char **fields, size_t size) /* {{{ */
break;
}
- return (i);
+ return i;
} /* }}} size_t strtabsplit */
static FILE *olsrd_connect(void) /* {{{ */
if (ai_return != 0) {
ERROR("olsrd plugin: getaddrinfo (%s, %s) failed: %s", olsrd_get_node(),
olsrd_get_service(), gai_strerror(ai_return));
- return (NULL);
+ return NULL;
}
fh = NULL;
freeaddrinfo(ai_list);
- return (fh);
+ return fh;
} /* }}} FILE *olsrd_connect */
__attribute__((nonnull(2))) static void
static int olsrd_cb_ignore(int lineno, /* {{{ */
size_t fields_num, char **fields) {
- return (0);
+ return 0;
} /* }}} int olsrd_cb_ignore */
static int olsrd_cb_links(int lineno, /* {{{ */
char *endptr;
if (config_want_links == OLSRD_WANT_NOT)
- return (0);
+ return 0;
/* Special handling of the first line. */
if (lineno <= 0) {
nlq_sum = 0.0;
nlq_num = 0;
- return (0);
+ return 0;
}
/* Special handling of the last line. */
olsrd_submit(/* p.-inst = */ "links", /* type = */ "signal_quality",
"average-nlq", nlq);
- return (0);
+ return 0;
}
if (fields_num != 6)
- return (-1);
+ return -1;
links_num++;
if (config_want_links == OLSRD_WANT_DETAIL) {
char type_instance[DATA_MAX_NAME_LEN];
- ssnprintf(type_instance, sizeof(type_instance), "%s-%s-lq", fields[0],
- fields[1]);
+ snprintf(type_instance, sizeof(type_instance), "%s-%s-lq", fields[0],
+ fields[1]);
DEBUG("olsrd plugin: links: type_instance = %s; lq = %g;", type_instance,
lq);
if (config_want_links == OLSRD_WANT_DETAIL) {
char type_instance[DATA_MAX_NAME_LEN];
- ssnprintf(type_instance, sizeof(type_instance), "%s-%s-rx", fields[0],
- fields[1]);
+ snprintf(type_instance, sizeof(type_instance), "%s-%s-rx", fields[0],
+ fields[1]);
DEBUG("olsrd plugin: links: type_instance = %s; nlq = %g;", type_instance,
lq);
}
}
- return (0);
+ return 0;
} /* }}} int olsrd_cb_links */
static int olsrd_cb_routes(int lineno, /* {{{ */
char *endptr;
if (config_want_routes == OLSRD_WANT_NOT)
- return (0);
+ return 0;
/* Special handling of the first line */
if (lineno <= 0) {
etx_sum = 0.0;
etx_num = 0;
- return (0);
+ return 0;
}
/* Special handling after the last line */
olsrd_submit(/* p.-inst = */ "routes", /* type = */ "route_etx", "average",
etx);
- return (0);
+ return 0;
}
if (fields_num != 5)
- return (-1);
+ return -1;
routes_num++;
}
}
- return (0);
+ return 0;
} /* }}} int olsrd_cb_routes */
static int olsrd_cb_topology(int lineno, /* {{{ */
char *endptr;
if (config_want_topology == OLSRD_WANT_NOT)
- return (0);
+ return 0;
/* Special handling of the first line */
if (lineno <= 0) {
lq_num = 0;
links_num = 0;
- return (0);
+ return 0;
}
/* Special handling after the last line */
olsrd_submit(/* p.-inst = */ "topology", /* type = */ "signal_quality",
/* t.-inst = */ "average", lq);
- return (0);
+ return 0;
}
if (fields_num != 5)
- return (-1);
+ return -1;
links_num++;
if (config_want_topology == OLSRD_WANT_DETAIL) {
char type_instance[DATA_MAX_NAME_LEN] = {0};
- ssnprintf(type_instance, sizeof(type_instance), "%s-%s-lq", fields[0],
- fields[1]);
+ snprintf(type_instance, sizeof(type_instance), "%s-%s-lq", fields[0],
+ fields[1]);
DEBUG("olsrd plugin: type_instance = %s; lq = %g;", type_instance, lq);
olsrd_submit(/* p.-inst = */ "topology", /* type = */ "signal_quality",
type_instance, lq);
} else {
char type_instance[DATA_MAX_NAME_LEN] = {0};
- ssnprintf(type_instance, sizeof(type_instance), "%s-%s-nlq", fields[0],
- fields[1]);
+ snprintf(type_instance, sizeof(type_instance), "%s-%s-nlq", fields[0],
+ fields[1]);
DEBUG("olsrd plugin: type_instance = %s; nlq = %g;", type_instance, nlq);
olsrd_submit(/* p.-inst = */ "topology", /* type = */ "signal_quality",
type_instance, nlq);
}
}
- return (0);
+ return 0;
} /* }}} int olsrd_cb_topology */
static int olsrd_read_table(FILE *fh, /* {{{ */
lineno++;
} /* while (fgets) */
- return (0);
+ return 0;
} /* }}} int olsrd_read_table */
static int olsrd_config(const char *key, const char *value) /* {{{ */
olsrd_set_detail(&config_want_topology, value, key);
else {
ERROR("olsrd plugin: Unknown configuration option given: %s", key);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int olsrd_config */
static int olsrd_read(void) /* {{{ */
fh = olsrd_connect();
if (fh == NULL)
- return (-1);
+ return -1;
fputs("\r\n", fh);
fflush(fh);
fclose(fh);
- return (0);
+ return 0;
} /* }}} int olsrd_read */
static int olsrd_shutdown(void) /* {{{ */
sfree(config_node);
sfree(config_service);
- return (0);
+ return 0;
} /* }}} int olsrd_shutdown */
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 : */
result->tv_sec = diff / 1000000;
result->tv_usec = diff % 1000000;
- return (diff < 0);
+ return diff < 0;
}
#endif /* COLLECT_DEBUG */
if (regcomp(®ex_direct, regexp_to_match, REG_EXTENDED)) {
ERROR("onewire plugin: Cannot compile regex");
direct_list_element_free(element);
- return (1);
+ return 1;
}
regex_direct_initialized = 1;
DEBUG("onewire plugin: Compiled regex!!");
if (ignorelist_add(sensor_list, value)) {
ERROR("onewire plugin: Cannot add value to ignorelist.");
- return (1);
+ return 1;
}
} else {
DEBUG("onewire plugin: %s is a direct access", value);
temp = strdup(value);
if (temp == NULL) {
ERROR("onewire plugin: strdup failed.");
- return (1);
+ return 1;
}
sfree(device_g);
device_g = temp;
else
ERROR("onewire plugin: Invalid `Interval' setting: %s", value);
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static int cow_read_values(const char *path, const char *name,
ERROR("onewire plugin: OW_get (%s/%s) failed. error = %s;", path,
family_info->features[i].filename,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
DEBUG("Read onewire device %s as %s", file, buffer);
free(buffer);
} /* for (i = 0; i < features_num; i++) */
- return ((success > 0) ? 0 : -1);
+ return (success > 0) ? 0 : -1;
} /* int cow_read_values */
/* Forward declaration so the recursion below works */
char subpath[4096];
int status;
- status = ssnprintf(subpath, sizeof(subpath), "%s/main", path);
+ status = snprintf(subpath, sizeof(subpath), "%s/main", path);
if ((status > 0) && (status < (int)sizeof(subpath)))
cow_read_bus(subpath);
- status = ssnprintf(subpath, sizeof(subpath), "%s/aux", path);
+ status = snprintf(subpath, sizeof(subpath), "%s/aux", path);
if ((status > 0) && (status < (int)sizeof(subpath)))
cow_read_bus(subpath);
- return (0);
+ return 0;
} /* int cow_read_ds2409 */
static int cow_read_bus(const char *path) {
if (status < 0) {
ERROR("onewire plugin: OW_get (%s) failed. error = %s;", path,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
DEBUG("onewire plugin: OW_get (%s) returned: %s", path, buffer);
dummy = NULL;
if (strcmp("/", path) == 0)
- status = ssnprintf(subpath, sizeof(subpath), "/%s", buffer_ptr);
+ status = snprintf(subpath, sizeof(subpath), "/%s", buffer_ptr);
else
- status = ssnprintf(subpath, sizeof(subpath), "%s/%s", path, buffer_ptr);
+ status = snprintf(subpath, sizeof(subpath), "%s/%s", path, buffer_ptr);
if ((status <= 0) || (status >= (int)sizeof(subpath)))
continue;
} /* while (strtok_r) */
free(buffer);
- return (0);
+ return 0;
} /* int cow_read_bus */
/* ===================================================================================
if (status < 0) {
ERROR("onewire plugin: OW_get (%s) failed. status = %s;", traverse->path,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
DEBUG("onewire plugin: Read onewire device %s as %s", traverse->path,
buffer);
regfree(®ex_direct);
}
- return (0);
+ return 0;
} /* int cow_shutdown */
static int cow_init(void) {
if (device_g == NULL) {
ERROR("onewire plugin: cow_init: No device configured.");
- return (-1);
+ return -1;
}
DEBUG("onewire plugin: about to init device <%s>.", device_g);
if (status != 0) {
ERROR("onewire plugin: OW_init(%s) failed: %s.", device_g,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
+ return 1;
}
plugin_register_complex_read(/* group = */ NULL, "onewire", cow_read,
ow_interval, /* user data = */ NULL);
plugin_register_shutdown("onewire", cow_shutdown);
- return (0);
+ return 0;
} /* int cow_init */
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 : */
char *password;
char *cacert;
char *host;
- int state;
_Bool starttls;
int timeout;
char *url;
};
typedef struct cldap_s cldap_t; /* }}} */
-static cldap_t **databases = NULL;
-static size_t databases_num = 0;
-
-static void cldap_free(cldap_t *st) /* {{{ */
+static void cldap_free(void *arg) /* {{{ */
{
+ cldap_t *st = arg;
+
if (st == NULL)
return;
sfree(st->name);
sfree(st->url);
if (st->ld)
- ldap_memfree(st->ld);
+ ldap_unbind_ext_s(st->ld, NULL, NULL);
+
sfree(st);
} /* }}} void cldap_free */
/* initialize ldap for each host */
static int cldap_init_host(cldap_t *st) /* {{{ */
{
- LDAP *ld;
int rc;
- if (st->state && st->ld) {
+ if (st->ld) {
DEBUG("openldap plugin: Already connected to %s", st->url);
- return (0);
+ return 0;
}
- rc = ldap_initialize(&ld, st->url);
+ rc = ldap_initialize(&st->ld, st->url);
if (rc != LDAP_SUCCESS) {
ERROR("openldap plugin: ldap_initialize failed: %s", ldap_err2string(rc));
- st->state = 0;
- if (ld != NULL)
- ldap_unbind_ext_s(ld, NULL, NULL);
+ if (st->ld != NULL)
+ ldap_unbind_ext_s(st->ld, NULL, NULL);
+ st->ld = NULL;
return (-1);
}
- st->ld = ld;
-
ldap_set_option(st->ld, LDAP_OPT_PROTOCOL_VERSION, &st->version);
ldap_set_option(st->ld, LDAP_OPT_TIMEOUT,
}
if (st->starttls != 0) {
- rc = ldap_start_tls_s(ld, NULL, NULL);
+ rc = ldap_start_tls_s(st->ld, NULL, NULL);
if (rc != LDAP_SUCCESS) {
ERROR("openldap plugin: Failed to start tls on %s: %s", st->url,
ldap_err2string(rc));
- st->state = 0;
- if (st->ld != NULL)
- ldap_unbind_ext_s(st->ld, NULL, NULL);
+ ldap_unbind_ext_s(st->ld, NULL, NULL);
+ st->ld = NULL;
return (-1);
}
}
if (rc != LDAP_SUCCESS) {
ERROR("openldap plugin: Failed to bind to %s: %s", st->url,
ldap_err2string(rc));
- st->state = 0;
- if (st->ld != NULL)
- ldap_unbind_ext_s(st->ld, NULL, NULL);
+ ldap_unbind_ext_s(st->ld, NULL, NULL);
+ st->ld = NULL;
return (-1);
} else {
DEBUG("openldap plugin: Successfully connected to %s", st->url);
- st->state = 1;
- return (0);
+ return 0;
}
} /* }}} static cldap_init_host */
if ((ud == NULL) || (ud->data == NULL)) {
ERROR("openldap plugin: cldap_read_host: Invalid user data.");
- return (-1);
+ return -1;
}
st = (cldap_t *)ud->data;
status = cldap_init_host(st);
if (status != 0)
- return (-1);
+ return -1;
rc = ldap_search_ext_s(st->ld, "cn=Monitor", LDAP_SCOPE_SUBTREE,
"(|(!(cn=* *))(cn=Database*))", attrs, 0, NULL, NULL,
if (rc != LDAP_SUCCESS) {
ERROR("openldap plugin: Failed to execute search: %s", ldap_err2string(rc));
ldap_msgfree(result);
- st->state = 0;
- if (st->ld != NULL)
- ldap_unbind_ext_s(st->ld, NULL, NULL);
+ ldap_unbind_ext_s(st->ld, NULL, NULL);
+ st->ld = NULL;
return (-1);
}
if ((olmbdb_list =
ldap_get_values_len(st->ld, e, "olmBDBEntryCache")) != NULL) {
olmbdb_data = *olmbdb_list[0];
- ssnprintf(typeinst, sizeof(typeinst), "bdbentrycache-%s",
- nc_data.bv_val);
+ snprintf(typeinst, sizeof(typeinst), "bdbentrycache-%s",
+ nc_data.bv_val);
cldap_submit_gauge("cache_size", typeinst, atoll(olmbdb_data.bv_val),
st);
ldap_value_free_len(olmbdb_list);
if ((olmbdb_list = ldap_get_values_len(st->ld, e, "olmBDBDNCache")) !=
NULL) {
olmbdb_data = *olmbdb_list[0];
- ssnprintf(typeinst, sizeof(typeinst), "bdbdncache-%s",
- nc_data.bv_val);
+ snprintf(typeinst, sizeof(typeinst), "bdbdncache-%s", nc_data.bv_val);
cldap_submit_gauge("cache_size", typeinst, atoll(olmbdb_data.bv_val),
st);
ldap_value_free_len(olmbdb_list);
if ((olmbdb_list = ldap_get_values_len(st->ld, e, "olmBDBIDLCache")) !=
NULL) {
olmbdb_data = *olmbdb_list[0];
- ssnprintf(typeinst, sizeof(typeinst), "bdbidlcache-%s",
- nc_data.bv_val);
+ snprintf(typeinst, sizeof(typeinst), "bdbidlcache-%s",
+ nc_data.bv_val);
cldap_submit_gauge("cache_size", typeinst, atoll(olmbdb_data.bv_val),
st);
ldap_value_free_len(olmbdb_list);
}
ldap_msgfree(result);
- return (0);
+ return 0;
} /* }}} int cldap_read_host */
/* Configuration handling functions {{{
st = calloc(1, sizeof(*st));
if (st == NULL) {
ERROR("openldap plugin: calloc failed.");
- return (-1);
+ return -1;
}
status = cf_util_get_string(ci, &st->name);
if (status != 0) {
sfree(st);
- return (status);
+ return status;
}
st->starttls = 0;
ldap_free_urldesc(ludpp);
}
- if (status == 0) {
- cldap_t **temp;
-
- temp = (cldap_t **)realloc(databases,
- sizeof(*databases) * (databases_num + 1));
-
- if (temp == NULL) {
- ERROR("openldap plugin: realloc failed");
- status = -1;
- } else {
- char callback_name[3 * DATA_MAX_NAME_LEN] = {0};
-
- databases = temp;
- databases[databases_num] = st;
- databases_num++;
-
- ssnprintf(callback_name, sizeof(callback_name), "openldap/%s/%s",
- (st->host != NULL) ? st->host : hostname_g,
- (st->name != NULL) ? st->name : "default");
-
- status = plugin_register_complex_read(/* group = */ NULL,
- /* name = */ callback_name,
- /* callback = */ cldap_read_host,
- /* interval = */ 0, &(user_data_t){
- .data = st,
- });
- }
- }
-
if (status != 0) {
cldap_free(st);
- return (-1);
+ return -1;
}
- return (0);
+ char callback_name[3 * DATA_MAX_NAME_LEN] = {0};
+
+ snprintf(callback_name, sizeof(callback_name), "openldap/%s/%s",
+ (st->host != NULL) ? st->host : hostname_g,
+ (st->name != NULL) ? st->name : "default");
+
+ return plugin_register_complex_read(/* group = */ NULL,
+ /* name = */ callback_name,
+ /* callback = */ cldap_read_host,
+ /* interval = */ 0,
+ &(user_data_t){
+ .data = st, .free_func = cldap_free,
+ });
} /* }}} int cldap_config_add */
static int cldap_config(oconfig_item_t *ci) /* {{{ */
child->key);
} /* for (ci->children) */
- return (status);
+ return status;
} /* }}} int cldap_config */
/* }}} End of configuration handling functions */
* ldap_initialize(3) */
int debug_level;
ldap_get_option(NULL, LDAP_OPT_DEBUG_LEVEL, &debug_level);
- return (0);
+ return 0;
} /* }}} int cldap_init */
-static int cldap_shutdown(void) /* {{{ */
-{
- for (size_t i = 0; i < databases_num; i++)
- if (databases[i]->ld != NULL)
- ldap_unbind_ext_s(databases[i]->ld, NULL, NULL);
- sfree(databases);
- databases_num = 0;
-
- return (0);
-} /* }}} int cldap_shutdown */
-
void module_register(void) /* {{{ */
{
plugin_register_complex_config("openldap", cldap_config);
plugin_register_init("openldap", cldap_init);
- plugin_register_shutdown("openldap", cldap_shutdown);
} /* }}} void module_register */
#if defined(__APPLE__)
* Florian octo Forster <octo at collectd.org>
* Marco Chiappero <marco at absence.it>
* Fabian Schuh <mail at xeroc.org>
+ * Pavel Rochnyak <pavel2000 ngs.ru>
**/
#include "collectd.h"
#include "common.h"
#include "plugin.h"
-#define V1STRING \
+/**
+ * There is two main kinds of OpenVPN status file:
+ * - for 'single' mode (point-to-point or client mode)
+ * - for 'multi' mode (server with multiple clients)
+ *
+ * For 'multi' there is 3 versions of status file format:
+ * - version 1 - First version of status file: without line type tokens,
+ * comma delimited for easy machine parsing. Currently used by default.
+ * Added in openvpn-2.0-beta3.
+ * - version 2 - with line type tokens, with 'HEADER' line type, uses comma
+ * as a delimiter.
+ * Added in openvpn-2.0-beta15.
+ * - version 3 - The only difference from version 2 is delimiter: in version 3
+ * tabs are used instead of commas. Set of fields is the same.
+ * Added in openvpn-2.1_rc14.
+ *
+ * For versions 2/3 there may be different sets of fields in different
+ * OpenVPN versions.
+ *
+ * Versions 2.0, 2.1, 2.2:
+ * Common Name,Real Address,Virtual Address,
+ * Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t)
+ *
+ * Version 2.3:
+ * Common Name,Real Address,Virtual Address,
+ * Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t),Username
+ *
+ * Version 2.4:
+ * Common Name,Real Address,Virtual Address,Virtual IPv6 Address,
+ * Bytes Received,Bytes Sent,Connected Since,Connected Since (time_t),Username,
+ * Client ID,Peer ID
+ *
+ * Current Collectd code tries to handle changes in this field set,
+ * if they are backward-compatible.
+ **/
+
+#define TITLE_SINGLE "OpenVPN STATISTICS\n"
+#define TITLE_V1 "OpenVPN CLIENT LIST\n"
+#define TITLE_V2 "TITLE"
+
+#define V1HEADER \
"Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since\n"
-#define V2STRING \
- "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes " \
- "Received,Bytes Sent,Connected Since,Connected Since (time_t)\n"
-#define V3STRING \
- "HEADER CLIENT_LIST Common Name Real Address Virtual Address Bytes " \
- "Received Bytes Sent Connected Since Connected Since (time_t)\n"
-#define V4STRING \
- "HEADER,CLIENT_LIST,Common Name,Real Address,Virtual Address,Bytes " \
- "Received,Bytes Sent,Connected Since,Connected Since (time_t),Username\n"
-#define VSSTRING "OpenVPN STATISTICS\n"
struct vpn_status_s {
char *file;
- enum {
- MULTI1 = 1, /* status-version 1 */
- MULTI2, /* status-version 2 */
- MULTI3, /* status-version 3 */
- MULTI4, /* status-version 4 */
- SINGLE = 10 /* currently no versions for single mode, maybe in the future */
- } version;
char *name;
};
typedef struct vpn_status_s vpn_status_t;
-static vpn_status_t **vpn_list = NULL;
-static int vpn_num = 0;
-
static _Bool new_naming_schema = 0;
static _Bool collect_compression = 1;
static _Bool collect_user_count = 0;
static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
/* Helper function
- * copy-n-pasted from common.c - changed delim to "," */
+ * copy-n-pasted from common.c - changed delim to ",\t" */
static int openvpn_strsplit(char *string, char **fields, size_t size) {
- size_t i;
- char *ptr;
- char *saveptr;
-
- i = 0;
- ptr = string;
- saveptr = NULL;
- while ((fields[i] = strtok_r(ptr, ",", &saveptr)) != NULL) {
+ size_t i = 0;
+ char *ptr = string;
+ char *saveptr = NULL;
+
+ while ((fields[i] = strtok_r(ptr, ",\t", &saveptr)) != NULL) {
ptr = NULL;
i++;
break;
}
- return (i);
+ return i;
} /* int openvpn_strsplit */
+static void openvpn_free(void *arg) {
+ vpn_status_t *st = arg;
+
+ sfree(st->file);
+ sfree(st);
+} /* void openvpn_free */
+
/* dispatches number of users */
static void numusers_submit(const char *pinst, const char *tinst,
gauge_t value) {
char buffer[1024];
char *fields[4];
const int max_fields = STATIC_ARRAY_SIZE(fields);
- int fields_num, read = 0;
-
- derive_t link_rx, link_tx;
- derive_t tun_rx, tun_tx;
- derive_t pre_compress, post_compress;
- derive_t pre_decompress, post_decompress;
- derive_t overhead_rx, overhead_tx;
-
- link_rx = 0;
- link_tx = 0;
- tun_rx = 0;
- tun_tx = 0;
- pre_compress = 0;
- post_compress = 0;
- pre_decompress = 0;
- post_decompress = 0;
+
+ derive_t link_rx = 0, link_tx = 0;
+ derive_t tun_rx = 0, tun_tx = 0;
+ derive_t pre_compress = 0, post_compress = 0;
+ derive_t pre_decompress = 0, post_decompress = 0;
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
- fields_num = openvpn_strsplit(buffer, fields, max_fields);
+ int fields_num = openvpn_strsplit(buffer, fields, max_fields);
/* status file is generated by openvpn/sig.c:print_status()
* http://svn.openvpn.net/projects/openvpn/trunk/openvpn/sig.c
iostats_submit(name, "traffic", link_rx, link_tx);
/* we need to force this order to avoid negative values with these unsigned */
- overhead_rx = (((link_rx - pre_decompress) + post_decompress) - tun_rx);
- overhead_tx = (((link_tx - post_compress) + pre_compress) - tun_tx);
+ derive_t overhead_rx =
+ (((link_rx - pre_decompress) + post_decompress) - tun_rx);
+ derive_t overhead_tx = (((link_tx - post_compress) + pre_compress) - tun_tx);
iostats_submit(name, "overhead", overhead_rx, overhead_tx);
compression_submit(name, "data_out", pre_compress, post_compress);
}
- read = 1;
-
- return (read);
+ return 0;
} /* int single_read */
/* for reading status version 1 */
static int multi1_read(const char *name, FILE *fh) {
char buffer[1024];
char *fields[10];
- int fields_num, found_header = 0;
+ const int max_fields = STATIC_ARRAY_SIZE(fields);
long long sum_users = 0;
+ _Bool found_header = 0;
/* read the file until the "ROUTING TABLE" line is found (no more info after)
*/
if (strcmp(buffer, "ROUTING TABLE\n") == 0)
break;
- if (strcmp(buffer, V1STRING) == 0) {
+ if (strcmp(buffer, V1HEADER) == 0) {
found_header = 1;
continue;
}
/* we can't start reading data until this string is found */
continue;
- fields_num = openvpn_strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields));
+ int fields_num = openvpn_strsplit(buffer, fields, max_fields);
if (fields_num < 4)
continue;
}
if (ferror(fh))
- return (0);
+ return -1;
+
+ if (found_header == 0) {
+ NOTICE("openvpn plugin: Unknown file format in instance %s, please "
+ "report this as bug. Make sure to include "
+ "your status file, so the plugin can "
+ "be adapted.",
+ name);
+ return -1;
+ }
if (collect_user_count)
numusers_submit(name, name, sum_users);
- return (1);
+ return 0;
} /* int multi1_read */
-/* for reading status version 2 */
+/* for reading status version 2 / version 3
+ * status file is generated by openvpn/multi.c:multi_print_status()
+ * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c
+ */
static int multi2_read(const char *name, FILE *fh) {
char buffer[1024];
- char *fields[10];
+ /* OpenVPN-2.4 has 11 fields of data + 2 fields for "HEADER" and "CLIENT_LIST"
+ * So, set array size to 20 elements, to support future extensions.
+ */
+ char *fields[20];
const int max_fields = STATIC_ARRAY_SIZE(fields);
- int fields_num, read = 0;
long long sum_users = 0;
- while (fgets(buffer, sizeof(buffer), fh) != NULL) {
- fields_num = openvpn_strsplit(buffer, fields, max_fields);
-
- /* status file is generated by openvpn/multi.c:multi_print_status()
- * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c
- *
- * The line we're expecting has 8 fields. We ignore all lines
- * with more or less fields.
- */
- if (fields_num != 8)
- continue;
-
- if (strcmp(fields[0], "CLIENT_LIST") != 0)
- continue;
-
- if (collect_user_count)
- /* If so, sum all users, ignore the individuals*/
- {
- sum_users += 1;
- }
- if (collect_individual_users) {
- if (new_naming_schema) {
- /* plugin inst = file name, type inst = fields[1] */
- iostats_submit(name, /* vpn instance */
- fields[1], /* "Common Name" */
- atoll(fields[4]), /* "Bytes Received" */
- atoll(fields[5])); /* "Bytes Sent" */
- } else {
- /* plugin inst = fields[1], type inst = "" */
- iostats_submit(fields[1], /* "Common Name" */
- NULL, /* unused when in multimode */
- atoll(fields[4]), /* "Bytes Received" */
- atoll(fields[5])); /* "Bytes Sent" */
- }
- }
-
- read = 1;
- }
-
- if (collect_user_count) {
- numusers_submit(name, name, sum_users);
- read = 1;
- }
-
- return (read);
-} /* int multi2_read */
-
-/* for reading status version 3 */
-static int multi3_read(const char *name, FILE *fh) {
- char buffer[1024];
- char *fields[15];
- const int max_fields = STATIC_ARRAY_SIZE(fields);
- int fields_num, read = 0;
- long long sum_users = 0;
+ _Bool found_header = 0;
+ int idx_cname = 0;
+ int idx_bytes_recv = 0;
+ int idx_bytes_sent = 0;
+ int columns = 0;
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
- fields_num = strsplit(buffer, fields, max_fields);
+ int fields_num = openvpn_strsplit(buffer, fields, max_fields);
- /* status file is generated by openvpn/multi.c:multi_print_status()
- * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c
- *
- * The line we're expecting has 12 fields. We ignore all lines
- * with more or less fields.
- */
- if (fields_num != 12) {
- continue;
- } else {
- if (strcmp(fields[0], "CLIENT_LIST") != 0)
+ /* Try to find section header */
+ if (found_header == 0) {
+ if (fields_num < 2)
+ continue;
+ if (strcmp(fields[0], "HEADER") != 0)
+ continue;
+ if (strcmp(fields[1], "CLIENT_LIST") != 0)
continue;
- if (collect_user_count)
- /* If so, sum all users, ignore the individuals*/
- {
- sum_users += 1;
- }
-
- if (collect_individual_users) {
- if (new_naming_schema) {
- iostats_submit(name, /* vpn instance */
- fields[1], /* "Common Name" */
- atoll(fields[4]), /* "Bytes Received" */
- atoll(fields[5])); /* "Bytes Sent" */
- } else {
- iostats_submit(fields[1], /* "Common Name" */
- NULL, /* unused when in multimode */
- atoll(fields[4]), /* "Bytes Received" */
- atoll(fields[5])); /* "Bytes Sent" */
+ for (int i = 2; i < fields_num; i++) {
+ if (strcmp(fields[i], "Common Name") == 0) {
+ idx_cname = i - 1;
+ } else if (strcmp(fields[i], "Bytes Received") == 0) {
+ idx_bytes_recv = i - 1;
+ } else if (strcmp(fields[i], "Bytes Sent") == 0) {
+ idx_bytes_sent = i - 1;
}
}
- read = 1;
- }
- }
+ DEBUG("openvpn plugin: found MULTI v2/v3 HEADER. "
+ "Column idx: cname: %d, bytes_recv: %d, bytes_sent: %d",
+ idx_cname, idx_bytes_recv, idx_bytes_sent);
- if (collect_user_count) {
- numusers_submit(name, name, sum_users);
- read = 1;
- }
+ if (idx_cname == 0 || idx_bytes_recv == 0 || idx_bytes_sent == 0)
+ break;
- return (read);
-} /* int multi3_read */
+ /* Data row has 1 field ("HEADER") less than header row */
+ columns = fields_num - 1;
-/* for reading status version 4 */
-static int multi4_read(const char *name, FILE *fh) {
- char buffer[1024];
- char *fields[11];
- const int max_fields = STATIC_ARRAY_SIZE(fields);
- int fields_num, read = 0;
- long long sum_users = 0;
-
- while (fgets(buffer, sizeof(buffer), fh) != NULL) {
- fields_num = openvpn_strsplit(buffer, fields, max_fields);
+ found_header = 1;
+ continue;
+ }
- /* status file is generated by openvpn/multi.c:multi_print_status()
- * http://svn.openvpn.net/projects/openvpn/trunk/openvpn/multi.c
- *
- * The line we're expecting has 9 fields. We ignore all lines
- * with more or less fields.
+ /* Header already found. Check if the line is the section data.
+ * If no match, then section was finished and there is no more data.
+ * Empty section is OK too.
*/
- if (fields_num != 9)
- continue;
+ if (fields_num == 0 || strcmp(fields[0], "CLIENT_LIST") != 0)
+ break;
- if (strcmp(fields[0], "CLIENT_LIST") != 0)
- continue;
+ /* Check if the data line fields count matches header line. */
+ if (fields_num != columns) {
+ ERROR("openvpn plugin: File format error in instance %s: Fields count "
+ "mismatch.",
+ name);
+ return -1;
+ }
+
+ DEBUG("openvpn plugin: found MULTI v2/v3 CLIENT_LIST. "
+ "Columns: cname: %s, bytes_recv: %s, bytes_sent: %s",
+ fields[idx_cname], fields[idx_bytes_recv], fields[idx_bytes_sent]);
if (collect_user_count)
- /* If so, sum all users, ignore the individuals*/
- {
sum_users += 1;
- }
+
if (collect_individual_users) {
if (new_naming_schema) {
/* plugin inst = file name, type inst = fields[1] */
- iostats_submit(name, /* vpn instance */
- fields[1], /* "Common Name" */
- atoll(fields[4]), /* "Bytes Received" */
- atoll(fields[5])); /* "Bytes Sent" */
+ iostats_submit(name, /* vpn instance */
+ fields[idx_cname], /* "Common Name" */
+ atoll(fields[idx_bytes_recv]), /* "Bytes Received" */
+ atoll(fields[idx_bytes_sent])); /* "Bytes Sent" */
} else {
- /* plugin inst = fields[1], type inst = "" */
- iostats_submit(fields[1], /* "Common Name" */
- NULL, /* unused when in multimode */
- atoll(fields[4]), /* "Bytes Received" */
- atoll(fields[5])); /* "Bytes Sent" */
+ /* plugin inst = fields[idx_cname], type inst = "" */
+ iostats_submit(fields[idx_cname], /* "Common Name" */
+ NULL, /* unused when in multimode */
+ atoll(fields[idx_bytes_recv]), /* "Bytes Received" */
+ atoll(fields[idx_bytes_sent])); /* "Bytes Sent" */
}
}
+ }
- read = 1;
+ if (ferror(fh))
+ return -1;
+
+ if (found_header == 0) {
+ NOTICE("openvpn plugin: Unknown file format in instance %s, please "
+ "report this as bug. Make sure to include "
+ "your status file, so the plugin can "
+ "be adapted.",
+ name);
+ return -1;
}
if (collect_user_count) {
numusers_submit(name, name, sum_users);
- read = 1;
}
- return (read);
-} /* int multi4_read */
+ return 0;
+} /* int multi2_read */
/* read callback */
-static int openvpn_read(void) {
- FILE *fh;
- int read;
-
- read = 0;
-
- if (vpn_num == 0)
- return (0);
-
- /* call the right read function for every status entry in the list */
- for (int i = 0; i < vpn_num; i++) {
- int vpn_read = 0;
-
- fh = fopen(vpn_list[i]->file, "r");
- if (fh == NULL) {
- char errbuf[1024];
- WARNING("openvpn plugin: fopen(%s) failed: %s", vpn_list[i]->file,
- sstrerror(errno, errbuf, sizeof(errbuf)));
-
- continue;
- }
-
- switch (vpn_list[i]->version) {
- case SINGLE:
- vpn_read = single_read(vpn_list[i]->name, fh);
- break;
-
- case MULTI1:
- vpn_read = multi1_read(vpn_list[i]->name, fh);
- break;
-
- case MULTI2:
- vpn_read = multi2_read(vpn_list[i]->name, fh);
- break;
-
- case MULTI3:
- vpn_read = multi3_read(vpn_list[i]->name, fh);
- break;
-
- case MULTI4:
- vpn_read = multi4_read(vpn_list[i]->name, fh);
- break;
- }
-
- fclose(fh);
- read += vpn_read;
- }
-
- return (read ? 0 : -1);
-} /* int openvpn_read */
-
-static int version_detect(const char *filename) {
- FILE *fh;
+static int openvpn_read(user_data_t *user_data) {
char buffer[1024];
- int version = 0;
+ int read = 0;
- /* Sanity checking. We're called from the config handling routine, so
- * better play it save. */
- if ((filename == NULL) || (*filename == 0))
- return (0);
+ vpn_status_t *st = user_data->data;
- fh = fopen(filename, "r");
+ FILE *fh = fopen(st->file, "r");
if (fh == NULL) {
char errbuf[1024];
- WARNING("openvpn plugin: Unable to read \"%s\": %s", filename,
+ WARNING("openvpn plugin: fopen(%s) failed: %s", st->file,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (0);
+
+ return -1;
}
- /* now search for the specific multimode data format */
- while ((fgets(buffer, sizeof(buffer), fh)) != NULL) {
- /* we look at the first line searching for SINGLE mode configuration */
- if (strcmp(buffer, VSSTRING) == 0) {
- DEBUG("openvpn plugin: found status file version SINGLE");
- version = SINGLE;
- break;
- }
- /* searching for multi version 1 */
- else if (strcmp(buffer, V1STRING) == 0) {
- DEBUG("openvpn plugin: found status file version MULTI1");
- version = MULTI1;
- break;
- }
- /* searching for multi version 2 */
- else if (strcmp(buffer, V2STRING) == 0) {
- DEBUG("openvpn plugin: found status file version MULTI2");
- version = MULTI2;
- break;
- }
- /* searching for multi version 3 */
- else if (strcmp(buffer, V3STRING) == 0) {
- DEBUG("openvpn plugin: found status file version MULTI3");
- version = MULTI3;
- break;
- }
- /* searching for multi version 4 */
- else if (strcmp(buffer, V4STRING) == 0) {
- DEBUG("openvpn plugin: found status file version MULTI4");
- version = MULTI4;
- break;
- }
+ // Try to detect file format by its first line
+ if ((fgets(buffer, sizeof(buffer), fh)) == NULL) {
+ WARNING("openvpn plugin: failed to get data from: %s", st->file);
+ fclose(fh);
+ return -1;
}
- if (version == 0) {
- /* This is only reached during configuration, so complaining to
- * the user is in order. */
+ if (strcmp(buffer, TITLE_SINGLE) == 0) { // OpenVPN STATISTICS
+ DEBUG("openvpn plugin: found status file SINGLE");
+ read = single_read(st->name, fh);
+ } else if (strcmp(buffer, TITLE_V1) == 0) { // OpenVPN CLIENT LIST
+ DEBUG("openvpn plugin: found status file MULTI version 1");
+ read = multi1_read(st->name, fh);
+ } else if (strncmp(buffer, TITLE_V2, strlen(TITLE_V2)) == 0) { // TITLE
+ DEBUG("openvpn plugin: found status file MULTI version 2/3");
+ read = multi2_read(st->name, fh);
+ } else {
NOTICE("openvpn plugin: %s: Unknown file format, please "
"report this as bug. Make sure to include "
"your status file, so the plugin can "
"be adapted.",
- filename);
+ st->file);
+ read = -1;
}
-
fclose(fh);
-
- return version;
-} /* int version_detect */
+ return read;
+} /* int openvpn_read */
static int openvpn_config(const char *key, const char *value) {
if (strcasecmp("StatusFile", key) == 0) {
- char *status_file, *status_name, *filename;
- int status_version;
- vpn_status_t *temp;
-
- /* try to detect the status file format */
- status_version = version_detect(value);
-
- if (status_version == 0) {
- WARNING("openvpn plugin: unable to detect status version, "
- "discarding status file \"%s\".",
- value);
- return (1);
- }
+ char callback_name[3 * DATA_MAX_NAME_LEN];
+ char *status_name;
- status_file = sstrdup(value);
+ char *status_file = strdup(value);
if (status_file == NULL) {
char errbuf[1024];
- WARNING("openvpn plugin: sstrdup failed: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
+ ERROR("openvpn plugin: strdup failed: %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return 1;
}
/* it determines the file name as string starting at location filename + 1
*/
- filename = strrchr(status_file, (int)'/');
+ char *filename = strrchr(status_file, (int)'/');
if (filename == NULL) {
/* status_file is already the file name only */
status_name = status_file;
status_name = filename + 1;
}
- /* scan the list looking for a clone */
- for (int i = 0; i < vpn_num; i++) {
- if (strcasecmp(vpn_list[i]->name, status_name) == 0) {
- WARNING("openvpn plugin: status filename \"%s\" "
- "already used, please choose a "
- "different one.",
- status_name);
- sfree(status_file);
- return (1);
- }
- }
-
- /* create a new vpn element since file, version and name are ok */
- temp = malloc(sizeof(*temp));
- if (temp == NULL) {
+ /* create a new vpn element */
+ vpn_status_t *instance = calloc(1, sizeof(*instance));
+ if (instance == NULL) {
char errbuf[1024];
ERROR("openvpn plugin: malloc failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
sfree(status_file);
- return (1);
+ return 1;
}
- temp->file = status_file;
- temp->version = status_version;
- temp->name = status_name;
-
- vpn_status_t **tmp_list =
- realloc(vpn_list, (vpn_num + 1) * sizeof(*vpn_list));
- if (tmp_list == NULL) {
- char errbuf[1024];
- ERROR("openvpn plugin: realloc failed: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
-
- sfree(vpn_list);
- sfree(temp->file);
- sfree(temp);
- return (1);
+ instance->file = status_file;
+ instance->name = status_name;
+
+ snprintf(callback_name, sizeof(callback_name), "openvpn/%s", status_name);
+
+ int status = plugin_register_complex_read(
+ /* group = */ "openvpn",
+ /* name = */ callback_name,
+ /* callback = */ openvpn_read,
+ /* interval = */ 0,
+ &(user_data_t){
+ .data = instance, .free_func = openvpn_free,
+ });
+
+ if (status == EINVAL) {
+ WARNING("openvpn plugin: status filename \"%s\" "
+ "already used, please choose a "
+ "different one.",
+ status_name);
+ return -1;
}
- vpn_list = tmp_list;
-
- vpn_list[vpn_num] = temp;
- vpn_num++;
-
- DEBUG("openvpn plugin: status file \"%s\" added", temp->file);
+ DEBUG("openvpn plugin: status file \"%s\" added", instance->file);
} /* if (strcasecmp ("StatusFile", key) == 0) */
else if ((strcasecmp("CollectCompression", key) == 0) ||
(strcasecmp("Compression", key) == 0)) /* old, deprecated name */
collect_individual_users = 1;
} /* if (strcasecmp("CollectIndividualUsers", key) == 0) */
else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int openvpn_config */
-/* shutdown callback */
-static int openvpn_shutdown(void) {
- for (int i = 0; i < vpn_num; i++) {
- sfree(vpn_list[i]->file);
- sfree(vpn_list[i]);
- }
-
- sfree(vpn_list);
-
- return (0);
-} /* int openvpn_shutdown */
-
static int openvpn_init(void) {
if (!collect_individual_users && !collect_compression &&
!collect_user_count) {
WARNING("OpenVPN plugin: Neither `CollectIndividualUsers', "
"`CollectCompression', nor `CollectUserCount' is true. There's no "
"data left to collect.");
- return (-1);
+ return -1;
}
- plugin_register_read("openvpn", openvpn_read);
- plugin_register_shutdown("openvpn", openvpn_shutdown);
-
- return (0);
+ return 0;
} /* int openvpn_init */
void module_register(void) {
config_keys_num);
plugin_register_init("openvpn", openvpn_init);
} /* void module_register */
-
-/* vim: set sw=2 ts=2 : */
char *connect_id;
char *username;
char *password;
+ char *plugin_name;
udb_query_preparation_area_t **q_prep_areas;
udb_query_t **queries;
sfree(db->username);
sfree(db->password);
sfree(db->queries);
+ sfree(db->plugin_name);
if (db->q_prep_areas != NULL)
for (size_t i = 0; i < db->queries_num; ++i)
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("oracle plugin: The `Database' block "
"needs exactly one string argument.");
- return (-1);
+ return -1;
}
db = calloc(1, sizeof(*db));
if (db == NULL) {
ERROR("oracle plugin: calloc failed.");
- return (-1);
+ return -1;
}
db->name = NULL;
db->host = NULL;
db->connect_id = NULL;
db->username = NULL;
db->password = NULL;
+ db->plugin_name = NULL;
status = cf_util_get_string(ci, &db->name);
if (status != 0) {
sfree(db);
- return (status);
+ return status;
}
/* Fill the `o_database_t' structure.. */
status = cf_util_get_string(child, &db->username);
else if (strcasecmp("Password", child->key) == 0)
status = cf_util_get_string(child, &db->password);
+ else if (strcasecmp("Plugin", child->key) == 0)
+ status = cf_util_get_string(child, &db->plugin_name);
else if (strcasecmp("Query", child->key) == 0)
status = udb_query_pick_from_list(child, queries, queries_num,
&db->queries, &db->queries_num);
if (status != 0) {
o_database_free(db);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int o_config_add_database */
static int o_config(oconfig_item_t *ci) /* {{{ */
}
} /* for (ci->children) */
- return (0);
+ return 0;
} /* }}} int o_config */
/* }}} End of configuration handling functions */
int status;
if (oci_env != NULL)
- return (0);
+ return 0;
status = OCIEnvCreate(&oci_env,
/* mode = */ OCI_THREADED,
/* user_data_ptr = */ NULL);
if (status != 0) {
ERROR("oracle plugin: OCIEnvCreate failed with status %i.", status);
- return (-1);
+ return -1;
}
status = OCIHandleAlloc(oci_env, (void *)&oci_error, OCI_HTYPE_ERROR,
ERROR("oracle plugin: OCIHandleAlloc (OCI_HTYPE_ERROR) failed "
"with status %i.",
status);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int o_init */
static int o_read_database_query(o_database_t *db, /* {{{ */
o_report_error("o_read_database_query", db->name, udb_query_get_name(q),
"OCIHandleAlloc", oci_error);
oci_statement = NULL;
- return (-1);
+ return -1;
}
status = OCIStmtPrepare(oci_statement, oci_error, (text *)statement,
"OCIStmtPrepare", oci_error);
OCIHandleFree(oci_statement, OCI_HTYPE_STMT);
oci_statement = NULL;
- return (-1);
+ return -1;
}
udb_query_set_user_data(q, oci_statement);
if (status != OCI_SUCCESS) {
o_report_error("o_read_database_query", db->name, udb_query_get_name(q),
"OCIStmtExecute", oci_error);
- return (-1);
+ return -1;
} /* }}} */
/* Acquire the number of columns returned. */
if (status != OCI_SUCCESS) {
o_report_error("o_read_database_query", db->name, udb_query_get_name(q),
"OCIAttrGet", oci_error);
- return (-1);
+ return -1;
} /* }}} */
column_num = (size_t)param_counter;
if ((ptr) == NULL) { \
FREE_ALL; \
ERROR("oracle plugin: o_read_database_query: calloc failed."); \
- return (-1); \
+ return -1; \
} \
} while (0)
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));
+ ALLOC_OR_FAIL(column_values[0], 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;
status = udb_query_prepare_result(
q, prep_area, (db->host != NULL) ? db->host : hostname_g,
- /* plugin = */ "oracle", db->name, column_names, column_num,
+ /* plugin = */ (db->plugin_name != NULL) ? db->plugin_name : "oracle",
+ db->name, column_names, column_num,
/* interval = */ 0);
if (status != 0) {
ERROR("oracle plugin: o_read_database_query (%s, %s): "
"udb_query_prepare_result failed.",
db->name, udb_query_get_name(q));
FREE_ALL;
- return (-1);
+ return -1;
}
/* Fetch and handle all the rows that matched the query. */
* %s", q->statement); */
FREE_ALL;
- return (0);
+ return 0;
#undef FREE_ALL
#undef ALLOC_OR_FAIL
} /* }}} int o_read_database_query */
if (status != OCI_SUCCESS) {
o_report_error("o_read_database", db->name, NULL, "OCIAttrGet",
oci_error);
- return (-1);
+ return -1;
}
if (server_handle == NULL) {
if (status != OCI_SUCCESS) {
o_report_error("o_read_database", db->name, NULL, "OCIAttrGet",
oci_error);
- return (-1);
+ return -1;
}
}
if ((status != OCI_SUCCESS) && (status != OCI_SUCCESS_WITH_INFO)) {
char errfunc[256];
- ssnprintf(errfunc, sizeof(errfunc), "OCILogon(\"%s\")", db->connect_id);
+ snprintf(errfunc, sizeof(errfunc), "OCILogon(\"%s\")", db->connect_id);
o_report_error("o_read_database", db->name, NULL, errfunc, oci_error);
DEBUG("oracle plugin: OCILogon (%s): db->oci_service_context = %p;",
db->connect_id, db->oci_service_context);
db->oci_service_context = NULL;
- return (-1);
+ return -1;
} else if (status == OCI_SUCCESS_WITH_INFO) {
/* TODO: Print NOTIFY message. */
}
for (size_t i = 0; i < db->queries_num; i++)
o_read_database_query(db, db->queries[i], db->q_prep_areas[i]);
- return (0);
+ return 0;
} /* }}} int o_read_database */
static int o_read(void) /* {{{ */
for (i = 0; i < databases_num; i++)
o_read_database(databases[i]);
- return (0);
+ return 0;
} /* }}} int o_read */
static int o_shutdown(void) /* {{{ */
queries = NULL;
queries_num = 0;
- return (0);
+ return 0;
} /* }}} int o_shutdown */
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
- */
--- /dev/null
+/**
+ * collectd - src/ovs_events.c
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ *of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to
+ *do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ *all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Volodymyr Mytnyk <volodymyrx.mytnyk@intel.com>
+ **/
+
+#include "collectd.h"
+
+#include "common.h" /* auxiliary functions */
+
+#include "utils_ovs.h" /* OVS helpers */
+
+#define OVS_EVENTS_IFACE_NAME_SIZE 128
+#define OVS_EVENTS_IFACE_UUID_SIZE 64
+#define OVS_EVENTS_EXT_IFACE_ID_SIZE 64
+#define OVS_EVENTS_EXT_VM_UUID_SIZE 64
+#define OVS_EVENTS_PLUGIN "ovs_events"
+#define OVS_EVENTS_CTX_LOCK \
+ for (int __i = ovs_events_ctx_lock(); __i != 0; __i = ovs_events_ctx_unlock())
+
+/* Link status type */
+enum ovs_events_link_status_e { DOWN, UP };
+typedef enum ovs_events_link_status_e ovs_events_link_status_t;
+
+/* Interface info */
+struct ovs_events_iface_info_s {
+ char name[OVS_EVENTS_IFACE_NAME_SIZE]; /* interface name */
+ char uuid[OVS_EVENTS_IFACE_UUID_SIZE]; /* interface UUID */
+ char ext_iface_id[OVS_EVENTS_EXT_IFACE_ID_SIZE]; /* external interface id */
+ char ext_vm_uuid[OVS_EVENTS_EXT_VM_UUID_SIZE]; /* external VM UUID */
+ ovs_events_link_status_t link_status; /* interface link status */
+ struct ovs_events_iface_info_s *next; /* next interface info */
+};
+typedef struct ovs_events_iface_info_s ovs_events_iface_info_t;
+
+/* Interface list */
+struct ovs_events_iface_list_s {
+ char name[OVS_EVENTS_IFACE_NAME_SIZE]; /* interface name */
+ struct ovs_events_iface_list_s *next; /* next interface info */
+};
+typedef struct ovs_events_iface_list_s ovs_events_iface_list_t;
+
+/* OVS events configuration data */
+struct ovs_events_config_s {
+ _Bool send_notification; /* sent notification to collectd? */
+ char ovs_db_node[OVS_DB_ADDR_NODE_SIZE]; /* OVS DB node */
+ char ovs_db_serv[OVS_DB_ADDR_SERVICE_SIZE]; /* OVS DB service */
+ char ovs_db_unix[OVS_DB_ADDR_UNIX_SIZE]; /* OVS DB unix socket path */
+ ovs_events_iface_list_t *ifaces; /* interface info */
+};
+typedef struct ovs_events_config_s ovs_events_config_t;
+
+/* OVS events context type */
+struct ovs_events_ctx_s {
+ pthread_mutex_t mutex; /* mutex to lock the context */
+ ovs_db_t *ovs_db; /* pointer to OVS DB instance */
+ ovs_events_config_t config; /* plugin config */
+ char *ovs_db_select_params; /* OVS DB select parameter request */
+ _Bool is_db_available; /* specify whether OVS DB is available */
+};
+typedef struct ovs_events_ctx_s ovs_events_ctx_t;
+
+/*
+ * Private variables
+ */
+static ovs_events_ctx_t ovs_events_ctx = {
+ .mutex = PTHREAD_MUTEX_INITIALIZER,
+ .config = {.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 = snprintf(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 (snprintf(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;
+ }
+ sstrncpy(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 */
+ snprintf(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);
+}
--- /dev/null
+/*
+ * 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 <tarasx.chornyi@intel.com>
+ */
+
+#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 = calloc(1, sizeof(*br));
+ if (!br) {
+ pthread_mutex_unlock(&g_stats_lock);
+ ERROR("%s: calloc(%zu) failed.", plugin_name, sizeof(*br));
+ 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);
+ ERROR("%s: strdup failed.", plugin_name);
+ 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) {
+ if (!iface || !YAJL_IS_OBJECT(iface)) {
+ ERROR("ovs_stats plugin: incorrect JSON port data");
+ return -1;
+ }
+
+ yajl_val row = ovs_utils_get_value_by_key(iface, "new");
+ if (!row || !YAJL_IS_OBJECT(row))
+ return 0;
+
+ yajl_val iface_name = ovs_utils_get_value_by_key(row, "name");
+ if (!iface_name || !YAJL_IS_STRING(iface_name))
+ return 0;
+
+ port_list_t *port = ovs_stats_get_port_by_name(YAJL_GET_STRING(iface_name));
+ if (port == NULL)
+ return 0;
+
+ 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");
+ /*
+ * {
+ "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));
+
+ 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;
+
+ 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 */
+ char const *br_name = child->values[j].value.string;
+ 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 {
+ char *br_name_dup = strdup(br_name);
+ if (br_name_dup == NULL) {
+ ERROR("%s: strdup() copy bridge name fail", plugin_name);
+ goto cleanup_fail;
+ }
+
+ pthread_mutex_lock(&g_stats_lock);
+ /* store bridge name */
+ bridge->name = br_name_dup;
+ 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);
+}
#undef DONT_POISON_SPRINTF_YET
-#if HAVE_STDBOOL_H
#include <stdbool.h>
-#endif
#include <EXTERN.h>
#include <perl.h>
{"Collectd::NOTIF_WARNING", NOTIF_WARNING},
{"Collectd::NOTIF_OKAY", NOTIF_OKAY},
{"", 0}};
-
-struct {
- char name[64];
- char *var;
-} g_strings[] = {{"Collectd::hostname_g", hostname_g}, {"", NULL}};
-
/*
* Helper functions for data type conversion.
*/
if (NULL != (tmp = hv_fetch(hash, "host", 4, 0)))
sstrncpy(vl->host, SvPV_nolen(*tmp), sizeof(vl->host));
- else
- sstrncpy(vl->host, hostname_g, sizeof(vl->host));
if (NULL != (tmp = hv_fetch(hash, "plugin", 6, 0)))
sstrncpy(vl->plugin, SvPV_nolen(*tmp), sizeof(vl->plugin));
static char *get_module_name(char *buf, size_t buf_len, const char *module) {
int status = 0;
if (base_name[0] == '\0')
- status = ssnprintf(buf, buf_len, "%s", module);
+ status = snprintf(buf, buf_len, "%s", module);
else
- status = ssnprintf(buf, buf_len, "%s::%s", base_name, module);
+ status = snprintf(buf, buf_len, "%s::%s", base_name, module);
if ((status < 0) || ((unsigned int)status >= buf_len))
- return (NULL);
- return (buf);
+ return NULL;
+ return buf;
} /* char *get_module_name */
/*
ret = plugin_register_flush("perl", perl_flush, /* user_data = */ NULL);
}
- if (0 == ret)
+ if (0 == ret) {
ret = plugin_register_flush(pluginname, perl_flush, &userdata);
+ } else {
+ free(userdata.data);
+ }
} else {
ret = -1;
}
if (0 == ret)
XSRETURN_YES;
- else {
- free(userdata.data);
+ else
XSRETURN_EMPTY;
- }
} /* static void _plugin_register_generic_userdata ( ... ) */
/*
/* Lock the base thread to avoid race conditions with c_ithread_create().
* See https://github.com/collectd/collectd/issues/9 and
* https://github.com/collectd/collectd/issues/1706 for details.
- */
+ */
assert(aTHX == perl_threads->head->interp);
pthread_mutex_lock(&perl_threads->mutex);
/* Lock the base thread if this is not called from one of the read threads
* to avoid race conditions with c_ithread_create(). See
* https://github.com/collectd/collectd/issues/9 for details.
- */
+ */
if (aTHX == perl_threads->head->interp)
pthread_mutex_lock(&perl_threads->mutex);
* accessing any such variable (this is basically the same as using
* tie() in Perl) */
/* global strings */
+ struct {
+ char name[64];
+ char *var;
+ } g_strings[] = {{"Collectd::hostname_g", hostname_g}, {"", NULL}};
+
for (int i = 0; '\0' != g_strings[i].name[0]; ++i) {
tmp = get_sv(g_strings[i].name, 1);
sv_magicext(tmp, NULL, PERL_MAGIC_ext, &g_pv_vtbl, g_strings[i].var, 0);
if (NULL == get_module_name(module_name, sizeof(module_name), value)) {
log_err("Invalid module name %s", value);
- return (1);
+ return 1;
}
if (0 != init_pi(perl_argc, perl_argv))
plugin_register_complex_config("perl", perl_config);
return;
} /* void module_register (void) */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
char errbuf[1024];
ERROR("pf plugin: Unable to open %s: %s", pf_device,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
status = ioctl(fd, DIOCGETSTATUS, &state);
ERROR("pf plugin: ioctl(DIOCGETSTATUS) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
close(fd);
- return (-1);
+ return -1;
}
close(fd);
if (!state.running) {
WARNING("pf plugin: PF is not running.");
- return (-1);
+ return -1;
}
for (int i = 0; i < PFRES_MAX; i++)
pf_submit("pf_states", "current", (uint32_t)state.states,
/* is gauge = */ 1);
- return (0);
+ return 0;
} /* int pf_read */
void module_register(void) { plugin_register_read("pf", pf_read); }
ret = (derive_t)(fc->i * factor);
ret += (derive_t)(fc->n / (1000000000 / factor));
- return (ret);
+ return ret;
} /* }}} derive_t float_counter_get */
static void strset(char **str, const char *new) /* {{{ */
/* reset node */
node->mem_peak = NAN;
- return (index + 1);
+ return index + 1;
} /* }}} unsigned int service_statnode_collect */
static void service_statnode_process(pinba_statnode_t *node, /* {{{ */
static int pb_del_socket(pinba_socket_t *s, /* {{{ */
nfds_t index) {
if (index >= s->fd_num)
- return (EINVAL);
+ return EINVAL;
close(s->fd[index].fd);
s->fd[index].fd = -1;
}
s->fd_num--;
- return (0);
+ return 0;
} /* }}} int pb_del_socket */
static int pb_add_socket(pinba_socket_t *s, /* {{{ */
"%i sockets. Please complain to the collectd developers so we can "
"raise the limit.",
PINBA_MAX_SOCKETS);
- return (-1);
+ return -1;
}
fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
char errbuf[1024];
ERROR("pinba plugin: socket(2) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (0);
+ return 0;
}
tmp = 1;
ERROR("pinba plugin: bind(2) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
close(fd);
- return (0);
+ return 0;
}
s->fd[s->fd_num].fd = fd;
s->fd[s->fd_num].revents = 0;
s->fd_num++;
- return (0);
+ return 0;
} /* }}} int pb_add_socket */
static pinba_socket_t *pinba_socket_open(const char *node, /* {{{ */
status = getaddrinfo(node, service, &ai_hints, &ai_list);
if (status != 0) {
ERROR("pinba plugin: getaddrinfo(3) failed: %s", gai_strerror(status));
- return (NULL);
+ return NULL;
}
assert(ai_list != NULL);
if (s == NULL) {
freeaddrinfo(ai_list);
ERROR("pinba plugin: calloc failed.");
- return (NULL);
+ return NULL;
}
for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
s = NULL;
}
- return (s);
+ return s;
} /* }}} pinba_socket_open */
static void pinba_socket_free(pinba_socket_t *socket) /* {{{ */
request = pinba__request__unpack(NULL, buffer_size, buffer);
if (!request)
- return (-1);
+ return -1;
service_process_request(request);
pinba__request__free_unpacked(request, NULL);
- return (0);
+ return 0;
} /* }}} int pinba_process_stats_packet */
static int pinba_udp_read_callback_fn(int sock) /* {{{ */
WARNING("pinba plugin: recvfrom(2) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
} else if (status == 0) {
DEBUG("pinba plugin: recvfrom(2) returned unexpected status zero.");
- return (-1);
+ return -1;
} else /* if (status > 0) */
{
assert(((size_t)status) < buffer_size);
status = pinba_process_stats_packet(buffer, buffer_size);
if (status != 0)
DEBUG("pinba plugin: Parsing packet failed.");
- return (status);
+ return status;
}
} /* while (42) */
/* not reached */
assert(23 == 42);
- return (-1);
+ return -1;
} /* }}} void pinba_udp_read_callback_fn */
static int receive_loop(void) /* {{{ */
s = pinba_socket_open(conf_node, conf_service);
if (s == NULL) {
ERROR("pinba plugin: Collector thread is exiting prematurely.");
- return (-1);
+ return -1;
}
while (!collector_thread_do_shutdown) {
ERROR("pinba plugin: poll(2) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
pinba_socket_free(s);
- return (-1);
+ return -1;
}
for (nfds_t i = 0; i < s->fd_num; i++) {
pinba_socket_free(s);
s = NULL;
- return (0);
+ return 0;
} /* }}} int receive_loop */
static void *collector_thread(void *arg) /* {{{ */
memset(&collector_thread_id, 0, sizeof(collector_thread_id));
collector_thread_running = 0;
pthread_exit(NULL);
- return (NULL);
+ return NULL;
} /* }}} void *collector_thread */
/*
status = cf_util_get_string(ci, &name);
if (status != 0)
- return (status);
+ return status;
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
sfree(server);
sfree(script);
- return (status);
+ return status;
} /* }}} int pinba_config_view */
static int plugin_config(oconfig_item_t *ci) /* {{{ */
pthread_mutex_unlock(&stat_nodes_lock);
- return (0);
+ return 0;
} /* }}} int pinba_config */
static int plugin_init(void) /* {{{ */
}
if (collector_thread_running)
- return (0);
+ return 0;
status = plugin_thread_create(&collector_thread_id,
/* attrs = */ NULL, collector_thread,
char errbuf[1024];
ERROR("pinba plugin: pthread_create(3) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
collector_thread_running = 1;
- return (0);
+ return 0;
} /* }}} */
static int plugin_shutdown(void) /* {{{ */
collector_thread_do_shutdown = 0;
} /* if (collector_thread_running) */
- return (0);
+ return 0;
} /* }}} int plugin_shutdown */
static int plugin_submit(const pinba_statnode_t *res) /* {{{ */
sstrncpy(vl.type_instance, "peak", sizeof(vl.type_instance));
plugin_dispatch_values(&vl);
- return (0);
+ return 0;
} /* }}} int plugin_submit */
static int plugin_read(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 : */
} /* }}} ping_max_missed */
} /* }}} for (iter) */
- return (0);
+ return 0;
} /* }}} int ping_dispatch_all */
static void *ping_thread(void *arg) /* {{{ */
pthread_mutex_lock(&ping_lock);
ping_thread_error = 1;
pthread_mutex_unlock(&ping_lock);
- return ((void *)-1);
+ return (void *)-1;
}
if (ping_source != NULL)
pthread_mutex_lock(&ping_lock);
ping_thread_error = 1;
pthread_mutex_unlock(&ping_lock);
- return ((void *)-1);
+ return (void *)-1;
}
/* Set up `ts_int' */
pthread_mutex_unlock(&ping_lock);
ping_destroy(pingobj);
- return ((void *)0);
+ return (void *)0;
} /* }}} void *ping_thread */
static int start_thread(void) /* {{{ */
if (ping_thread_loop != 0) {
pthread_mutex_unlock(&ping_lock);
- return (0);
+ return 0;
}
ping_thread_loop = 1;
ping_thread_loop = 0;
ERROR("ping plugin: Starting thread failed.");
pthread_mutex_unlock(&ping_lock);
- return (-1);
+ return -1;
}
pthread_mutex_unlock(&ping_lock);
- return (0);
+ return 0;
} /* }}} int start_thread */
static int stop_thread(void) /* {{{ */
if (ping_thread_loop == 0) {
pthread_mutex_unlock(&ping_lock);
- return (-1);
+ return -1;
}
ping_thread_loop = 0;
ping_thread_error = 0;
pthread_mutex_unlock(&ping_lock);
- return (status);
+ return status;
} /* }}} int stop_thread */
static int ping_init(void) /* {{{ */
{
if (hostlist_head == NULL) {
NOTICE("ping plugin: No hosts have been configured.");
- return (-1);
+ return -1;
}
if (ping_timeout > ping_interval) {
}
#endif
- return (start_thread());
+ return start_thread();
} /* }}} int ping_init */
static int config_set_string(const char *name, /* {{{ */
char errbuf[1024];
ERROR("ping plugin: Setting `%s' to `%s' failed: strdup failed: %s", name,
value, sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
+ return 1;
}
if (*var != NULL)
free(*var);
*var = tmp;
- return (0);
+ return 0;
} /* }}} int config_set_string */
static int ping_config(const char *key, const char *value) /* {{{ */
char errbuf[1024];
ERROR("ping plugin: malloc failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
+ return 1;
}
host = strdup(value);
sfree(hl);
ERROR("ping plugin: strdup failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (1);
+ return 1;
}
hl->host = host;
} else if (strcasecmp(key, "SourceAddress") == 0) {
int status = config_set_string(key, &ping_source, value);
if (status != 0)
- return (status);
+ return status;
}
#ifdef HAVE_OPING_1_3
else if (strcasecmp(key, "Device") == 0) {
int status = config_set_string(key, &ping_device, value);
if (status != 0)
- return (status);
+ return status;
}
#endif
else if (strcasecmp(key, "TTL") == 0) {
ping_data = malloc(size + 1);
if (ping_data == NULL) {
ERROR("ping plugin: malloc failed.");
- return (1);
+ return 1;
}
/* Note: By default oping is using constant string
if (ping_max_missed < 0)
INFO("ping plugin: MaxMissed < 0, disabled re-resolving of hosts");
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int ping_config */
static void submit(const char *host, const char *type, /* {{{ */
start_thread();
- return (-1);
+ return -1;
} /* if (ping_thread_error != 0) */
for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next) /* {{{ */
submit(hl->host, "ping_droprate", droprate);
} /* }}} for (hl = hostlist_head; hl != NULL; hl = hl->next) */
- return (0);
+ return 0;
} /* }}} int ping_read */
static int ping_shutdown(void) /* {{{ */
INFO("ping plugin: Shutting down thread.");
if (stop_thread() < 0)
- return (-1);
+ return -1;
hl = hostlist_head;
while (hl != NULL) {
ping_data = NULL;
}
- return (0);
+ return 0;
} /* }}} int ping_shutdown */
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 : */
* is ignored. */
#define C_PSQL_PAR_APPEND(buf, buf_len, parameter, value) \
if ((0 < (buf_len)) && (NULL != (value)) && ('\0' != *(value))) { \
- int s = ssnprintf(buf, buf_len, " %s = '%s'", parameter, value); \
+ int s = snprintf(buf, buf_len, " %s = '%s'", parameter, value); \
if (0 < s) { \
buf += s; \
buf_len -= s; \
char *password;
char *instance;
+ char *plugin_name;
char *sslmode;
db->instance = sstrdup(name);
+ db->plugin_name = NULL;
+
db->sslmode = NULL;
db->krbsrvname = NULL;
sfree(db->instance);
+ sfree(db->plugin_name);
+
sfree(db->sslmode);
sfree(db->krbsrvname);
if ((!db) || (!db->database))
return -1;
- status = ssnprintf(buf, buf_len, "dbname = '%s'", db->database);
+ status = snprintf(buf, buf_len, "dbname = '%s'", db->database);
if (0 < status) {
buf += status;
buf_len -= status;
C_PSQL_PAR_APPEND(buf, buf_len, "sslmode", db->sslmode);
C_PSQL_PAR_APPEND(buf, buf_len, "krbsrvname", db->krbsrvname);
C_PSQL_PAR_APPEND(buf, buf_len, "service", db->service);
+ C_PSQL_PAR_APPEND(buf, buf_len, "application_name", "collectd_postgresql");
db->conn = PQconnectdb(conninfo);
db->proto_version = PQprotocolVersion(db->conn);
char interval[64];
if ((data == NULL) || (data->params_num == 0))
- return (c_psql_exec_query_noparams(db, q));
+ return c_psql_exec_query_noparams(db, q);
assert(db->max_params_num >= data->params_num);
params[i] = db->user;
break;
case C_PSQL_PARAM_INTERVAL:
- ssnprintf(interval, sizeof(interval), "%.3f",
- (db->interval > 0) ? CDTIME_T_TO_DOUBLE(db->interval)
- : plugin_get_interval());
+ snprintf(interval, sizeof(interval), "%.3f",
+ (db->interval > 0) ? CDTIME_T_TO_DOUBLE(db->interval)
+ : plugin_get_interval());
params[i] = interval;
break;
case C_PSQL_PARAM_INSTANCE:
}
return PQexecParams(db->conn, udb_query_get_statement(q), data->params_num,
- NULL, (const char *const *)params, NULL, NULL,
- /* return text data */ 0);
+ NULL, (const char *const *)params, NULL, NULL, 0);
} /* c_psql_exec_query_params */
/* db->db_lock must be locked when calling this function */
else
host = db->host;
- status =
- udb_query_prepare_result(q, prep_area, host, "postgresql", db->instance,
- column_names, (size_t)column_num, db->interval);
+ status = udb_query_prepare_result(
+ q, prep_area, host,
+ (db->plugin_name != NULL) ? db->plugin_name : "postgresql", db->instance,
+ column_names, (size_t)column_num, db->interval);
+
if (0 != status) {
log_err("udb_query_prepare_result failed with status %i.", status);
BAIL_OUT(-1);
str_len = string_len;
for (size_t i = 0; i < ds->ds_num; ++i) {
- int status = ssnprintf(str_ptr, str_len, ",'%s'", ds->ds[i].name);
+ int status = snprintf(str_ptr, str_len, ",'%s'", ds->ds[i].name);
if (status < 1)
return NULL;
int status;
if (store_rates)
- status = ssnprintf(str_ptr, str_len, ",'gauge'");
+ status = snprintf(str_ptr, str_len, ",'gauge'");
else
- status = ssnprintf(str_ptr, str_len, ",'%s'",
- DS_TYPE_TO_STRING(ds->ds[i].type));
+ status = snprintf(str_ptr, str_len, ",'%s'",
+ DS_TYPE_TO_STRING(ds->ds[i].type));
if (status < 1) {
str_len = 0;
if (ds->ds[i].type == DS_TYPE_GAUGE)
status =
- ssnprintf(str_ptr, str_len, "," GAUGE_FORMAT, vl->values[i].gauge);
+ snprintf(str_ptr, str_len, "," GAUGE_FORMAT, vl->values[i].gauge);
else if (store_rates) {
if (rates == NULL)
rates = uc_get_rate(ds, vl);
return NULL;
}
- status = ssnprintf(str_ptr, str_len, ",%lf", rates[i]);
+ status = snprintf(str_ptr, str_len, ",%lf", rates[i]);
} else if (ds->ds[i].type == DS_TYPE_COUNTER)
- status = ssnprintf(str_ptr, str_len, ",%llu", vl->values[i].counter);
+ status = snprintf(str_ptr, str_len, ",%llu", vl->values[i].counter);
else if (ds->ds[i].type == DS_TYPE_DERIVE)
- status = ssnprintf(str_ptr, str_len, ",%" PRIi64, vl->values[i].derive);
+ status = snprintf(str_ptr, str_len, ",%" PRIi64, vl->values[i].derive);
else if (ds->ds[i].type == DS_TYPE_ABSOLUTE)
- status = ssnprintf(str_ptr, str_len, ",%" PRIu64, vl->values[i].absolute);
+ status = snprintf(str_ptr, str_len, ",%" PRIu64, vl->values[i].absolute);
if (status < 1) {
str_len = 0;
if (db->writers_num > 0) {
char cb_name[DATA_MAX_NAME_LEN];
- ssnprintf(cb_name, sizeof(cb_name), "postgresql-%s", db->database);
+ snprintf(cb_name, sizeof(cb_name), "postgresql-%s", db->database);
if (!had_flush) {
plugin_unregister_flush("postgresql");
}
data->params_num++;
- return (0);
+ return 0;
} /* config_query_param_add */
static int config_query_callback(udb_query_t *q, oconfig_item_t *ci) {
log_err("Option not allowed within a Query block: `%s'", ci->key);
- return (-1);
+ return -1;
} /* config_query_callback */
static int config_add_writer(oconfig_item_t *ci, c_psql_writer_t *src_writers,
cf_util_get_string(c, &db->password);
else if (0 == strcasecmp(c->key, "Instance"))
cf_util_get_string(c, &db->instance);
+ else if (0 == strcasecmp(c->key, "Plugin"))
+ cf_util_get_string(c, &db->plugin_name);
else if (0 == strcasecmp(c->key, "SSLMode"))
cf_util_get_string(c, &db->sslmode);
else if (0 == strcasecmp(c->key, "KRBSrvName"))
}
}
- ssnprintf(cb_name, sizeof(cb_name), "postgresql-%s", db->instance);
+ snprintf(cb_name, sizeof(cb_name), "postgresql-%s", db->instance);
user_data_t ud = {.data = db, .free_func = c_psql_database_delete};
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 : */
sd = socket(PF_UNIX, item->socktype, 0);
if (sd < 0) {
FUNC_ERROR("socket");
- return (-1);
+ return -1;
}
sa_unix.sun_family = AF_UNIX;
if ((status != 0) && (errno != ENOENT)) {
SOCK_ERROR("unlink", sa_unix.sun_path);
close(sd);
- return (-1);
+ return -1;
}
do /* while (0) */
unlink(sa_unix.sun_path);
if (status != 0)
- return (-1);
+ return -1;
assert(buffer_size > 0);
buffer = malloc(buffer_size);
if (buffer == NULL) {
FUNC_ERROR("malloc");
- return (-1);
+ return -1;
}
memcpy(buffer, temp, buffer_size - 1);
buffer[buffer_size - 1] = 0;
*ret_buffer = buffer;
- return (0);
+ return 0;
} /* }}} int powerdns_get_data_dgram */
static int powerdns_get_data_stream(list_item_t *item, char **ret_buffer) {
sd = socket(PF_UNIX, item->socktype, 0);
if (sd < 0) {
FUNC_ERROR("socket");
- return (-1);
+ return -1;
}
struct timeval timeout;
if (status != 0) {
FUNC_ERROR("setsockopt");
close(sd);
- return (-1);
+ return -1;
}
status =
if (status != 0) {
SOCK_ERROR("connect", item->sockaddr.sun_path);
close(sd);
- return (-1);
+ return -1;
}
/* strlen + 1, because we need to send the terminating NULL byte, too. */
if (status < 0) {
SOCK_ERROR("send", item->sockaddr.sun_path);
close(sd);
- return (-1);
+ return -1;
}
while (42) {
static int powerdns_get_data(list_item_t *item, char **ret_buffer) {
if (item->socktype == SOCK_DGRAM)
- return (powerdns_get_data_dgram(item, ret_buffer));
+ return powerdns_get_data_dgram(item, ret_buffer);
else if (item->socktype == SOCK_STREAM)
- return (powerdns_get_data_stream(item, ret_buffer));
+ return powerdns_get_data_stream(item, ret_buffer);
else {
ERROR("powerdns plugin: Unknown socket type: %i", (int)item->socktype);
- return (-1);
+ return -1;
}
} /* int powerdns_get_data */
item->command = strdup(SERVER_COMMAND);
if (item->command == NULL) {
ERROR("powerdns plugin: strdup failed.");
- return (-1);
+ return -1;
}
char *buffer = NULL;
int status = powerdns_get_data(item, &buffer);
if (status != 0) {
ERROR("powerdns plugin: powerdns_get_data failed.");
- return (status);
+ return status;
}
if (buffer == NULL) {
return EINVAL;
sfree(buffer);
- return (0);
+ return 0;
} /* }}} int powerdns_read_server */
/*
int status;
if (li == NULL)
- return (0);
+ return 0;
if (li->fields_num < 1) {
sstrncpy(buffer, RECURSOR_COMMAND, sizeof(buffer));
/* seperator = */ " ");
if (status < 0) {
ERROR("powerdns plugin: strjoin failed.");
- return (-1);
+ return -1;
}
buffer[sizeof(buffer) - 1] = 0;
size_t len = strlen(buffer);
li->command = strdup(buffer);
if (li->command == NULL) {
ERROR("powerdns plugin: strdup failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int powerdns_update_recursor_command */
static int powerdns_read_recursor(list_item_t *item) /* {{{ */
status = powerdns_update_recursor_command(item);
if (status != 0) {
ERROR("powerdns plugin: powerdns_update_recursor_command failed.");
- return (-1);
+ return -1;
}
DEBUG("powerdns plugin: powerdns_read_recursor: item->command = %s;",
status = powerdns_get_data(item, &buffer);
if (status != 0) {
ERROR("powerdns plugin: powerdns_get_data failed.");
- return (-1);
+ return -1;
}
keys_list = strdup(item->command);
if (keys_list == NULL) {
FUNC_ERROR("strdup");
sfree(buffer);
- return (-1);
+ return -1;
}
key_saveptr = NULL;
sfree(buffer);
sfree(keys_list);
- return (0);
+ return 0;
} /* }}} int powerdns_read_recursor */
static int powerdns_config_add_collect(list_item_t *li, /* {{{ */
if (ci->values_num < 1) {
WARNING("powerdns plugin: The `Collect' option needs "
"at least one argument.");
- return (-1);
+ return -1;
}
for (int i = 0; i < ci->values_num; i++)
if (ci->values[i].type != OCONFIG_TYPE_STRING) {
WARNING("powerdns plugin: Only string arguments are allowed to "
"the `Collect' option.");
- return (-1);
+ return -1;
}
temp =
realloc(li->fields, sizeof(char *) * (li->fields_num + ci->values_num));
if (temp == NULL) {
WARNING("powerdns plugin: realloc failed.");
- return (-1);
+ return -1;
}
li->fields = temp;
/* Invalidate a previously computed command */
sfree(li->command);
- return (0);
+ return 0;
} /* }}} int powerdns_config_add_collect */
static int powerdns_config_add_server(oconfig_item_t *ci) /* {{{ */
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("powerdns plugin: `%s' needs exactly one string argument.",
ci->key);
- return (-1);
+ return -1;
}
item = calloc(1, sizeof(*item));
if (item == NULL) {
ERROR("powerdns plugin: calloc failed.");
- return (-1);
+ return -1;
}
item->instance = strdup(ci->values[0].value.string);
if (item->instance == NULL) {
ERROR("powerdns plugin: strdup failed.");
sfree(item);
- return (-1);
+ return -1;
}
/*
} else {
/* We must never get here.. */
assert(0);
- return (-1);
+ return -1;
}
status = 0;
if (status != 0) {
sfree(socket_temp);
sfree(item);
- return (-1);
+ return -1;
}
DEBUG("powerdns plugin: Add server: instance = %s;", item->instance);
sfree(socket_temp);
- return (0);
+ return 0;
} /* }}} int powerdns_config_add_server */
static int powerdns_config(oconfig_item_t *ci) /* {{{ */
if (list == NULL) {
ERROR("powerdns plugin: `llist_create' failed.");
- return (-1);
+ return -1;
}
}
} else {
char *temp = strdup(option->values[0].value.string);
if (temp == NULL)
- return (1);
+ return 1;
sfree(local_sockpath);
local_sockpath = temp;
}
}
} /* for (i = 0; i < ci->children_num; i++) */
- return (0);
+ return 0;
} /* }}} int powerdns_config */
static int powerdns_read(void) {
item->func(item);
}
- return (0);
+ return 0;
} /* static int powerdns_read */
static int powerdns_shutdown(void) {
if (list == NULL)
- return (0);
+ return 0;
for (llentry_t *e = llist_head(list); e != NULL; e = e->next) {
list_item_t *item = (list_item_t *)e->value;
llist_destroy(list);
list = NULL;
- return (0);
+ return 0;
} /* static int powerdns_shutdown */
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 : */
* Manuel Sanmartin
* Clément Stenac <clement.stenac at diwi.org>
* Cosmin Ioiart <cioiart at gmail.com>
+ * Pavel Rochnyack <pavel2000 at ngs.ru>
+ * Wilfried Goesgens <dothebart at citadel.org>
**/
#include "collectd.h"
#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 num_maps;
unsigned long vmem_size;
unsigned long vmem_rss;
unsigned long vmem_data;
derive_t io_wchar;
derive_t io_syscr;
derive_t io_syscw;
+ derive_t io_diskr;
+ derive_t io_diskw;
_Bool has_io;
derive_t cswitch_vol;
derive_t cswitch_invol;
_Bool has_cswitch;
+ _Bool has_fd;
+
+ _Bool has_maps;
+} 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 io_diskr;
+ derive_t io_diskw;
+
+ 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
unsigned long num_proc;
unsigned long num_lwp;
+ unsigned long num_fd;
+ unsigned long num_maps;
unsigned long vmem_size;
unsigned long vmem_rss;
unsigned long vmem_data;
derive_t io_wchar;
derive_t io_syscr;
derive_t io_syscw;
+ derive_t io_diskr;
+ derive_t io_diskw;
derive_t cswitch_vol;
derive_t cswitch_invol;
+ _Bool report_fd_num;
+ _Bool report_maps_num;
+ _Bool report_ctx_switch;
+
struct procstat *next;
struct procstat_entry_s *instances;
} procstat_t;
static _Bool want_init = 1;
static _Bool report_ctx_switch = 0;
+static _Bool report_fd_num = 0;
+static _Bool report_maps_num = 0;
#if HAVE_THREAD_INFO
static mach_port_t port_host_self;
#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 && \
/* 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;
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->io_diskr = -1;
+ new->io_diskw = -1;
+ new->cswitch_vol = -1;
+ new->cswitch_invol = -1;
+
+ new->report_fd_num = report_fd_num;
+ new->report_maps_num = report_maps_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,
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);
regexp);
sfree(new->re);
sfree(new);
- return;
+ return NULL;
}
}
#else
"has been disabled at compile time.",
regexp);
sfree(new);
- return;
+ return NULL;
}
#endif
sfree(new->re);
#endif
sfree(new);
- return;
+ return NULL;
}
if (ptr->next == NULL)
list_head_g = new;
else
ptr->next = new;
+
+ return new;
} /* void ps_list_register */
/* try to match name against entry, returns 1 if success */
/* pmatch = */ NULL,
/* eflags = */ 0);
if (status == 0)
- return (1);
+ return 1;
} else
#endif
if (strcmp(ps->name, name) == 0)
- return (1);
+ return 1;
- return (0);
+ return 0;
} /* int ps_list_match */
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)
}
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->num_maps += entry->num_maps;
+ 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->io_diskr != -1) && (entry->io_diskw != -1)) {
+ ps_update_counter(&ps->io_diskr, &pse->io_diskr, entry->io_diskr);
+ ps_update_counter(&ps->io_diskw, &pse->io_diskw, entry->io_diskw);
+ }
+
+ if ((entry->cswitch_vol != -1) && (entry->cswitch_invol != -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);
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->num_maps = 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;
} /* 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 if (strcasecmp(c->key, "CollectMemoryMaps") == 0)
+ cf_util_get_boolean(c, &ps->report_maps_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
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;
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 <Process '%s'> 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 "
}
#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)) {
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 <ProcessMatch '%s' '%s'> "
- "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 if (strcasecmp(c->key, "CollectMemoryMaps") == 0) {
+ cf_util_get_boolean(c, &report_maps_num);
} else {
ERROR("processes plugin: The `%s' configuration option is not "
"understood and will be ignored.",
}
}
- return (0);
+ return 0;
}
static int ps_init(void) {
ERROR("host_processor_sets failed: %s\n", mach_error_string(status));
pset_list = NULL;
pset_list_len = 0;
- return (-1);
+ return -1;
}
/* #endif HAVE_THREAD_INFO */
pagesize = getpagesize();
#endif /* HAVE_PROCINFO_H */
- return (0);
+ return 0;
} /* int ps_init */
/* submit global state (e.g.: qty of zombies, running, etc..) */
plugin_dispatch_values(&vl);
if ((ps->io_rchar != -1) && (ps->io_wchar != -1)) {
- sstrncpy(vl.type, "ps_disk_octets", sizeof(vl.type));
+ sstrncpy(vl.type, "io_octets", sizeof(vl.type));
vl.values[0].derive = ps->io_rchar;
vl.values[1].derive = ps->io_wchar;
vl.values_len = 2;
}
if ((ps->io_syscr != -1) && (ps->io_syscw != -1)) {
- sstrncpy(vl.type, "ps_disk_ops", sizeof(vl.type));
+ sstrncpy(vl.type, "io_ops", sizeof(vl.type));
vl.values[0].derive = ps->io_syscr;
vl.values[1].derive = ps->io_syscw;
vl.values_len = 2;
plugin_dispatch_values(&vl);
}
- if (report_ctx_switch) {
+ if ((ps->io_diskr != -1) && (ps->io_diskw != -1)) {
+ sstrncpy(vl.type, "disk_octets", sizeof(vl.type));
+ vl.values[0].derive = ps->io_diskr;
+ vl.values[1].derive = ps->io_diskw;
+ vl.values_len = 2;
+ plugin_dispatch_values(&vl);
+ }
+
+ 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->num_maps > 0) {
+ sstrncpy(vl.type, "file_handles", sizeof(vl.type));
+ sstrncpy(vl.type_instance, "mapped", sizeof(vl.type_instance));
+ vl.values[0].gauge = ps->num_maps;
+ 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;
plugin_dispatch_values(&vl);
}
- DEBUG("name = %s; num_proc = %lu; num_lwp = %lu; "
- "vmem_size = %lu; vmem_rss = %lu; vmem_data = %lu; "
- "vmem_code = %lu; "
- "vmem_minflt_counter = %" PRIi64 "; vmem_majflt_counter = %" PRIi64 "; "
- "cpu_user_counter = %" PRIi64 "; cpu_system_counter = %" PRIi64 "; "
- "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->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);
+ DEBUG(
+ "name = %s; num_proc = %lu; num_lwp = %lu; num_fd = %lu; num_maps = %lu; "
+ "vmem_size = %lu; vmem_rss = %lu; vmem_data = %lu; "
+ "vmem_code = %lu; "
+ "vmem_minflt_counter = %" PRIi64 "; vmem_majflt_counter = %" PRIi64 "; "
+ "cpu_user_counter = %" PRIi64 "; cpu_system_counter = %" PRIi64 "; "
+ "io_rchar = %" PRIi64 "; io_wchar = %" PRIi64 "; "
+ "io_syscr = %" PRIi64 "; io_syscw = %" PRIi64 "; "
+ "io_diskr = %" PRIi64 "; io_diskw = %" PRIi64 "; "
+ "cswitch_vol = %" PRIi64 "; cswitch_invol = %" PRIi64 ";",
+ ps->name, ps->num_proc, ps->num_lwp, ps->num_fd, ps->num_maps,
+ 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->io_diskr, ps->io_diskw, ps->cswitch_vol,
+ ps->cswitch_invol);
+
} /* void ps_submit_proc_list */
#if KERNEL_LINUX || KERNEL_SOLARIS
/* ------- 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];
char *fields[8];
int numfields;
- ssnprintf(dirname, sizeof(dirname), "/proc/%li/task", ps->id);
+ snprintf(dirname, sizeof(dirname), "/proc/%li/task", ps->id);
if ((dh = opendir(dirname)) == NULL) {
DEBUG("Failed to open directory `%s'", dirname);
- return (-1);
+ return -1;
}
while ((ent = readdir(dh)) != NULL) {
tpid = ent->d_name;
- ssnprintf(filename, sizeof(filename), "/proc/%li/task/%s/status", ps->id,
- tpid);
+ if (snprintf(filename, sizeof(filename), "/proc/%li/task/%s/status", ps->id,
+ tpid) >= sizeof(filename)) {
+ DEBUG("Filename too long: `%s'", filename);
+ continue;
+ }
+
if ((fh = fopen(filename, "r")) == NULL) {
DEBUG("Failed to open file `%s'", filename);
continue;
ps->cswitch_vol = cswitch_vol;
ps->cswitch_invol = cswitch_invol;
- return (0);
+ return 0;
} /* 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];
char *fields[8];
int numfields;
- ssnprintf(filename, sizeof(filename), "/proc/%li/status", pid);
+ snprintf(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;
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];
char *fields[8];
int numfields;
- ssnprintf(filename, sizeof(filename), "/proc/%li/io", ps->id);
- if ((fh = fopen(filename, "r")) == NULL)
- return (-1);
+ snprintf(filename, sizeof(filename), "/proc/%li/io", ps->id);
+ 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;
val = &(ps->io_syscr);
else if (strncasecmp(buffer, "syscw:", 6) == 0)
val = &(ps->io_syscw);
+ else if (strncasecmp(buffer, "read_bytes:", 11) == 0)
+ val = &(ps->io_diskr);
+ else if (strncasecmp(buffer, "write_bytes:", 12) == 0)
+ val = &(ps->io_diskw);
else
continue;
char errbuf[1024];
WARNING("processes: fclose: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
}
- return (0);
+ 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_maps(pid_t pid) {
+ FILE *fh;
+ char buffer[1024];
+ char filename[64];
+ int count = 0;
+
+ snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);
+ if ((fh = fopen(filename, "r")) == NULL) {
+ DEBUG("ps_count_maps: Failed to open file `%s'", filename);
+ return -1;
+ }
+
+ while (fgets(buffer, sizeof(buffer), fh) != NULL) {
+ if (strchr(buffer, '\n')) {
+ count++;
+ }
+ } /* while (fgets) */
+
+ if (fclose(fh)) {
+ char errbuf[1024];
+ WARNING("processes: fclose: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
+ }
+ return count;
+} /* int ps_count_maps (...) */
+
+static int ps_count_fd(int pid) {
+ char dirname[64];
+ DIR *dh;
+ struct dirent *ent;
+ int count = 0;
+
+ snprintf(dirname, sizeof(dirname), "/proc/%i/fd", pid);
+
+ if ((dh = opendir(dirname)) == NULL) {
+ DEBUG("Failed to open directory `%s'", dirname);
+ return -1;
+ }
+ while ((ent = readdir(dh)) != NULL) {
+ if (!isdigit((int)ent->d_name[0]))
+ continue;
+ else
+ count++;
+ }
+ closedir(dh);
- DEBUG("ps_read_process: not get io data for pid %li", entry->id);
+ return (count >= 1) ? count : 1;
+} /* int ps_count_fd (pid) */
+
+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;
}
- entry->has_io = 1;
- if (report_ctx_switch) {
- if (entry->has_cswitch == 0 && ps_read_tasks_status(entry) != 0) {
- entry->cswitch_vol = -1;
- entry->cswitch_invol = -1;
+ if (ps->report_ctx_switch) {
+ if (entry->has_cswitch == 0) {
+ ps_read_tasks_status(entry);
+ entry->has_cswitch = 1;
+ }
+ }
- DEBUG("ps_read_tasks_status: not get context "
- "switch data for pid %li",
- entry->id);
+ if (ps->report_maps_num) {
+ int num_maps;
+ if (entry->has_maps == 0 && (num_maps = ps_count_maps(entry->id)) > 0) {
+ entry->num_maps = num_maps;
}
- entry->has_cswitch = 1;
+ entry->has_maps = 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_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];
ssize_t status;
- memset(ps, 0, sizeof(procstat_t));
-
- ssnprintf(filename, sizeof(filename), "/proc/%li/stat", pid);
+ snprintf(filename, sizeof(filename), "/proc/%li/stat", pid);
status = read_file_contents(filename, buffer, sizeof(buffer) - 1);
if (status <= 0)
- return (-1);
+ return -1;
buffer_len = (size_t)status;
buffer[buffer_len] = 0;
if (name_start_pos >= name_end_pos) {
ERROR("processes plugin: name_start_pos = %zu >= name_end_pos = %zu",
name_start_pos, name_end_pos);
- return (-1);
+ return -1;
}
name_len = (name_end_pos - name_start_pos) - 1;
sstrncpy(ps->name, &buffer[name_start_pos + 1], name_len + 1);
if ((buffer_len - name_end_pos) < 2)
- return (-1);
+ return -1;
buffer_ptr = &buffer[name_end_pos + 2];
fields_len = strsplit(buffer_ptr, fields, STATIC_ARRAY_SIZE(fields));
DEBUG("processes plugin: ps_read_process (pid = %li):"
" `%s' has only %i fields..",
pid, filename, fields_len);
- return (-1);
+ return -1;
}
*state = fields[0][0];
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;
DEBUG("processes plugin: This is only a zombie: pid = %li; "
"name = %s;",
pid, ps->name);
- return (0);
+ return 0;
}
cpu_user_counter = atoll(fields[11]);
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->io_diskr = -1;
+ ps->io_diskw = -1;
+
+ ps->cswitch_vol = -1;
+ ps->cswitch_invol = -1;
+
/* success */
- return (0);
+ return 0;
} /* int ps_read_process (...) */
static char *ps_get_cmdline(long pid, char *name, char *buf, size_t buf_len) {
if ((pid < 1) || (NULL == buf) || (buf_len < 2))
return NULL;
- ssnprintf(file, sizeof(file), "/proc/%li/cmdline", pid);
+ snprintf(file, sizeof(file), "/proc/%li/cmdline", pid);
errno = 0;
fd = open(file, O_RDONLY);
if (NULL == name)
return NULL;
- ssnprintf(buf, buf_len, "[%s]", name);
+ snprintf(buf, buf_len, "[%s]", name);
return buf;
}
char errbuf[1024];
ERROR("processes plugin: fopen (/proc/stat) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
while (fgets(buffer, sizeof(buffer), proc_stat) != NULL) {
fclose(proc_stat);
if (!value_valid)
- return (-1);
+ return -1;
ps_submit_fork_rate(value.derive);
- return (0);
+ return 0;
}
#endif /*KERNEL_LINUX */
"while reading \"%s\": "
"Returned %zd but expected %zu.",
path, status, buffer_size);
- return (NULL);
+ return NULL;
}
info.pr_psargs[sizeof(info.pr_psargs) - 1] = 0;
sstrncpy(buffer, info.pr_psargs, buffer_size);
- return (buffer);
+ return buffer;
} /* }}} int ps_get_cmdline */
/*
* 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;
sfree(myStatus);
sfree(myInfo);
sfree(myUsage);
- return (0);
+ return 0;
} else {
ps->num_proc = 1;
ps->num_lwp = myInfo->pr_nlwp;
ps->stack_size = myStatus->pr_stksize;
/*
+ * TODO: File descriptor count for Solaris
+ */
+ ps->num_fd = 0;
+
+ /* Number of memory mappings */
+ ps->num_maps = 0;
+
+ /*
* Calculating input/ouput chars
* Formula used is total chars / total blocks => chars/block
* then convert input/output blocks to chars
ps->io_wchar = myUsage->pr_oublk * chars_per_block;
ps->io_syscr = myUsage->pr_sysc;
ps->io_syscw = myUsage->pr_sysc;
+ ps->io_diskr = -1;
+ ps->io_diskw = -1;
/*
* TODO: context switch counters for Solaris
sfree(myInfo);
sfree(myUsage);
- return (0);
+ return 0;
}
/*
derive_t result = 0;
if (kc == NULL)
- return (-1);
+ return -1;
for (kstat_t *ksp_chain = kc->kc_chain; ksp_chain != NULL;
ksp_chain = ksp_chain->ks_next) {
}
ps_submit_fork_rate(result);
- return (0);
+ return 0;
}
#endif /* KERNEL_SOLARIS */
mib[2] = KERN_PROC_PID;
if (pid_for_task(t, pid) != KERN_SUCCESS)
- return (-1);
+ return -1;
mib[3] = *pid;
kp_size = sizeof(kp);
if (sysctl(mib, 4, &kp, &kp_size, NULL, 0) != 0)
- return (-1);
+ return -1;
if (name_max_len > (MAXCOMLEN + 1))
name_max_len = MAXCOMLEN + 1;
* `top' does it, because it is a lot of work and only used when
* debugging. -octo */
- return (0);
+ return 0;
}
#endif /* HAVE_THREAD_INFO */
/* ------- end of additional functions for KERNEL_LINUX/HAVE_THREAD_INFO -------
int blocked = 0;
procstat_t *ps;
- procstat_entry_t pse;
+ process_entry_t pse;
ps_list_reset();
pse.vmem_data = 0;
pse.vmem_code = 0;
+ pse.io_rchar = -1;
+ pse.io_wchar = -1;
+ pse.io_syscr = -1;
+ pse.io_syscw = -1;
+ pse.io_diskr = -1;
+ pse.io_diskw = -1;
+
+ /* File descriptor count not implemented */
+ pse.num_fd = 0;
+
+ /* Number of memory mappings */
+ pse.num_maps = 0;
+
pse.vmem_minflt_counter = task_events_info.cow_faults;
pse.vmem_majflt_counter = task_events_info.faults;
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;
if ((proc = opendir("/proc")) == NULL) {
char errbuf[1024];
ERROR("Cannot open `/proc': %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
while ((ent = readdir(proc)) != NULL) {
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++;
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);
struct kinfo_proc *proc_ptr = NULL;
int count; /* returns number of processes */
- procstat_entry_t pse;
+ process_entry_t pse;
ps_list_reset();
kd = kvm_openfiles(NULL, "/dev/null", NULL, 0, errbuf);
if (kd == NULL) {
ERROR("processes plugin: Cannot open kvm interface: %s", errbuf);
- return (0);
+ return 0;
}
/* Get the list of processes. */
ERROR("processes plugin: Cannot get kvm processes list: %s",
kvm_geterr(kd));
kvm_close(kd);
- return (0);
+ return 0;
}
/* Iterate through the processes in kinfo_proc */
}
} /* 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;
pse.io_wchar = -1;
pse.io_syscr = -1;
pse.io_syscw = -1;
+ pse.io_diskr = -1;
+ pse.io_diskw = -1;
+
+ /* file descriptor count not implemented */
+ pse.num_fd = 0;
+
+ /* Number of memory mappings */
+ pse.num_maps = 0;
/* context switch counters not implemented */
pse.cswitch_vol = -1;
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);
+ return 0;
}
/* Get the list of processes. */
ERROR("processes plugin: Cannot get kvm processes list: %s",
kvm_geterr(kd));
kvm_close(kd);
- return (0);
+ return 0;
}
/* Iterate through the processes in kinfo_proc */
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 ? */
pse.io_wchar = -1;
pse.io_syscr = -1;
pse.io_syscw = -1;
+ pse.io_diskr = -1;
+ pse.io_diskw = -1;
+
+ /* file descriptor count not implemented */
+ pse.num_fd = 0;
+
+ /* Number of memory mappings */
+ pse.num_maps = 0;
/* context switch counters not implemented */
pse.cswitch_vol = -1;
pid_t pindex = 0;
int nprocs;
- procstat_entry_t pse;
+ process_entry_t pse;
ps_list_reset();
while ((nprocs = getprocs64(procentry, sizeof(struct procentry64),
}
}
+ 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;
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;
pse.io_wchar = -1;
pse.io_syscr = -1;
pse.io_syscw = -1;
+ pse.io_diskr = -1;
+ pse.io_diskw = -1;
+
+ pse.num_fd = 0;
+ pse.num_maps = 0;
pse.cswitch_vol = -1;
pse.cswitch_invol = -1;
proc = opendir("/proc");
if (proc == NULL)
- return (-1);
+ return -1;
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]))
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++;
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);
want_init = 0;
- return (0);
+ return 0;
} /* int ps_read */
void module_register(void) {
if (fh == NULL) {
ERROR("protocols plugin: fopen (%s) failed: %s.", path,
sstrerror(errno, key_buffer, sizeof(key_buffer)));
- return (-1);
+ return -1;
}
status = -1;
if (values_list != NULL) {
char match_name[2 * DATA_MAX_NAME_LEN];
- ssnprintf(match_name, sizeof(match_name), "%s:%s", key_buffer,
- key_fields[i]);
+ snprintf(match_name, sizeof(match_name), "%s:%s", key_buffer,
+ key_fields[i]);
if (ignorelist_match(values_list, match_name))
continue;
fclose(fh);
- return (status);
+ return status;
} /* int read_file */
static int protocols_read(void) {
success++;
if (success == 0)
- return (-1);
+ return -1;
- return (0);
+ return 0;
} /* int protocols_read */
static int protocols_config(const char *key, const char *value) {
invert = 0;
ignorelist_set_invert(values_list, invert);
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int protocols_config */
void module_register(void) {
config_keys_num);
plugin_register_read("protocols", protocols_read);
} /* void module_register */
-
-/* vim: set sw=2 sts=2 et : */
"The callback function will be called with no parameters except for\n"
" data if it was supplied.";
+static char CollectdError_doc[] =
+ "Basic exception for collectd Python scripts.\n"
+ "\n"
+ "Throwing this exception will not cause a stacktrace to be logged, \n"
+ "even if LogTraces is enabled in the config.";
+
static pthread_t main_thread;
static PyOS_sighandler_t python_sigint_handler;
static _Bool do_interactive = 0;
static PyThreadState *state;
-static PyObject *sys_path, *cpy_format_exception;
+static PyObject *sys_path, *cpy_format_exception, *CollectdError;
static cpy_callback_t *cpy_config_callbacks;
static cpy_callback_t *cpy_init_callbacks;
}
void cpy_log_exception(const char *context) {
- int l = 0;
+ int l = 0, collectd_error;
const char *typename = NULL, *message = NULL;
PyObject *type, *value, *traceback, *tn, *m, *list;
PyErr_NormalizeException(&type, &value, &traceback);
if (type == NULL)
return;
+ collectd_error = PyErr_GivenExceptionMatches(value, CollectdError);
tn = PyObject_GetAttrString(type, "__name__"); /* New reference. */
m = PyObject_Str(value); /* New reference. */
if (tn != NULL)
typename = "NamelessException";
if (message == NULL)
message = "N/A";
- Py_BEGIN_ALLOW_THREADS ERROR("Unhandled python exception in %s: %s: %s",
- context, typename, message);
- Py_END_ALLOW_THREADS Py_XDECREF(tn);
+ Py_BEGIN_ALLOW_THREADS;
+ if (collectd_error) {
+ WARNING("%s in %s: %s", typename, context, message);
+ } else {
+ ERROR("Unhandled python exception in %s: %s: %s", context, typename,
+ message);
+ }
+ Py_END_ALLOW_THREADS;
+ Py_XDECREF(tn);
Py_XDECREF(m);
- if (!cpy_format_exception || !traceback) {
+ if (!cpy_format_exception || !traceback || collectd_error) {
PyErr_Clear();
Py_DECREF(type);
Py_XDECREF(value);
if (cpy[strlen(cpy) - 1] == '\n')
cpy[strlen(cpy) - 1] = 0;
- Py_BEGIN_ALLOW_THREADS ERROR("%s", cpy);
- Py_END_ALLOW_THREADS
+ Py_BEGIN_ALLOW_THREADS;
+ ERROR("%s", cpy);
+ Py_END_ALLOW_THREADS;
- free(cpy);
+ free(cpy);
}
Py_XDECREF(list);
PyList_SetItem(
list, i, PyLong_FromUnsignedLongLong(value_list->values[i].absolute));
} else {
- Py_BEGIN_ALLOW_THREADS ERROR("cpy_write_callback: Unknown value type %d.",
- ds->ds[i].type);
- Py_END_ALLOW_THREADS Py_DECREF(list);
+ Py_BEGIN_ALLOW_THREADS;
+ ERROR("cpy_write_callback: Unknown value type %d.", ds->ds[i].type);
+ Py_END_ALLOW_THREADS;
+ Py_DECREF(list);
CPY_RETURN_FROM_THREADS 0;
}
if (PyErr_Occurred() != NULL) {
}
dict = PyDict_New(); /* New reference. */
if (value_list->meta) {
- char **table;
+ char **table = NULL;
meta_data_t *meta = value_list->meta;
int num = meta_data_toc(meta, &table);
} else if (type == MD_TYPE_SIGNED_INT) {
if (meta_data_get_signed_int(meta, table[i], &si))
continue;
- temp = PyObject_CallFunctionObjArgs((void *)&SignedType,
- PyLong_FromLongLong(si),
+ PyObject *sival = PyLong_FromLongLong(si); /* New reference */
+ temp = PyObject_CallFunctionObjArgs((void *)&SignedType, sival,
(void *)0); /* New reference. */
PyDict_SetItemString(dict, table[i], temp);
Py_XDECREF(temp);
+ Py_XDECREF(sival);
} else if (type == MD_TYPE_UNSIGNED_INT) {
if (meta_data_get_unsigned_int(meta, table[i], &ui))
continue;
- temp = PyObject_CallFunctionObjArgs((void *)&UnsignedType,
- PyLong_FromUnsignedLongLong(ui),
+ PyObject *uval = PyLong_FromUnsignedLongLong(ui); /* New reference */
+ temp = PyObject_CallFunctionObjArgs((void *)&UnsignedType, uval,
(void *)0); /* New reference. */
PyDict_SetItemString(dict, table[i], temp);
Py_XDECREF(temp);
+ Py_XDECREF(uval);
} else if (type == MD_TYPE_DOUBLE) {
if (meta_data_get_double(meta, table[i], &d))
continue;
Notification *n;
CPY_LOCK_THREADS
+ PyObject *dict = PyDict_New(); /* New reference. */
+ for (notification_meta_t *meta = notification->meta; meta != NULL;
+ meta = meta->next) {
+ PyObject *temp = NULL;
+ if (meta->type == NM_TYPE_STRING) {
+ temp = cpy_string_to_unicode_or_bytes(
+ meta->nm_value.nm_string); /* New reference. */
+ PyDict_SetItemString(dict, meta->name, temp);
+ Py_XDECREF(temp);
+ } else if (meta->type == NM_TYPE_SIGNED_INT) {
+ PyObject *sival = PyLong_FromLongLong(meta->nm_value.nm_signed_int);
+ temp = PyObject_CallFunctionObjArgs((void *)&SignedType, sival,
+ (void *)0); /* New reference. */
+ PyDict_SetItemString(dict, meta->name, temp);
+ Py_XDECREF(temp);
+ Py_XDECREF(sival);
+ } else if (meta->type == NM_TYPE_UNSIGNED_INT) {
+ PyObject *uval =
+ PyLong_FromUnsignedLongLong(meta->nm_value.nm_unsigned_int);
+ temp = PyObject_CallFunctionObjArgs((void *)&UnsignedType, uval,
+ (void *)0); /* New reference. */
+ PyDict_SetItemString(dict, meta->name, temp);
+ Py_XDECREF(temp);
+ Py_XDECREF(uval);
+ } else if (meta->type == NM_TYPE_DOUBLE) {
+ temp = PyFloat_FromDouble(meta->nm_value.nm_double); /* New reference. */
+ PyDict_SetItemString(dict, meta->name, temp);
+ Py_XDECREF(temp);
+ } else if (meta->type == NM_TYPE_BOOLEAN) {
+ PyDict_SetItemString(dict, meta->name,
+ meta->nm_value.nm_boolean ? Py_True : Py_False);
+ }
+ }
notify = Notification_New(); /* New reference. */
n = (Notification *)notify;
sstrncpy(n->data.host, notification->host, sizeof(n->data.host));
n->data.time = CDTIME_T_TO_DOUBLE(notification->time);
sstrncpy(n->message, notification->message, sizeof(n->message));
n->severity = notification->severity;
+ Py_CLEAR(n->meta);
+ n->meta = dict; /* Steals a reference. */
ret = PyObject_CallFunctionObjArgs(c->callback, n, c->data,
(void *)0); /* New reference. */
Py_XDECREF(notify);
for (size_t i = 0; i < ds->ds_num; ++i) {
tuple = PyTuple_New(4);
PyTuple_SET_ITEM(tuple, 0, cpy_string_to_unicode_or_bytes(ds->ds[i].name));
- PyTuple_SET_ITEM(tuple, 1, cpy_string_to_unicode_or_bytes(
- DS_TYPE_TO_STRING(ds->ds[i].type)));
+ PyTuple_SET_ITEM(
+ tuple, 1,
+ cpy_string_to_unicode_or_bytes(DS_TYPE_TO_STRING(ds->ds[i].type)));
PyTuple_SET_ITEM(tuple, 2, float_or_none(ds->ds[i].min));
PyTuple_SET_ITEM(tuple, 3, float_or_none(ds->ds[i].max));
PyList_SET_ITEM(list, i, tuple);
if (PyArg_ParseTupleAndKeywords(args, kwds, "|etiet", kwlist, NULL, &plugin,
&timeout, NULL, &identifier) == 0)
return NULL;
- Py_BEGIN_ALLOW_THREADS plugin_flush(plugin, timeout, identifier);
- Py_END_ALLOW_THREADS PyMem_Free(plugin);
+ Py_BEGIN_ALLOW_THREADS;
+ plugin_flush(plugin, timeout, identifier);
+ Py_END_ALLOW_THREADS;
+ PyMem_Free(plugin);
PyMem_Free(identifier);
Py_RETURN_NONE;
}
register_function(buf, handler,
&(user_data_t){
- .data = c, .free_func = cpy_destroy_user_data,
+ .data = c,
+ .free_func = cpy_destroy_user_data,
});
++cpy_num_callbacks;
/* group = */ "python", buf, cpy_read_callback,
DOUBLE_TO_CDTIME_T(interval),
&(user_data_t){
- .data = c, .free_func = cpy_destroy_user_data,
+ .data = c,
+ .free_func = cpy_destroy_user_data,
});
++cpy_num_callbacks;
return cpy_string_to_unicode_or_bytes(buf);
char *text;
if (PyArg_ParseTuple(args, "et", NULL, &text) == 0)
return NULL;
- Py_BEGIN_ALLOW_THREADS plugin_log(LOG_ERR, "%s", text);
- Py_END_ALLOW_THREADS PyMem_Free(text);
+ Py_BEGIN_ALLOW_THREADS;
+ plugin_log(LOG_ERR, "%s", text);
+ Py_END_ALLOW_THREADS;
+ PyMem_Free(text);
Py_RETURN_NONE;
}
char *text;
if (PyArg_ParseTuple(args, "et", NULL, &text) == 0)
return NULL;
- Py_BEGIN_ALLOW_THREADS plugin_log(LOG_WARNING, "%s", text);
- Py_END_ALLOW_THREADS PyMem_Free(text);
+ Py_BEGIN_ALLOW_THREADS;
+ plugin_log(LOG_WARNING, "%s", text);
+ Py_END_ALLOW_THREADS;
+ PyMem_Free(text);
Py_RETURN_NONE;
}
char *text;
if (PyArg_ParseTuple(args, "et", NULL, &text) == 0)
return NULL;
- Py_BEGIN_ALLOW_THREADS plugin_log(LOG_NOTICE, "%s", text);
- Py_END_ALLOW_THREADS PyMem_Free(text);
+ Py_BEGIN_ALLOW_THREADS;
+ plugin_log(LOG_NOTICE, "%s", text);
+ Py_END_ALLOW_THREADS;
+ PyMem_Free(text);
Py_RETURN_NONE;
}
char *text;
if (PyArg_ParseTuple(args, "et", NULL, &text) == 0)
return NULL;
- Py_BEGIN_ALLOW_THREADS plugin_log(LOG_INFO, "%s", text);
- Py_END_ALLOW_THREADS PyMem_Free(text);
+ Py_BEGIN_ALLOW_THREADS;
+ plugin_log(LOG_INFO, "%s", text);
+ Py_END_ALLOW_THREADS;
+ PyMem_Free(text);
Py_RETURN_NONE;
}
char *text;
if (PyArg_ParseTuple(args, "et", NULL, &text) == 0)
return NULL;
- Py_BEGIN_ALLOW_THREADS plugin_log(LOG_DEBUG, "%s", text);
- Py_END_ALLOW_THREADS PyMem_Free(text);
+ Py_BEGIN_ALLOW_THREADS;
+ plugin_log(LOG_DEBUG, "%s", text);
+ Py_END_ALLOW_THREADS;
+ PyMem_Free(text);
#endif
Py_RETURN_NONE;
}
}
PyErr_Print();
- Py_BEGIN_ALLOW_THREADS cpy_unregister_list(&cpy_config_callbacks);
+ Py_BEGIN_ALLOW_THREADS;
+ cpy_unregister_list(&cpy_config_callbacks);
cpy_unregister_list(&cpy_init_callbacks);
cpy_unregister_list(&cpy_shutdown_callbacks);
cpy_shutdown_triggered = 1;
- Py_END_ALLOW_THREADS
+ Py_END_ALLOW_THREADS;
- if (!cpy_num_callbacks) {
+ if (!cpy_num_callbacks) {
Py_Finalize();
return 0;
}
values = PyTuple_New(ci->values_num); /* New reference. */
for (int i = 0; i < ci->values_num; ++i) {
if (ci->values[i].type == OCONFIG_TYPE_STRING) {
- PyTuple_SET_ITEM(values, i, cpy_string_to_unicode_or_bytes(
- ci->values[i].value.string));
+ PyTuple_SET_ITEM(
+ values, i,
+ cpy_string_to_unicode_or_bytes(ci->values[i].value.string));
} else if (ci->values[i].type == OCONFIG_TYPE_NUMBER) {
PyTuple_SET_ITEM(values, i,
PyFloat_FromDouble(ci->values[i].value.number));
static int cpy_init_python(void) {
PyOS_sighandler_t cur_sig;
- PyObject *sys;
+ PyObject *sys, *errordict;
PyObject *module;
#ifdef IS_PY3K
PyType_Ready(&SignedType);
UnsignedType.tp_base = &PyLong_Type;
PyType_Ready(&UnsignedType);
+ errordict = PyDict_New();
+ PyDict_SetItemString(
+ errordict, "__doc__",
+ cpy_string_to_unicode_or_bytes(CollectdError_doc)); /* New reference. */
+ CollectdError = PyErr_NewException("collectd.CollectdError", NULL, errordict);
sys = PyImport_ImportModule("sys"); /* New reference. */
if (sys == NULL) {
cpy_log_exception("python initialization");
(void *)&SignedType); /* Steals a reference. */
PyModule_AddObject(module, "Unsigned",
(void *)&UnsignedType); /* Steals a reference. */
+ Py_XINCREF(CollectdError);
+ PyModule_AddObject(module, "CollectdError",
+ CollectdError); /* Steals a reference. */
PyModule_AddIntConstant(module, "LOG_DEBUG", LOG_DEBUG);
PyModule_AddIntConstant(module, "LOG_INFO", LOG_INFO);
PyModule_AddIntConstant(module, "LOG_NOTICE", LOG_NOTICE);
status = 1;
}
}
- return (status);
+ return status;
}
void module_register(void) {
#include "cpython.h"
+typedef struct {
+ int (*add_string)(void *, const char *, const char *);
+ int (*add_signed_int)(void *, const char *, int64_t);
+ int (*add_unsigned_int)(void *, const char *, uint64_t);
+ int (*add_double)(void *, const char *, double);
+ int (*add_boolean)(void *, const char *, _Bool);
+} cpy_build_meta_handler_t;
+
#define FreeAll() \
do { \
PyMem_Free(type); \
return 0;
}
-static meta_data_t *cpy_build_meta(PyObject *meta) {
+static int cpy_build_meta_generic(PyObject *meta,
+ cpy_build_meta_handler_t *meta_func,
+ void *m) {
int s;
- meta_data_t *m = NULL;
PyObject *l;
if ((meta == NULL) || (meta == Py_None))
- return NULL;
+ return -1;
l = PyDict_Items(meta); /* New reference. */
if (!l) {
cpy_log_exception("building meta data");
- return NULL;
+ return -1;
}
s = PyList_Size(l);
if (s <= 0) {
Py_XDECREF(l);
- return NULL;
+ return -1;
}
- m = meta_data_create();
for (int i = 0; i < s; ++i) {
const char *string, *keystring;
PyObject *key, *value, *item, *tmp;
value = PyTuple_GET_ITEM(item, 1);
Py_INCREF(value);
if (value == Py_True) {
- meta_data_add_boolean(m, keystring, 1);
+ meta_func->add_boolean(m, keystring, 1);
} else if (value == Py_False) {
- meta_data_add_boolean(m, keystring, 0);
+ meta_func->add_boolean(m, keystring, 0);
} else if (PyFloat_Check(value)) {
- meta_data_add_double(m, keystring, PyFloat_AsDouble(value));
+ meta_func->add_double(m, keystring, PyFloat_AsDouble(value));
} else if (PyObject_TypeCheck(value, &SignedType)) {
long long int lli;
lli = PyLong_AsLongLong(value);
if (!PyErr_Occurred() && (lli == (int64_t)lli))
- meta_data_add_signed_int(m, keystring, lli);
+ meta_func->add_signed_int(m, keystring, lli);
} else if (PyObject_TypeCheck(value, &UnsignedType)) {
long long unsigned llu;
llu = PyLong_AsUnsignedLongLong(value);
if (!PyErr_Occurred() && (llu == (uint64_t)llu))
- meta_data_add_unsigned_int(m, keystring, llu);
+ meta_func->add_unsigned_int(m, keystring, llu);
} else if (PyNumber_Check(value)) {
long long int lli;
long long unsigned llu;
tmp = PyNumber_Long(value);
lli = PyLong_AsLongLong(tmp);
if (!PyErr_Occurred() && (lli == (int64_t)lli)) {
- meta_data_add_signed_int(m, keystring, lli);
+ meta_func->add_signed_int(m, keystring, lli);
} else {
PyErr_Clear();
llu = PyLong_AsUnsignedLongLong(tmp);
if (!PyErr_Occurred() && (llu == (uint64_t)llu))
- meta_data_add_unsigned_int(m, keystring, llu);
+ meta_func->add_unsigned_int(m, keystring, llu);
}
Py_XDECREF(tmp);
} else {
string = cpy_unicode_or_bytes_to_string(&value);
if (string) {
- meta_data_add_string(m, keystring, string);
+ meta_func->add_string(m, keystring, string);
} else {
PyErr_Clear();
tmp = PyObject_Str(value);
string = cpy_unicode_or_bytes_to_string(&tmp);
if (string)
- meta_data_add_string(m, keystring, string);
+ meta_func->add_string(m, keystring, string);
Py_XDECREF(tmp);
}
}
Py_DECREF(key);
}
Py_XDECREF(l);
+ return 0;
+}
+
+#define CPY_BUILD_META_FUNC(meta_type, func, val_type) \
+ static int cpy_##func(void *meta, const char *key, val_type val) { \
+ return func((meta_type *)meta, key, val); \
+ }
+
+#define CPY_BUILD_META_HANDLER(func_prefix, meta_type) \
+ CPY_BUILD_META_FUNC(meta_type, func_prefix##_add_string, const char *) \
+ CPY_BUILD_META_FUNC(meta_type, func_prefix##_add_signed_int, int64_t) \
+ CPY_BUILD_META_FUNC(meta_type, func_prefix##_add_unsigned_int, uint64_t) \
+ CPY_BUILD_META_FUNC(meta_type, func_prefix##_add_double, double) \
+ CPY_BUILD_META_FUNC(meta_type, func_prefix##_add_boolean, _Bool) \
+ \
+ static cpy_build_meta_handler_t cpy_##func_prefix = { \
+ .add_string = cpy_##func_prefix##_add_string, \
+ .add_signed_int = cpy_##func_prefix##_add_signed_int, \
+ .add_unsigned_int = cpy_##func_prefix##_add_unsigned_int, \
+ .add_double = cpy_##func_prefix##_add_double, \
+ .add_boolean = cpy_##func_prefix##_add_boolean}
+
+CPY_BUILD_META_HANDLER(meta_data, meta_data_t);
+CPY_BUILD_META_HANDLER(plugin_notification_meta, notification_t);
+
+static meta_data_t *cpy_build_meta(PyObject *meta) {
+ meta_data_t *m = meta_data_create();
+ if (cpy_build_meta_generic(meta, &cpy_meta_data, (void *)m) < 0) {
+ meta_data_destroy(m);
+ return NULL;
+ }
return m;
}
+static void cpy_build_notification_meta(notification_t *n, PyObject *meta) {
+ cpy_build_meta_generic(meta, &cpy_plugin_notification_meta, (void *)n);
+}
+
static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
int ret;
const data_set_t *ds;
Values_new /* tp_new */
};
+static char notification_meta_doc[] =
+ "These are the meta data for the Notification object.\n"
+ "It has to be a dictionary of numbers, strings or bools. All keys must be\n"
+ "strings. int and long objects will be dispatched as signed integers "
+ "unless\n"
+ "they are between 2**63 and 2**64-1, which will result in an unsigned "
+ "integer.\n"
+ "One of these storage classes can be forced by using the classes\n"
+ "collectd.Signed and collectd.Unsigned. A meta object received by a\n"
+ "notification callback will always contain Signed or Unsigned objects.";
+
static char severity_doc[] =
"The severity of this notification. Assign or compare to\n"
"NOTIF_FAILURE, NOTIF_WARNING or NOTIF_OKAY.";
int severity = 0;
double time = 0;
char *message = NULL;
+ PyObject *meta = NULL;
char *type = NULL, *plugin_instance = NULL, *type_instance = NULL,
*plugin = NULL, *host = NULL;
- static char *kwlist[] = {"type", "message", "plugin_instance",
- "type_instance", "plugin", "host",
- "time", "severity", NULL};
+ static char *kwlist[] = {
+ "type", "message", "plugin_instance", "type_instance", "plugin",
+ "host", "time", "severity", "meta", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdi", kwlist, NULL,
- &type, NULL, &message, NULL,
- &plugin_instance, NULL, &type_instance, NULL,
- &plugin, NULL, &host, &time, &severity))
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kwds, "|etetetetetetdiO", kwlist, NULL, &type, NULL, &message,
+ NULL, &plugin_instance, NULL, &type_instance, NULL, &plugin, NULL,
+ &host, &time, &severity, &meta))
return -1;
if (type && plugin_get_ds(type) == NULL) {
FreeAll();
PyMem_Free(message);
+
+ if (meta == NULL) {
+ meta = PyDict_New();
+ PyErr_Clear();
+ } else {
+ Py_INCREF(meta);
+ }
+
+ PyObject *tmp = self->meta;
+ self->meta = meta;
+ Py_XDECREF(tmp);
+
return 0;
}
const data_set_t *ds;
notification_t notification;
double t = self->data.time;
+ PyObject *meta = self->meta;
int severity = self->severity;
char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL,
*type_instance = NULL;
char *message = NULL;
- static char *kwlist[] = {"type", "message", "plugin_instance",
- "type_instance", "plugin", "host",
- "time", "severity", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdi", kwlist, NULL,
+ static char *kwlist[] = {
+ "type", "message", "plugin_instance", "type_instance", "plugin",
+ "host", "time", "severity", "meta", NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdiO", kwlist, NULL,
&type, NULL, &message, NULL,
&plugin_instance, NULL, &type_instance, NULL,
- &plugin, NULL, &host, &t, &severity))
+ &plugin, NULL, &host, &t, &severity, &meta))
return NULL;
notification.time = DOUBLE_TO_CDTIME_T(t);
PyErr_Format(PyExc_TypeError, "Dataset %s not found", notification.type);
return NULL;
}
+ if (meta != NULL && meta != Py_None && !PyDict_Check(meta)) {
+ PyErr_Format(PyExc_TypeError, "meta must be a dict");
+ return NULL;
+ }
+ cpy_build_notification_meta(¬ification, meta);
if (notification.time == 0)
notification.time = cdtime();
sstrncpy(notification.plugin, "python", sizeof(notification.plugin));
Py_BEGIN_ALLOW_THREADS;
ret = plugin_dispatch_notification(¬ification);
+ if (notification.meta)
+ plugin_notification_meta_free(notification.meta);
Py_END_ALLOW_THREADS;
if (ret != 0) {
PyErr_SetString(PyExc_RuntimeError,
if (self == NULL)
return NULL;
+ self->meta = PyDict_New();
self->message[0] = 0;
self->severity = 0;
return (PyObject *)self;
static PyObject *Notification_repr(PyObject *s) {
PyObject *ret, *tmp;
- static PyObject *l_severity = NULL, *l_message = NULL, *l_closing = NULL;
+ static PyObject *l_severity = NULL, *l_message = NULL, *l_meta = NULL,
+ *l_closing = NULL;
Notification *self = (Notification *)s;
if (l_severity == NULL)
l_severity = cpy_string_to_unicode_or_bytes(",severity=");
if (l_message == NULL)
l_message = cpy_string_to_unicode_or_bytes(",message=");
+ if (l_meta == NULL)
+ l_meta = cpy_string_to_unicode_or_bytes(",meta=");
if (l_closing == NULL)
l_closing = cpy_string_to_unicode_or_bytes(")");
- if (l_severity == NULL || l_message == NULL || l_closing == NULL)
+ if (l_severity == NULL || l_message == NULL || l_meta == NULL ||
+ l_closing == NULL)
return NULL;
ret = cpy_common_repr(s);
CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp);
CPY_STRCAT_AND_DEL(&ret, tmp);
}
+ if (self->meta &&
+ (!PyDict_Check(self->meta) || PyDict_Size(self->meta) > 0)) {
+ CPY_STRCAT(&ret, l_meta);
+ tmp = PyObject_Repr(self->meta);
+ CPY_STRCAT_AND_DEL(&ret, tmp);
+ }
CPY_STRCAT(&ret, l_closing);
return ret;
}
+static int Notification_traverse(PyObject *self, visitproc visit, void *arg) {
+ Notification *n = (Notification *)self;
+ Py_VISIT(n->meta);
+ return 0;
+}
+
+static int Notification_clear(PyObject *self) {
+ Notification *n = (Notification *)self;
+ Py_CLEAR(n->meta);
+ return 0;
+}
+
+static void Notification_dealloc(PyObject *self) {
+ Notification_clear(self);
+ self->ob_type->tp_free(self);
+}
+
static PyMethodDef Notification_methods[] = {
{"dispatch", (PyCFunction)Notification_dispatch,
METH_VARARGS | METH_KEYWORDS, dispatch_doc},
static PyMemberDef Notification_members[] = {
{"severity", T_INT, offsetof(Notification, severity), 0, severity_doc},
+ {"meta", T_OBJECT_EX, offsetof(Notification, meta), 0,
+ notification_meta_doc},
{NULL}};
static PyGetSetDef Notification_getseters[] = {
{NULL}};
PyTypeObject NotificationType = {
- CPY_INIT_TYPE "collectd.Notification", /* tp_name */
- sizeof(Notification), /* tp_basicsize */
- 0, /* Will be filled in later */
- 0, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- Notification_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
- Notification_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Notification_methods, /* tp_methods */
- Notification_members, /* tp_members */
- Notification_getseters, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- Notification_init, /* tp_init */
- 0, /* tp_alloc */
- Notification_new /* tp_new */
+ CPY_INIT_TYPE "collectd.Notification", /* tp_name */
+ sizeof(Notification), /* tp_basicsize */
+ 0, /* Will be filled in later */
+ Notification_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ Notification_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ Notification_doc, /* tp_doc */
+ Notification_traverse, /* tp_traverse */
+ Notification_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Notification_methods, /* tp_methods */
+ Notification_members, /* tp_members */
+ Notification_getseters, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ Notification_init, /* tp_init */
+ 0, /* tp_alloc */
+ Notification_new /* tp_new */
};
static char Signed_doc[] =
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Signed_doc /* tp_doc */
};
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Unsigned_doc /* tp_doc */
};
#define REDIS_DEF_PASSWD ""
#define REDIS_DEF_PORT 6379
#define REDIS_DEF_TIMEOUT 2000
+#define REDIS_DEF_DB_COUNT 16
#define MAX_REDIS_NODE_NAME 64
#define MAX_REDIS_PASSWD_LENGTH 512
#define MAX_REDIS_VAL_SIZE 256
if (rn_ptr != NULL) {
ERROR("redis plugin: A node with the name `%s' already exists.", rn->name);
- return (-1);
+ return -1;
}
rn_copy = malloc(sizeof(*rn_copy));
if (rn_copy == NULL) {
ERROR("redis plugin: malloc failed adding redis_node to the tree.");
- return (-1);
+ return -1;
}
memcpy(rn_copy, rn, sizeof(*rn_copy));
rn_ptr->next = rn_copy;
}
- return (0);
+ return 0;
} /* }}} */
static redis_query_t *redis_config_query(oconfig_item_t *ci) /* {{{ */
status = cf_util_get_string_buffer(ci, rn.name, sizeof(rn.name));
if (status != 0)
- return (status);
+ return status;
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *option = ci->children + i;
}
if (status != 0)
- return (status);
+ return status;
- return (redis_node_add(&rn));
+ return redis_node_add(&rn);
} /* }}} int redis_config_node */
static int redis_config(oconfig_item_t *ci) /* {{{ */
if (nodes_head == NULL) {
ERROR("redis plugin: No valid node configuration could be found.");
- return (ENOENT);
+ return ENOENT;
}
- return (0);
+ return 0;
} /* }}} */
__attribute__((nonnull(2))) static void
if (nodes_head == NULL)
redis_node_add(&rn);
- return (0);
+ return 0;
} /* }}} int redis_init */
static int redis_handle_info(char *node, char const *info_line,
if (parse_value(buf, &val, ds_type) == -1) {
WARNING("redis plugin: Unable to parse field `%s'.", field_name);
- return (-1);
+ return -1;
}
redis_submit(node, type, type_instance, val);
- return (0);
+ return 0;
}
- return (-1);
+ return -1;
} /* }}} int redis_handle_info */
ds = plugin_get_ds(rq->type);
if (!ds) {
ERROR("redis plugin: DataSet `%s' not defined.", rq->type);
- return (-1);
+ return -1;
}
if (ds->ds_num != 1) {
ERROR("redis plugin: DS `%s' has too many types.", rq->type);
- return (-1);
+ return -1;
}
if ((rr = redisCommand(rh, rq->query)) == NULL) {
WARNING("redis plugin: unable to carry out query `%s'.", rq->query);
- return (-1);
+ return -1;
}
switch (rr->type) {
if (parse_value(rr->str, &val, ds->ds[0].type) == -1) {
WARNING("redis plugin: Unable to parse field `%s'.", rq->type);
freeReplyObject(rr);
- return (-1);
+ return -1;
}
break;
default:
WARNING("redis plugin: Cannot coerce redis type.");
freeReplyObject(rr);
- return (-1);
+ return -1;
}
redis_submit(rn->name, rq->type,
return 0;
} /* }}} int redis_handle_query */
+static int redis_db_stats(char *node, char const *info_line) /* {{{ */
+{
+ /* redis_db_stats parses and dispatches Redis database statistics,
+ * currently the number of keys for each database.
+ * info_line needs to have the following format:
+ * db0:keys=4,expires=0,avg_ttl=0
+ */
+
+ for (int db = 0; db < REDIS_DEF_DB_COUNT; db++) {
+ static char buf[MAX_REDIS_VAL_SIZE];
+ static char field_name[11];
+ static char db_id[3];
+ value_t val;
+ char *str;
+ int i;
+
+ snprintf(field_name, sizeof(field_name), "db%d:keys=", db);
+
+ str = strstr(info_line, field_name);
+ if (!str)
+ continue;
+
+ str += strlen(field_name);
+ for (i = 0; (*str && isdigit((int)*str)); i++, str++)
+ buf[i] = *str;
+ buf[i] = '\0';
+
+ if (parse_value(buf, &val, DS_TYPE_GAUGE) != 0) {
+ WARNING("redis plugin: Unable to parse field `%s'.", field_name);
+ return -1;
+ }
+
+ snprintf(db_id, sizeof(db_id), "%d", db);
+ redis_submit(node, "records", db_id, val);
+ }
+ return 0;
+
+} /* }}} int redis_db_stats */
+
static int redis_read(void) /* {{{ */
{
for (redis_node_t *rn = nodes_head; rn != NULL; rn = rn->next) {
redis_handle_info(rn->name, rr->str, "total_bytes", "output",
"total_net_output_bytes", DS_TYPE_DERIVE);
+ redis_db_stats(rn->name, rr->str);
+
for (redis_query_t *rq = rn->queries; rq != NULL; rq = rq->next)
redis_handle_query(rh, rn, rq);
* X elements */
}
/* }}} */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
static int handle_interface(__attribute__((unused))
ros_connection_t *c, /* {{{ */
- const ros_interface_t *i,
- void *user_data) {
+ const ros_interface_t *i, void *user_data) {
if ((i == NULL) || (user_data == NULL))
- return (EINVAL);
+ return EINVAL;
submit_interface(user_data, i);
- return (0);
+ return 0;
} /* }}} int handle_interface */
static void cr_submit_gauge(cr_data_t *rd, const char *type, /* {{{ */
return;
/*** RX ***/
- ssnprintf(type_instance, sizeof(type_instance), "%s-%s-rx", r->interface,
- r->radio_name);
+ snprintf(type_instance, sizeof(type_instance), "%s-%s-rx", r->interface,
+ r->radio_name);
cr_submit_gauge(rd, "bitrate", type_instance,
(gauge_t)(1000000.0 * r->rx_rate));
cr_submit_gauge(rd, "signal_power", type_instance,
cr_submit_gauge(rd, "signal_quality", type_instance, (gauge_t)r->rx_ccq);
/*** TX ***/
- ssnprintf(type_instance, sizeof(type_instance), "%s-%s-tx", r->interface,
- r->radio_name);
+ snprintf(type_instance, sizeof(type_instance), "%s-%s-tx", r->interface,
+ r->radio_name);
cr_submit_gauge(rd, "bitrate", type_instance,
(gauge_t)(1000000.0 * r->tx_rate));
cr_submit_gauge(rd, "signal_power", type_instance,
cr_submit_gauge(rd, "signal_quality", type_instance, (gauge_t)r->tx_ccq);
/*** RX / TX ***/
- ssnprintf(type_instance, sizeof(type_instance), "%s-%s", r->interface,
- r->radio_name);
+ snprintf(type_instance, sizeof(type_instance), "%s-%s", r->interface,
+ r->radio_name);
cr_submit_io(rd, "if_octets", type_instance, (derive_t)r->rx_bytes,
(derive_t)r->tx_bytes);
cr_submit_gauge(rd, "snr", type_instance, (gauge_t)r->signal_to_noise);
static int handle_regtable(__attribute__((unused))
ros_connection_t *c, /* {{{ */
- const ros_registration_table_t *r,
- void *user_data) {
+ const ros_registration_table_t *r, void *user_data) {
if ((r == NULL) || (user_data == NULL))
- return (EINVAL);
+ return EINVAL;
submit_regtable(user_data, r);
- return (0);
+ return 0;
} /* }}} int handle_regtable */
#if ROS_VERSION >= ROS_VERSION_ENCODE(1, 1, 0)
cr_data_t *rd;
if ((r == NULL) || (user_data == NULL))
- return (EINVAL);
+ return EINVAL;
rd = user_data;
if (rd->collect_cpu_load)
cr_submit_gauge(rd, "gauge", "bad_blocks", (gauge_t)r->bad_blocks);
}
- return (0);
+ return 0;
} /* }}} int handle_system_resource */
#endif
cr_data_t *rd;
if (user_data == NULL)
- return (EINVAL);
+ return EINVAL;
rd = user_data->data;
if (rd == NULL)
- return (EINVAL);
+ return EINVAL;
if (rd->connection == NULL) {
rd->connection =
char errbuf[128];
ERROR("routeros plugin: ros_connect failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
}
assert(rd->connection != NULL);
sstrerror(status, errbuf, sizeof(errbuf)));
ros_disconnect(rd->connection);
rd->connection = NULL;
- return (-1);
+ return -1;
}
}
sstrerror(status, errbuf, sizeof(errbuf)));
ros_disconnect(rd->connection);
rd->connection = NULL;
- return (-1);
+ return -1;
}
}
sstrerror(status, errbuf, sizeof(errbuf)));
ros_disconnect(rd->connection);
rd->connection = NULL;
- return (-1);
+ return -1;
}
}
#endif
- return (0);
+ return 0;
} /* }}} int cr_read */
static void cr_free_data(cr_data_t *ptr) /* {{{ */
router_data = calloc(1, sizeof(*router_data));
if (router_data == NULL)
- return (-1);
+ return -1;
router_data->connection = NULL;
router_data->node = NULL;
router_data->service = NULL;
}
}
- ssnprintf(read_name, sizeof(read_name), "routeros/%s", router_data->node);
- if (status == 0)
- status = plugin_register_complex_read(
- /* group = */ NULL, read_name, cr_read, /* interval = */ 0,
- &(user_data_t){
- .data = router_data, .free_func = (void *)cr_free_data,
- });
-
- if (status != 0)
+ if (status != 0) {
cr_free_data(router_data);
+ return status;
+ }
- return (status);
+ snprintf(read_name, sizeof(read_name), "routeros/%s", router_data->node);
+ return plugin_register_complex_read(
+ /* group = */ NULL, read_name, cr_read, /* interval = */ 0,
+ &(user_data_t){
+ .data = router_data, .free_func = (void *)cr_free_data,
+ });
} /* }}} int cr_config_router */
static int cr_config(oconfig_item_t *ci) {
}
}
- return (0);
+ return 0;
} /* }}} int cr_config */
void module_register(void) {
plugin_register_complex_config("routeros", cr_config);
} /* void module_register */
-
-/* vim: set sw=2 noet fdm=marker : */
memset(buffer, '\0', buffer_len);
t = CDTIME_T_TO_TIME_T(vl->time);
- status = ssnprintf(buffer, buffer_len, "%lu", (unsigned long)t);
+ status = snprintf(buffer, buffer_len, "%lu", (unsigned long)t);
if ((status < 1) || (status >= buffer_len))
- return (-1);
+ return -1;
offset = status;
for (size_t i = 0; i < ds->ds_num; i++) {
(ds->ds[i].type != DS_TYPE_GAUGE) &&
(ds->ds[i].type != DS_TYPE_DERIVE) &&
(ds->ds[i].type != DS_TYPE_ABSOLUTE))
- return (-1);
+ return -1;
if (ds->ds[i].type == DS_TYPE_COUNTER) {
- status = ssnprintf(buffer + offset, buffer_len - offset, ":%llu",
- vl->values[i].counter);
+ status = snprintf(buffer + offset, buffer_len - offset, ":%llu",
+ vl->values[i].counter);
} else if (ds->ds[i].type == DS_TYPE_GAUGE) {
- status = ssnprintf(buffer + offset, buffer_len - offset, ":%f",
- vl->values[i].gauge);
+ status = snprintf(buffer + offset, buffer_len - offset, ":%f",
+ vl->values[i].gauge);
} else if (ds->ds[i].type == DS_TYPE_DERIVE) {
- status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIi64,
- vl->values[i].derive);
+ status = snprintf(buffer + offset, buffer_len - offset, ":%" PRIi64,
+ vl->values[i].derive);
} else /* if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */ {
- status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
- vl->values[i].absolute);
+ status = snprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
+ vl->values[i].absolute);
}
if ((status < 1) || (status >= (buffer_len - offset)))
- return (-1);
+ return -1;
offset += status;
} /* for ds->ds_num */
- return (0);
+ return 0;
} /* int value_list_to_string */
static int value_list_to_filename(char *buffer, size_t buffer_size,
size_t datadir_len = strlen(datadir) + 1;
if (datadir_len >= buffer_size)
- return (ENOMEM);
+ return ENOMEM;
sstrncpy(buffer, datadir, buffer_size);
buffer[datadir_len - 1] = '/';
status = FORMAT_VL(buffer, buffer_size, vl);
if (status != 0)
- return (status);
+ return status;
len = strlen(buffer);
assert(len < buffer_size);
buffer_size -= len;
if (buffer_size <= sizeof(suffix))
- return (ENOMEM);
+ return ENOMEM;
memcpy(buffer, suffix, sizeof(suffix));
- return (0);
+ return 0;
} /* int value_list_to_filename */
static int rc_config_get_int_positive(oconfig_item_t const *ci, int *ret) {
status = cf_util_get_int(ci, &tmp);
if (status != 0)
- return (status);
+ return status;
if (tmp < 0)
- return (EINVAL);
+ return EINVAL;
*ret = tmp;
- return (0);
+ return 0;
} /* int rc_config_get_int_positive */
static int rc_config_get_xff(oconfig_item_t const *ci, double *ret) {
ERROR("rrdcached plugin: The \"%s\" needs exactly one numeric argument "
"in the range [0.0, 1.0)",
ci->key);
- return (EINVAL);
+ return EINVAL;
}
value = ci->values[0].value.number;
if ((value >= 0.0) && (value < 1.0)) {
*ret = value;
- return (0);
+ return 0;
}
ERROR("rrdcached plugin: The \"%s\" needs exactly one numeric argument "
"in the range [0.0, 1.0)",
ci->key);
- return (EINVAL);
+ return EINVAL;
} /* int rc_config_get_xff */
static int rc_config_add_timespan(int timespan) {
int *tmp;
if (timespan <= 0)
- return (EINVAL);
+ return EINVAL;
tmp = realloc(rrdcreate_config.timespans,
sizeof(*rrdcreate_config.timespans) *
(rrdcreate_config.timespans_num + 1));
if (tmp == NULL)
- return (ENOMEM);
+ return ENOMEM;
rrdcreate_config.timespans = tmp;
rrdcreate_config.timespans[rrdcreate_config.timespans_num] = timespan;
rrdcreate_config.timespans_num++;
- return (0);
+ return 0;
} /* int rc_config_add_timespan */
static int rc_config(oconfig_item_t *ci) {
plugin_register_write("rrdcached", rc_write, /* user_data = */ NULL);
plugin_register_flush("rrdcached", rc_flush, /* user_data = */ NULL);
}
- return (0);
+ return 0;
} /* int rc_config */
static int try_reconnect(void) {
ERROR("rrdcached plugin: Failed to reconnect to RRDCacheD "
"at %s: %s (status=%d)",
daemon_address, rrd_get_error(), status);
- return (-1);
+ return -1;
}
INFO("rrdcached plugin: Successfully reconnected to RRDCacheD "
"at %s",
daemon_address);
- return (0);
+ return 0;
} /* int try_reconnect */
static int rc_read(void) {
vl.values_len = 1;
if (daemon_address == NULL)
- return (-1);
+ return -1;
if (!config_collect_stats)
- return (-1);
+ return -1;
if ((strncmp("unix:", daemon_address, strlen("unix:")) != 0) &&
(daemon_address[0] != '/'))
ERROR("rrdcached plugin: Failed to connect to RRDCacheD "
"at %s: %s (status=%d)",
daemon_address, rrd_get_error(), status);
- return (-1);
+ return -1;
}
while (42) {
ERROR("rrdcached plugin: rrdc_stats_get failed: %s (status=%i).",
rrd_get_error(), status);
- return (-1);
+ return -1;
}
for (rrdc_stats_t *ptr = head; ptr != NULL; ptr = ptr->next) {
rrdc_stats_free(head);
- return (0);
+ return 0;
} /* int rc_read */
static int rc_init(void) {
if (config_collect_stats)
plugin_register_read("rrdcached", rc_read);
- return (0);
+ return 0;
} /* int rc_init */
static int rc_write(const data_set_t *ds, const value_list_t *vl,
if (daemon_address == NULL) {
ERROR("rrdcached plugin: daemon_address == NULL.");
plugin_unregister_write("rrdcached");
- return (-1);
+ return -1;
}
if (strcmp(ds->type, vl->type) != 0) {
ERROR("rrdcached plugin: DS type does not match value list type");
- return (-1);
+ return -1;
}
if (value_list_to_filename(filename, sizeof(filename), vl) != 0) {
ERROR("rrdcached plugin: value_list_to_filename failed.");
- return (-1);
+ return -1;
}
if (value_list_to_string(values, sizeof(values), ds, vl) != 0) {
ERROR("rrdcached plugin: value_list_to_string failed.");
- return (-1);
+ return -1;
}
values_array[0] = values;
char errbuf[1024];
ERROR("rrdcached plugin: stat (%s) failed: %s", filename,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
status = cu_rrd_create_file(filename, ds, vl, &rrdcreate_config);
if (status != 0) {
ERROR("rrdcached plugin: cu_rrd_create_file (%s) failed.", filename);
- return (-1);
+ return -1;
} else if (rrdcreate_config.async)
- return (0);
+ return 0;
}
}
ERROR("rrdcached plugin: Failed to connect to RRDCacheD "
"at %s: %s (status=%d)",
daemon_address, rrd_get_error(), status);
- return (-1);
+ return -1;
}
while (42) {
ERROR("rrdcached plugin: rrdc_update (%s, [%s], 1) failed: %s (status=%i)",
filename, values_array[0], rrd_get_error(), status);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int rc_write */
static int rc_flush(__attribute__((unused)) cdtime_t timeout, /* {{{ */
_Bool retried = 0;
if (identifier == NULL)
- return (EINVAL);
+ return EINVAL;
if (datadir != NULL)
- ssnprintf(filename, sizeof(filename), "%s/%s.rrd", datadir, identifier);
+ snprintf(filename, sizeof(filename), "%s/%s.rrd", datadir, identifier);
else
- ssnprintf(filename, sizeof(filename), "%s.rrd", identifier);
+ snprintf(filename, sizeof(filename), "%s.rrd", identifier);
rrd_clear_error();
status = rrdc_connect(daemon_address);
ERROR("rrdcached plugin: Failed to connect to RRDCacheD "
"at %s: %s (status=%d)",
daemon_address, rrd_get_error(), status);
- return (-1);
+ return -1;
}
while (42) {
ERROR("rrdcached plugin: rrdc_flush (%s) failed: %s (status=%i).", filename,
rrd_get_error(), status);
- return (-1);
+ return -1;
}
DEBUG("rrdcached plugin: rrdc_flush (%s): Success.", filename);
- return (0);
+ return 0;
} /* }}} int rc_flush */
static int rc_shutdown(void) {
rrdc_disconnect();
- return (0);
+ return 0;
} /* int rc_shutdown */
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 :
- */
/*
* Private types
*/
-struct rrd_cache_s {
+typedef struct rrd_cache_s {
int values_num;
char **values;
cdtime_t first_value;
cdtime_t last_value;
int64_t random_variation;
enum { FLAG_NONE = 0x00, FLAG_QUEUED = 0x01, FLAG_FLUSHQ = 0x02 } flags;
-};
-typedef struct rrd_cache_s rrd_cache_t;
+} rrd_cache_t;
enum rrd_queue_dir_e { QUEUE_INSERT_FRONT, QUEUE_INSERT_BACK };
typedef enum rrd_queue_dir_e rrd_queue_dir_t;
#if HAVE_THREADSAFE_LIBRRD
static int srrd_update(char *filename, char *template, int argc,
const char **argv) {
- int status;
-
optind = 0; /* bug in librrd? */
rrd_clear_error();
- status = rrd_update_r(filename, template, argc, (void *)argv);
-
+ int status = rrd_update_r(filename, template, argc, (void *)argv);
if (status != 0) {
WARNING("rrdtool plugin: rrd_update_r (%s) failed: %s", filename,
rrd_get_error());
}
- return (status);
+ return status;
} /* int srrd_update */
/* #endif HAVE_THREADSAFE_LIBRRD */
new_argv = malloc((new_argc + 1) * sizeof(*new_argv));
if (new_argv == NULL) {
ERROR("rrdtool plugin: malloc failed.");
- return (-1);
+ return -1;
}
new_argv[0] = "update";
sfree(new_argv);
- return (status);
+ return status;
} /* int srrd_update */
#endif /* !HAVE_THREADSAFE_LIBRRD */
memset(buffer, '\0', buffer_len);
tt = CDTIME_T_TO_TIME_T(vl->time);
- status = ssnprintf(buffer, buffer_len, "%u", (unsigned int)tt);
+ status = snprintf(buffer, buffer_len, "%u", (unsigned int)tt);
if ((status < 1) || (status >= buffer_len))
- return (-1);
+ return -1;
offset = status;
for (size_t i = 0; i < ds->ds_num; i++) {
(ds->ds[i].type != DS_TYPE_GAUGE) &&
(ds->ds[i].type != DS_TYPE_DERIVE) &&
(ds->ds[i].type != DS_TYPE_ABSOLUTE))
- return (-1);
+ return -1;
if (ds->ds[i].type == DS_TYPE_COUNTER)
- status = ssnprintf(buffer + offset, buffer_len - offset, ":%llu",
- vl->values[i].counter);
+ status = snprintf(buffer + offset, buffer_len - offset, ":%llu",
+ vl->values[i].counter);
else if (ds->ds[i].type == DS_TYPE_GAUGE)
- status = ssnprintf(buffer + offset, buffer_len - offset, ":" GAUGE_FORMAT,
- vl->values[i].gauge);
+ status = snprintf(buffer + offset, buffer_len - offset, ":" GAUGE_FORMAT,
+ vl->values[i].gauge);
else if (ds->ds[i].type == DS_TYPE_DERIVE)
- status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIi64,
- vl->values[i].derive);
+ status = snprintf(buffer + offset, buffer_len - offset, ":%" PRIi64,
+ vl->values[i].derive);
else /*if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */
- status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
- vl->values[i].absolute);
+ status = snprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
+ vl->values[i].absolute);
if ((status < 1) || (status >= (buffer_len - offset)))
- return (-1);
+ return -1;
offset += status;
} /* for ds->ds_num */
- return (0);
+ return 0;
} /* int value_list_to_string_multiple */
static int value_list_to_string(char *buffer, int buffer_len,
time_t tt;
if (ds->ds_num != 1)
- return (value_list_to_string_multiple(buffer, buffer_len, ds, vl));
+ return value_list_to_string_multiple(buffer, buffer_len, ds, vl);
tt = CDTIME_T_TO_TIME_T(vl->time);
switch (ds->ds[0].type) {
case DS_TYPE_DERIVE:
- status = ssnprintf(buffer, buffer_len, "%u:%" PRIi64, (unsigned)tt,
- vl->values[0].derive);
+ status = snprintf(buffer, buffer_len, "%u:%" PRIi64, (unsigned)tt,
+ vl->values[0].derive);
break;
case DS_TYPE_GAUGE:
- status = ssnprintf(buffer, buffer_len, "%u:" GAUGE_FORMAT, (unsigned)tt,
- vl->values[0].gauge);
+ status = snprintf(buffer, buffer_len, "%u:" GAUGE_FORMAT, (unsigned)tt,
+ vl->values[0].gauge);
break;
case DS_TYPE_COUNTER:
- status = ssnprintf(buffer, buffer_len, "%u:%llu", (unsigned)tt,
- vl->values[0].counter);
+ status = snprintf(buffer, buffer_len, "%u:%llu", (unsigned)tt,
+ vl->values[0].counter);
break;
case DS_TYPE_ABSOLUTE:
- status = ssnprintf(buffer, buffer_len, "%u:%" PRIu64, (unsigned)tt,
- vl->values[0].absolute);
+ status = snprintf(buffer, buffer_len, "%u:%" PRIu64, (unsigned)tt,
+ vl->values[0].absolute);
break;
default:
- return (EINVAL);
+ return EINVAL;
}
if ((status < 1) || (status >= buffer_len))
- return (ENOMEM);
+ return ENOMEM;
- return (0);
+ return 0;
} /* int value_list_to_string */
static int value_list_to_filename(char *buffer, size_t buffer_size,
size_t datadir_len = strlen(datadir) + 1;
if (datadir_len >= buffer_size)
- return (ENOMEM);
+ return ENOMEM;
sstrncpy(buffer, datadir, buffer_size);
buffer[datadir_len - 1] = '/';
status = FORMAT_VL(buffer, buffer_size, vl);
if (status != 0)
- return (status);
+ return status;
len = strlen(buffer);
assert(len < buffer_size);
buffer_size -= len;
if (buffer_size <= sizeof(suffix))
- return (ENOMEM);
+ return ENOMEM;
memcpy(buffer, suffix, sizeof(suffix));
- return (0);
+ return 0;
} /* int value_list_to_filename */
static void *rrd_queue_thread(void __attribute__((unused)) * data) {
} /* while (42) */
pthread_exit((void *)0);
- return ((void *)0);
+ return (void *)0;
} /* void *rrd_queue_thread */
static int rrd_queue_enqueue(const char *filename, rrd_queue_t **head,
queue_entry = malloc(sizeof(*queue_entry));
if (queue_entry == NULL)
- return (-1);
+ return -1;
queue_entry->filename = strdup(filename);
if (queue_entry->filename == NULL) {
free(queue_entry);
- return (-1);
+ return -1;
}
queue_entry->next = NULL;
pthread_cond_signal(&queue_cond);
pthread_mutex_unlock(&queue_lock);
- return (0);
+ return 0;
} /* int rrd_queue_enqueue */
static int rrd_queue_dequeue(const char *filename, rrd_queue_t **head,
if (this == NULL) {
pthread_mutex_unlock(&queue_lock);
- return (-1);
+ return -1;
}
if (prev == NULL)
sfree(this->filename);
sfree(this);
- return (0);
+ return 0;
} /* int rrd_queue_dequeue */
/* XXX: You must hold "cache_lock" when calling this function! */
if (identifier == NULL) {
rrd_cache_flush(timeout);
- return (0);
+ return 0;
}
now = cdtime();
INFO("rrdtool plugin: rrd_cache_flush_identifier: "
"c_avl_get (%s) failed. Does that file really exist?",
key);
- return (status);
+ return status;
}
if (rc->flags == FLAG_FLUSHQ) {
rc->flags = FLAG_FLUSHQ;
}
- return (status);
+ return status;
} /* int rrd_cache_flush_identifier */
static int64_t rrd_get_random_variation(void) {
if (random_timeout == 0)
- return (0);
+ return 0;
return (int64_t)cdrand_range(-random_timeout, random_timeout);
} /* int64_t rrd_get_random_variation */
if (cache == NULL) {
pthread_mutex_unlock(&cache_lock);
WARNING("rrdtool plugin: cache == NULL.");
- return (-1);
+ return -1;
}
int status = c_avl_get(cache, filename, (void *)&rc);
rc = malloc(sizeof(*rc));
if (rc == NULL) {
pthread_mutex_unlock(&cache_lock);
- return (-1);
+ return -1;
}
rc->values_num = 0;
rc->values = NULL;
DEBUG("rrdtool plugin: (rc->last_value = %" PRIu64 ") "
">= (value_time = %" PRIu64 ")",
rc->last_value, value_time);
- return (-1);
+ return -1;
}
values_new =
sfree(cache_key);
sfree(rc->values);
sfree(rc);
- return (-1);
+ return -1;
}
rc->values = values_new;
sfree(rc->values[0]);
sfree(rc->values);
sfree(rc);
- return (-1);
+ return -1;
}
c_avl_insert(cache, cache_key, rc);
pthread_mutex_unlock(&cache_lock);
- return (0);
+ return 0;
} /* int rrd_cache_insert */
static int rrd_cache_destroy(void) /* {{{ */
if (cache == NULL) {
pthread_mutex_unlock(&cache_lock);
- return (0);
+ return 0;
}
while (c_avl_pick(cache, &key, &value) == 0) {
}
pthread_mutex_unlock(&cache_lock);
- return (0);
+ return 0;
} /* }}} int rrd_cache_destroy */
static int rrd_compare_numeric(const void *a_ptr, const void *b_ptr) {
int b = *((int *)b_ptr);
if (a < b)
- return (-1);
+ return -1;
else if (a > b)
- return (1);
+ return 1;
else
- return (0);
+ return 0;
} /* int rrd_compare_numeric */
static int rrd_write(const data_set_t *ds, const value_list_t *vl,
user_data_t __attribute__((unused)) * user_data) {
- struct stat statbuf;
- char filename[512];
- char values[512];
- int status;
if (do_shutdown)
- return (0);
+ return 0;
if (0 != strcmp(ds->type, vl->type)) {
ERROR("rrdtool plugin: DS type does not match value list type");
return -1;
}
+ char filename[PATH_MAX];
if (value_list_to_filename(filename, sizeof(filename), vl) != 0)
- return (-1);
+ return -1;
+ char values[32 * (ds->ds_num + 1)];
if (value_list_to_string(values, sizeof(values), ds, vl) != 0)
- return (-1);
+ return -1;
+ struct stat statbuf = {0};
if (stat(filename, &statbuf) == -1) {
if (errno == ENOENT) {
- status = cu_rrd_create_file(filename, ds, vl, &rrdcreate_config);
- if (status != 0)
- return (-1);
- else if (rrdcreate_config.async)
- return (0);
+ if (cu_rrd_create_file(filename, ds, vl, &rrdcreate_config) != 0) {
+ return -1;
+ } else if (rrdcreate_config.async) {
+ return 0;
+ }
} else {
char errbuf[1024];
- ERROR("stat(%s) failed: %s", filename,
+ ERROR("rrdtool plugin: stat(%s) failed: %s", filename,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
} else if (!S_ISREG(statbuf.st_mode)) {
- ERROR("stat(%s): Not a regular file!", filename);
- return (-1);
+ ERROR("rrdtool plugin: stat(%s): Not a regular file!", filename);
+ return -1;
}
- status = rrd_cache_insert(filename, values, vl->time);
-
- return (status);
+ return rrd_cache_insert(filename, values, vl->time);
} /* int rrd_write */
static int rrd_flush(cdtime_t timeout, const char *identifier,
if (cache == NULL) {
pthread_mutex_unlock(&cache_lock);
- return (0);
+ return 0;
}
rrd_cache_flush_identifier(timeout, identifier);
pthread_mutex_unlock(&cache_lock);
- return (0);
+ return 0;
} /* int rrd_flush */
static int rrd_config(const char *key, const char *value) {
"be greater than 0.\n");
ERROR("rrdtool: `CacheTimeout' must "
"be greater than 0.\n");
- return (1);
+ return 1;
}
cache_timeout = DOUBLE_TO_CDTIME_T(tmp);
} else if (strcasecmp("CacheFlush", key) == 0) {
"be greater than 0.\n");
ERROR("rrdtool: `CacheFlush' must "
"be greater than 0.\n");
- return (1);
+ return 1;
}
cache_flush_timeout = DOUBLE_TO_CDTIME_T(tmp);
} else if (strcasecmp("DataDir", key) == 0) {
tmp = strdup(value);
if (tmp == NULL) {
ERROR("rrdtool plugin: strdup failed.");
- return (1);
+ return 1;
}
len = strlen(tmp);
if (len == 0) {
ERROR("rrdtool plugin: Invalid \"DataDir\" option.");
sfree(tmp);
- return (1);
+ return 1;
}
if (datadir != NULL) {
"be greater than 0.\n");
ERROR("rrdtool: `RRARows' must "
"be greater than 0.\n");
- return (1);
+ return 1;
}
rrdcreate_config.rrarows = tmp;
} else if (strcasecmp("RRATimespan", key) == 0) {
value_copy = strdup(value);
if (value_copy == NULL)
- return (1);
+ return 1;
dummy = value_copy;
while ((ptr = strtok_r(dummy, ", \t", &saveptr)) != NULL) {
fprintf(stderr, "rrdtool: realloc failed.\n");
ERROR("rrdtool: realloc failed.\n");
free(value_copy);
- return (1);
+ return 1;
}
rrdcreate_config.timespans = tmp_alloc;
rrdcreate_config.timespans[rrdcreate_config.timespans_num] = atoi(ptr);
"be in the range 0 to 1 (exclusive).");
ERROR("rrdtool: `XFF' must "
"be in the range 0 to 1 (exclusive).");
- return (1);
+ return 1;
}
rrdcreate_config.xff = tmp;
} else if (strcasecmp("WritesPerSecond", key) == 0) {
if (wps < 0.0) {
fprintf(stderr, "rrdtool: `WritesPerSecond' must be "
"greater than or equal to zero.");
- return (1);
+ return 1;
} else if (wps == 0.0) {
write_rate = 0.0;
} else {
random_timeout = DOUBLE_TO_CDTIME_T(tmp);
}
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int rrd_config */
static int rrd_shutdown(void) {
rrd_cache_destroy();
- return (0);
+ return 0;
} /* int rrd_shutdown */
static int rrd_init(void) {
static int init_once = 0;
- int status;
if (init_once != 0)
- return (0);
+ return 0;
init_once = 1;
if (rrdcreate_config.heartbeat <= 0)
if (cache == NULL) {
pthread_mutex_unlock(&cache_lock);
ERROR("rrdtool plugin: c_avl_create failed.");
- return (-1);
+ return -1;
}
cache_flush_last = cdtime();
pthread_mutex_unlock(&cache_lock);
- status =
+ int status =
plugin_thread_create(&queue_thread, /* attr = */ NULL, rrd_queue_thread,
/* args = */ NULL, "rrdtool queue");
if (status != 0) {
ERROR("rrdtool plugin: Cannot create queue-thread.");
- return (-1);
+ return -1;
}
queue_thread_running = 1;
rrdcreate_config.heartbeat, rrdcreate_config.rrarows,
rrdcreate_config.xff);
- return (0);
+ return 0;
} /* int rrd_init */
void module_register(void) {
int status = -1;
if (chip->bus == SENSORS_CHIP_NAME_BUS_ISA) {
- status = ssnprintf(buf, buf_size, "%s-isa-%04x", chip->prefix, chip->addr);
+ status = snprintf(buf, buf_size, "%s-isa-%04x", chip->prefix, chip->addr);
} else if (chip->bus == SENSORS_CHIP_NAME_BUS_DUMMY) {
status = snprintf(buf, buf_size, "%s-%s-%04x", chip->prefix, chip->busname,
chip->addr);
chip->addr);
}
- return (status);
+ return status;
} /* int sensors_snprintf_chip_name */
static int sensors_feature_name_to_type(const char *name) {
* it's a one time cost.. */
for (int i = 0; i < known_features_num; i++)
if (strcasecmp(known_features[i].label, name) == 0)
- return (known_features[i].type);
+ return known_features[i].type;
- return (SENSOR_TYPE_UNKNOWN);
+ return SENSOR_TYPE_UNKNOWN;
} /* int sensors_feature_name_to_type */
#endif
if (ignorelist_add(sensor_list, value)) {
ERROR("sensors plugin: "
"Cannot add value to ignorelist.");
- return (1);
+ return 1;
}
} else if (strcasecmp(key, "IgnoreSelected") == 0) {
ignorelist_set_invert(sensor_list, 1);
}
#endif
else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static void sensors_free_features(void) {
char errbuf[1024];
ERROR("sensors plugin: fopen(%s) failed: %s", conffile,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
}
if (status != 0) {
ERROR("sensors plugin: Cannot initialize sensors. "
"Data will not be collected.");
- return (-1);
+ return -1;
}
#if SENSORS_API_VERSION < 0x400
if ((feature->type != SENSORS_FEATURE_IN) &&
(feature->type != SENSORS_FEATURE_FAN) &&
(feature->type != SENSORS_FEATURE_TEMP) &&
+#if SENSORS_API_VERSION >= 0x402
+ (feature->type != SENSORS_FEATURE_CURR) &&
+#endif
(feature->type != SENSORS_FEATURE_POWER)) {
DEBUG("sensors plugin: sensors_load_conf: "
"Ignoring feature `%s', "
if ((subfeature->type != SENSORS_SUBFEATURE_IN_INPUT) &&
(subfeature->type != SENSORS_SUBFEATURE_FAN_INPUT) &&
(subfeature->type != SENSORS_SUBFEATURE_TEMP_INPUT) &&
+#if SENSORS_API_VERSION >= 0x402
+ (subfeature->type != SENSORS_SUBFEATURE_CURR_INPUT) &&
+#endif
(subfeature->type != SENSORS_SUBFEATURE_POWER_INPUT))
continue;
sensors_cleanup();
INFO("sensors plugin: lm_sensors reports no "
"features. Data will not be collected.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int sensors_load_conf */
static int sensors_shutdown(void) {
sensors_free_features();
ignorelist_free(sensor_list);
- return (0);
+ return 0;
} /* int sensors_shutdown */
static void sensors_submit(const char *plugin_instance, const char *type,
value_list_t vl = VALUE_LIST_INIT;
- status = ssnprintf(match_key, sizeof(match_key), "%s/%s-%s", plugin_instance,
- type, type_instance);
+ status = snprintf(match_key, sizeof(match_key), "%s/%s-%s", plugin_instance,
+ type, type_instance);
if (status < 1)
return;
static int sensors_read(void) {
if (sensors_load_conf() != 0)
- return (-1);
+ return -1;
#if SENSORS_API_VERSION < 0x400
for (featurelist_t *fl = first_feature; fl != NULL; fl = fl->next) {
type = "temperature";
else if (fl->feature->type == SENSORS_FEATURE_POWER)
type = "power";
+#if SENSORS_API_VERSION >= 0x402
+ else if (fl->feature->type == SENSORS_FEATURE_CURR)
+ type = "current";
+#endif
else
continue;
} /* for fl = first_feature .. NULL */
#endif /* (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) */
- return (0);
+ return 0;
} /* int sensors_read */
void module_register(void) {
(fh = fopen("/proc/tty/driver/ttyS", "r")) == NULL) {
char errbuf[1024];
WARNING("serial: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
}
fclose(fh);
- return (0);
+ return 0;
} /* int serial_read */
void module_register(void) {
}
cfdev->sdi = devlist->data;
g_slist_free(devlist);
- ssnprintf(hwident, sizeof(hwident), "%s %s %s",
- cfdev->sdi->vendor ? cfdev->sdi->vendor : "",
- cfdev->sdi->model ? cfdev->sdi->model : "",
- cfdev->sdi->version ? cfdev->sdi->version : "");
+ snprintf(hwident, sizeof(hwident), "%s %s %s",
+ cfdev->sdi->vendor ? cfdev->sdi->vendor : "",
+ cfdev->sdi->model ? cfdev->sdi->model : "",
+ cfdev->sdi->version ? cfdev->sdi->version : "");
INFO("sigrok plugin: Device \"%s\" is a %s", cfdev->name, hwident);
if (sr_dev_open(cfdev->sdi) != SR_OK)
if (ignorelist == NULL)
ignorelist = ignorelist_create(/* invert = */ 1);
if (ignorelist == NULL)
- return (1);
+ return 1;
if (strcasecmp("Disk", key) == 0) {
ignorelist_add(ignorelist, value);
if (IS_TRUE(value))
use_serial = 1;
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int smart_config */
static void smart_submit(const char *dev, const char *type,
sstrncpy(notif.host, hostname_g, sizeof(notif.host));
sstrncpy(notif.plugin_instance, name, sizeof(notif.plugin_instance));
sstrncpy(notif.type_instance, a->name, sizeof(notif.type_instance));
- ssnprintf(notif.message, sizeof(notif.message),
- "attribute %s is below allowed threshold (%d < %d)", a->name,
- a->current_value, a->threshold);
+ snprintf(notif.message, sizeof(notif.message),
+ "attribute %s is below allowed threshold (%d < %d)", a->name,
+ a->current_value, a->threshold);
plugin_dispatch_notification(¬if);
}
}
handle_udev = udev_new();
if (!handle_udev) {
ERROR("smart plugin: unable to initialize udev.");
- return (-1);
+ return -1;
}
enumerate = udev_enumerate_new(handle_udev);
udev_enumerate_add_match_subsystem(enumerate, "block");
udev_enumerate_unref(enumerate);
udev_unref(handle_udev);
- return (0);
+ return 0;
} /* int smart_read */
static int smart_init(void) {
"running \"setcap cap_sys_rawio=ep\" on the collectd binary.");
}
#endif
- return (0);
+ return 0;
} /* int smart_init */
void module_register(void) {
struct data_definition_s *next;
char **ignores;
size_t ignores_len;
- int invert_match;
+ _Bool invert_match;
};
typedef struct data_definition_s data_definition_t;
char *name;
char *address;
int version;
+ cdtime_t timeout;
+ int retries;
/* snmpv1/2 options */
char *community;
}
static int csnmp_oid_compare(oid_t const *left, oid_t const *right) {
- return (
- snmp_oid_compare(left->oid, left->oid_len, right->oid, right->oid_len));
+ return snmp_oid_compare(left->oid, left->oid_len, right->oid, right->oid_len);
}
static int csnmp_oid_suffix(oid_t *dst, oid_t const *src, oid_t const *root) {
/* Make sure "src" is in "root"s subtree. */
if (src->oid_len <= root->oid_len)
- return (EINVAL);
+ return EINVAL;
if (snmp_oid_ncompare(root->oid, root->oid_len, src->oid, src->oid_len,
/* n = */ root->oid_len) != 0)
- return (EINVAL);
+ return EINVAL;
memset(dst, 0, sizeof(*dst));
dst->oid_len = src->oid_len - root->oid_len;
memcpy(dst->oid, &src->oid[root->oid_len],
dst->oid_len * sizeof(dst->oid[0]));
- return (0);
+ return 0;
}
static int csnmp_oid_to_string(char *buffer, size_t buffer_size,
char *oid_str_ptr[MAX_OID_LEN];
for (size_t i = 0; i < o->oid_len; i++) {
- ssnprintf(oid_str[i], sizeof(oid_str[i]), "%lu", (unsigned long)o->oid[i]);
+ snprintf(oid_str[i], sizeof(oid_str[i]), "%lu", (unsigned long)o->oid[i]);
oid_str_ptr[i] = oid_str[i];
}
- return (strjoin(buffer, buffer_size, oid_str_ptr, o->oid_len,
- /* separator = */ "."));
+ return strjoin(buffer, buffer_size, oid_str_ptr, o->oid_len, ".");
}
static void csnmp_host_close_session(host_definition_t *host) /* {{{ */
if (!read_objid(buffer, dd->instance.oid.oid, &dd->instance.oid.oid_len)) {
ERROR("snmp plugin: read_objid (%s) failed.", buffer);
- return (-1);
+ return -1;
}
} else {
/* Instance is a simple string */
sstrncpy(dd->instance.string, buffer, sizeof(dd->instance.string));
}
- return (0);
+ return 0;
} /* int csnmp_config_add_data_instance */
static int csnmp_config_add_data_instance_prefix(data_definition_t *dd,
WARNING("snmp plugin: data %s: InstancePrefix is ignored when `Table' "
"is set to `false'.",
dd->name);
- return (-1);
+ return -1;
}
status = cf_util_get_string(ci, &dd->instance_prefix);
oconfig_item_t *ci) {
if (ci->values_num < 1) {
WARNING("snmp plugin: `Values' needs at least one argument.");
- return (-1);
+ return -1;
}
for (int i = 0; i < ci->values_num; i++)
if (ci->values[i].type != OCONFIG_TYPE_STRING) {
WARNING("snmp plugin: `Values' needs only string argument.");
- return (-1);
+ return -1;
}
sfree(dd->values);
dd->values_len = 0;
dd->values = malloc(sizeof(*dd->values) * ci->values_num);
if (dd->values == NULL)
- return (-1);
+ return -1;
dd->values_len = (size_t)ci->values_num;
for (int i = 0; i < ci->values_num; i++) {
free(dd->values);
dd->values = NULL;
dd->values_len = 0;
- return (-1);
+ return -1;
}
}
- return (0);
+ return 0;
} /* int csnmp_config_add_data_instance */
static int csnmp_config_add_data_blacklist(data_definition_t *dd,
oconfig_item_t *ci) {
if (ci->values_num < 1)
- return (0);
+ return 0;
for (int i = 0; i < ci->values_num; i++) {
if (ci->values[i].type != OCONFIG_TYPE_STRING) {
WARNING("snmp plugin: `Ignore' needs only string argument.");
- return (-1);
+ return -1;
}
}
ci->values[i].value.string) != 0) {
ERROR("snmp plugin: Can't allocate memory");
strarray_free(dd->ignores, dd->ignores_len);
- return (ENOMEM);
+ return ENOMEM;
}
}
return 0;
} /* int csnmp_config_add_data_blacklist */
-static int csnmp_config_add_data_blacklist_match_inverted(data_definition_t *dd,
- oconfig_item_t *ci) {
- if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) {
- WARNING("snmp plugin: `InvertMatch' needs exactly one boolean argument.");
- return (-1);
- }
-
- dd->invert_match = ci->values[0].value.boolean ? 1 : 0;
-
- return (0);
-} /* int csnmp_config_add_data_blacklist_match_inverted */
-
static int csnmp_config_add_data(oconfig_item_t *ci) {
- data_definition_t *dd;
- int status = 0;
-
- dd = calloc(1, sizeof(*dd));
+ data_definition_t *dd = calloc(1, sizeof(*dd));
if (dd == NULL)
- return (-1);
+ return -1;
- status = cf_util_get_string(ci, &dd->name);
+ int status = cf_util_get_string(ci, &dd->name);
if (status != 0) {
- free(dd);
- return (-1);
+ sfree(dd);
+ return -1;
}
dd->scale = 1.0;
else if (strcasecmp("Ignore", option->key) == 0)
status = csnmp_config_add_data_blacklist(dd, option);
else if (strcasecmp("InvertMatch", option->key) == 0)
- status = csnmp_config_add_data_blacklist_match_inverted(dd, option);
+ status = cf_util_get_boolean(option, &dd->invert_match);
else {
WARNING("snmp plugin: Option `%s' not allowed here.", option->key);
status = -1;
sfree(dd->values);
sfree(dd->ignores);
sfree(dd);
- return (-1);
+ return -1;
}
DEBUG("snmp plugin: dd = { name = %s, type = %s, is_table = %s, values_len = "
last->next = dd;
}
- return (0);
+ return 0;
} /* int csnmp_config_add_data */
static int csnmp_config_add_host_version(host_definition_t *hd,
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)) {
WARNING("snmp plugin: The `Version' config option needs exactly one number "
"argument.");
- return (-1);
+ return -1;
}
version = (int)ci->values[0].value.number;
if ((version < 1) || (version > 3)) {
WARNING("snmp plugin: `Version' must either be `1', `2', or `3'.");
- return (-1);
+ return -1;
}
hd->version = version;
- return (0);
+ return 0;
} /* int csnmp_config_add_host_address */
static int csnmp_config_add_host_collect(host_definition_t *host,
if (ci->values_num < 1) {
WARNING("snmp plugin: `Collect' needs at least one argument.");
- return (-1);
+ return -1;
}
for (int i = 0; i < ci->values_num; i++)
if (ci->values[i].type != OCONFIG_TYPE_STRING) {
WARNING("snmp plugin: All arguments to `Collect' must be strings.");
- return (-1);
+ return -1;
}
data_list_len = host->data_list_len + ci->values_num;
data_list =
realloc(host->data_list, sizeof(data_definition_t *) * data_list_len);
if (data_list == NULL)
- return (-1);
+ return -1;
host->data_list = data_list;
for (int i = 0; i < ci->values_num; i++) {
host->data_list_len++;
} /* for (values_num) */
- return (0);
+ return 0;
} /* int csnmp_config_add_host_collect */
static int csnmp_config_add_host_auth_protocol(host_definition_t *hd,
} else {
WARNING("snmp plugin: The `AuthProtocol' config option must be `MD5' or "
"`SHA'.");
- return (-1);
+ return -1;
}
DEBUG("snmp plugin: host = %s; host->auth_protocol = %s;", hd->name,
hd->auth_protocol == usmHMACMD5AuthProtocol ? "MD5" : "SHA");
- return (0);
+ return 0;
} /* int csnmp_config_add_host_auth_protocol */
static int csnmp_config_add_host_priv_protocol(host_definition_t *hd,
} else {
WARNING("snmp plugin: The `PrivProtocol' config option must be `AES' or "
"`DES'.");
- return (-1);
+ return -1;
}
DEBUG("snmp plugin: host = %s; host->priv_protocol = %s;", hd->name,
hd->priv_protocol == usmAESPrivProtocol ? "AES" : "DES");
- return (0);
+ return 0;
} /* int csnmp_config_add_host_priv_protocol */
static int csnmp_config_add_host_security_level(host_definition_t *hd,
else {
WARNING("snmp plugin: The `SecurityLevel' config option must be "
"`noAuthNoPriv', `authNoPriv', or `authPriv'.");
- return (-1);
+ return -1;
}
DEBUG("snmp plugin: host = %s; host->security_level = %d;", hd->name,
hd->security_level);
- return (0);
+ return 0;
} /* int csnmp_config_add_host_security_level */
static int csnmp_config_add_host(oconfig_item_t *ci) {
hd = calloc(1, sizeof(*hd));
if (hd == NULL)
- return (-1);
+ return -1;
hd->version = 2;
C_COMPLAIN_INIT(&hd->complaint);
hd->sess_handle = NULL;
hd->interval = 0;
+ /* These mean that we have not set a timeout or retry value */
+ hd->timeout = 0;
+ hd->retries = -1;
+
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *option = ci->children + i;
status = 0;
status = cf_util_get_string(option, &hd->community);
else if (strcasecmp("Version", option->key) == 0)
status = csnmp_config_add_host_version(hd, option);
+ else if (strcasecmp("Timeout", option->key) == 0)
+ cf_util_get_cdtime(option, &hd->timeout);
+ else if (strcasecmp("Retries", option->key) == 0)
+ cf_util_get_int(option, &hd->retries);
else if (strcasecmp("Collect", option->key) == 0)
csnmp_config_add_host_collect(hd, option);
else if (strcasecmp("Interval", option->key) == 0)
if (status != 0) {
csnmp_host_definition_destroy(hd);
- return (-1);
+ return -1;
}
DEBUG("snmp plugin: hd = { name = %s, address = %s, community = %s, version "
"= %i }",
hd->name, hd->address, hd->community, hd->version);
- ssnprintf(cb_name, sizeof(cb_name), "snmp-%s", hd->name);
+ snprintf(cb_name, sizeof(cb_name), "snmp-%s", hd->name);
status = plugin_register_complex_read(
/* group = */ NULL, cb_name, csnmp_read_host, hd->interval,
});
if (status != 0) {
ERROR("snmp plugin: Registering complex read function failed.");
- csnmp_host_definition_destroy(hd);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int csnmp_config_add_host */
static int csnmp_config(oconfig_item_t *ci) {
}
} /* for (ci->children) */
- return (0);
+ return 0;
} /* int csnmp_config */
/* }}} End of the config stuff. Now the interesting part begins */
sess.community_len = strlen(host->community);
}
+ /* Set timeout & retries, if they have been changed from the default */
+ if (host->timeout != 0) {
+ /* net-snmp expects microseconds */
+ sess.timeout = CDTIME_T_TO_US(host->timeout);
+ }
+ if (host->retries >= 0) {
+ sess.retries = host->retries;
+ }
+
/* snmp_sess_open will copy the `struct snmp_session *'. */
host->sess_handle = snmp_sess_open(&sess);
ret.gauge = NAN;
}
- return (ret);
+ return ret;
} /* value_t csnmp_value_list_to_value */
/* csnmp_strvbcopy_hexstring converts the bit string contained in "vb" to a hex
else if (vb->type == ASN_BIT_STR)
src = (char *)vb->val.bitstring;
else if (vb->type == ASN_IPADDRESS) {
- return ssnprintf(dst, dst_size,
- "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 "",
- (uint8_t)vb->val.string[0], (uint8_t)vb->val.string[1],
- (uint8_t)vb->val.string[2], (uint8_t)vb->val.string[3]);
+ return snprintf(dst, dst_size,
+ "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 "",
+ (uint8_t)vb->val.string[0], (uint8_t)vb->val.string[1],
+ (uint8_t)vb->val.string[2], (uint8_t)vb->val.string[3]);
} else {
dst[0] = 0;
- return (EINVAL);
+ return EINVAL;
}
num_chars = dst_size - 1;
for (size_t i = 0; i < num_chars; i++) {
/* Check for control characters. */
if ((unsigned char)src[i] < 32)
- return (csnmp_strvbcopy_hexstring(dst, vb, dst_size));
+ return csnmp_strvbcopy_hexstring(dst, vb, dst_size);
dst[i] = src[i];
}
dst[num_chars] = 0;
struct variable_list *vb;
oid_t vb_name;
int status;
- uint32_t is_matched;
/* Set vb on the last variable */
for (vb = res->variables; (vb != NULL) && (vb->next_variable != NULL);
vb = vb->next_variable)
/* do nothing */;
if (vb == NULL)
- return (-1);
+ return -1;
csnmp_oid_init(&vb_name, vb->name, vb->name_length);
il = calloc(1, sizeof(*il));
if (il == NULL) {
ERROR("snmp plugin: calloc failed.");
- return (-1);
+ return -1;
}
il->next = NULL;
status = csnmp_oid_suffix(&il->suffix, &vb_name, &dd->instance.oid);
if (status != 0) {
sfree(il);
- return (status);
+ return status;
}
/* Get instance name */
char *ptr;
csnmp_strvbcopy(il->instance, vb, sizeof(il->instance));
- is_matched = 0;
+ _Bool is_matched = 0;
for (uint32_t i = 0; i < dd->ignores_len; i++) {
status = fnmatch(dd->ignores[i], il->instance, 0);
if (status == 0) {
- if (dd->invert_match == 0) {
+ if (!dd->invert_match) {
sfree(il);
return 0;
} else {
}
}
}
- if (dd->invert_match != 0 && is_matched == 0) {
+ if (dd->invert_match && !is_matched) {
sfree(il);
return 0;
}
value_t val = csnmp_value_list_to_value(
vb, DS_TYPE_COUNTER,
/* scale = */ 1.0, /* shift = */ 0.0, hd->name, dd->name);
- ssnprintf(il->instance, sizeof(il->instance), "%llu", val.counter);
+ snprintf(il->instance, sizeof(il->instance), "%llu", val.counter);
}
/* TODO: Debugging output */
(*tail)->next = il;
*tail = il;
- return (0);
+ return 0;
} /* int csnmp_instance_list_add */
static int csnmp_dispatch_table(host_definition_t *host,
value_list_t vl = VALUE_LIST_INIT;
csnmp_list_instances_t *instance_list_ptr;
- csnmp_table_values_t **value_table_ptr;
+ csnmp_table_values_t *value_table_ptr[data->values_len];
size_t i;
_Bool have_more;
ds = plugin_get_ds(data->type);
if (!ds) {
ERROR("snmp plugin: DataSet `%s' not defined.", data->type);
- return (-1);
+ return -1;
}
assert(ds->ds_num == data->values_len);
assert(data->values_len > 0);
instance_list_ptr = instance_list;
- value_table_ptr = calloc(data->values_len, sizeof(*value_table_ptr));
- if (value_table_ptr == NULL)
- return (-1);
for (i = 0; i < data->values_len; i++)
value_table_ptr[i] = value_table[i];
- vl.values_len = data->values_len;
- vl.values = malloc(sizeof(*vl.values) * vl.values_len);
- if (vl.values == NULL) {
- ERROR("snmp plugin: malloc failed.");
- sfree(value_table_ptr);
- return (-1);
- }
-
sstrncpy(vl.host, host->name, sizeof(vl.host));
sstrncpy(vl.plugin, "snmp", sizeof(vl.plugin));
memcpy(¤t_suffix, &instance_list_ptr->suffix,
sizeof(current_suffix));
- } else /* no instance configured */
- {
+ } else {
+ /* no instance configured */
csnmp_table_values_t *ptr = value_table_ptr[0];
if (ptr == NULL) {
have_more = 0;
if (data->instance_prefix == NULL)
sstrncpy(vl.type_instance, temp, sizeof(vl.type_instance));
else
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s%s",
- data->instance_prefix, temp);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%s%s",
+ data->instance_prefix, temp);
}
+ vl.values_len = data->values_len;
+ value_t values[vl.values_len];
+ vl.values = values;
+
for (i = 0; i < data->values_len; i++)
vl.values[i] = value_table_ptr[i]->value;
if (vl.type_instance[0] != '\0')
plugin_dispatch_values(&vl);
+ /* prevent leakage of pointer to local variable. */
+ vl.values_len = 0;
+ vl.values = NULL;
+
if (instance_list != NULL)
instance_list_ptr = instance_list_ptr->next;
else
value_table_ptr[0] = value_table_ptr[0]->next;
} /* while (have_more) */
- sfree(vl.values);
- sfree(value_table_ptr);
-
return (0);
} /* int csnmp_dispatch_table */
if (host->sess_handle == NULL) {
DEBUG("snmp plugin: csnmp_read_table: host->sess_handle == NULL");
- return (-1);
+ return -1;
}
ds = plugin_get_ds(data->type);
if (!ds) {
ERROR("snmp plugin: DataSet `%s' not defined.", data->type);
- return (-1);
+ return -1;
}
if (ds->ds_num != data->values_len) {
ERROR("snmp plugin: DataSet `%s' requires %zu values, but config talks "
"about %zu",
data->type, ds->ds_num, data->values_len);
- return (-1);
+ return -1;
}
assert(data->values_len > 0);
ERROR("snmp plugin: csnmp_read_table: calloc failed.");
sfree(value_list_head);
sfree(value_list_tail);
- return (-1);
+ return -1;
}
instance_list_head = NULL;
status = 0;
while (status == 0) {
- int oid_list_todo_num;
-
req = snmp_pdu_create(SNMP_MSG_GETNEXT);
if (req == NULL) {
ERROR("snmp plugin: snmp_pdu_create failed.");
break;
}
- oid_list_todo_num = 0;
+ size_t oid_list_todo_num = 0;
+ size_t var_idx[oid_list_len];
+ memset(var_idx, 0, sizeof(var_idx));
+
for (i = 0; i < oid_list_len; i++) {
/* Do not rerequest already finished OIDs */
if (!oid_list_todo[i])
continue;
- oid_list_todo_num++;
snmp_add_null_var(req, oid_list[i].oid, oid_list[i].oid_len);
+ var_idx[oid_list_todo_num] = i;
+ oid_list_todo_num++;
}
if (oid_list_todo_num == 0) {
break;
}
+ if (res->errstat != SNMP_ERR_NOERROR) {
+ if (res->errindex != 0) {
+ /* Find the OID which caused error */
+ for (i = 1, vb = res->variables; vb != NULL && i != res->errindex;
+ vb = vb->next_variable, i++)
+ /* do nothing */;
+ }
+
+ if ((res->errindex == 0) || (vb == NULL)) {
+ ERROR("snmp plugin: host %s; data %s: response error: %s (%li) ",
+ host->name, data->name, snmp_errstring(res->errstat),
+ res->errstat);
+ status = -1;
+ break;
+ }
+
+ char oid_buffer[1024] = {0};
+ snprint_objid(oid_buffer, sizeof(oid_buffer) - 1, vb->name,
+ vb->name_length);
+ NOTICE("snmp plugin: host %s; data %s: OID `%s` failed: %s", host->name,
+ data->name, oid_buffer, snmp_errstring(res->errstat));
+
+ /* Get value index from todo list and skip OID found */
+ assert(res->errindex <= oid_list_todo_num);
+ i = var_idx[res->errindex - 1];
+ assert(i < oid_list_len);
+ oid_list_todo[i] = 0;
+
+ snmp_free_pdu(res);
+ res = NULL;
+ continue;
+ }
+
for (vb = res->variables, i = 0; (vb != NULL);
vb = vb->next_variable, i++) {
/* Calculate value index from todo list */
sfree(value_list_head);
sfree(value_list_tail);
- return (0);
+ return 0;
} /* int csnmp_read_table */
static int csnmp_read_value(host_definition_t *host, data_definition_t *data) {
if (host->sess_handle == NULL) {
DEBUG("snmp plugin: csnmp_read_value: host->sess_handle == NULL");
- return (-1);
+ return -1;
}
ds = plugin_get_ds(data->type);
if (!ds) {
ERROR("snmp plugin: DataSet `%s' not defined.", data->type);
- return (-1);
+ return -1;
}
if (ds->ds_num != data->values_len) {
ERROR("snmp plugin: DataSet `%s' requires %zu values, but config talks "
"about %zu",
data->type, ds->ds_num, data->values_len);
- return (-1);
+ return -1;
}
vl.values_len = ds->ds_num;
vl.values = malloc(sizeof(*vl.values) * vl.values_len);
if (vl.values == NULL)
- return (-1);
+ return -1;
for (i = 0; i < vl.values_len; i++) {
if (ds->ds[i].type == DS_TYPE_COUNTER)
vl.values[i].counter = 0;
if (req == NULL) {
ERROR("snmp plugin: snmp_pdu_create failed.");
sfree(vl.values);
- return (-1);
+ return -1;
}
for (i = 0; i < data->values_len; i++)
sfree(vl.values);
csnmp_host_close_session(host);
- return (-1);
+ return -1;
}
for (vb = res->variables; vb != NULL; vb = vb->next_variable) {
plugin_dispatch_values(&vl);
sfree(vl.values);
- return (0);
+ return 0;
} /* int csnmp_read_value */
static int csnmp_read_host(user_data_t *ud) {
csnmp_host_open_session(host);
if (host->sess_handle == NULL)
- return (-1);
+ return -1;
success = 0;
for (i = 0; i < host->data_list_len; i++) {
}
if (success == 0)
- return (-1);
+ return -1;
- return (0);
+ return 0;
} /* int csnmp_read_host */
static int csnmp_init(void) {
call_snmp_init_once();
- return (0);
+ return 0;
} /* int csnmp_init */
static int csnmp_shutdown(void) {
data_this = data_next;
}
- return (0);
+ return 0;
} /* int csnmp_shutdown */
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
- */
--- /dev/null
+/**
+ * collectd - src/snmp_agent.c
+ *
+ * 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:
+ * Roman Korynkevych <romanx.korynkevych@intel.com>
+ * Serhiy Pshyk <serhiyx.pshyk@intel.com>
+ **/
+
+#include "collectd.h"
+
+#include "common.h"
+#include "utils_avltree.h"
+#include "utils_cache.h"
+#include "utils_llist.h"
+
+#include <net-snmp/net-snmp-config.h>
+
+#include <net-snmp/net-snmp-includes.h>
+
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#define PLUGIN_NAME "snmp_agent"
+#define ERR_BUF_SIZE 1024
+#define TYPE_STRING -1
+
+#ifndef MIN
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#endif
+
+struct oid_s {
+ oid oid[MAX_OID_LEN];
+ size_t oid_len;
+ u_char type;
+};
+typedef struct oid_s oid_t;
+
+struct table_definition_s {
+ char *name;
+ oid_t index_oid;
+ oid_t size_oid;
+ llist_t *columns;
+ c_avl_tree_t *instance_index;
+ c_avl_tree_t *index_instance;
+};
+typedef struct table_definition_s table_definition_t;
+
+struct data_definition_s {
+ char *name;
+ char *plugin;
+ char *plugin_instance;
+ char *type;
+ char *type_instance;
+ const table_definition_t *table;
+ _Bool is_instance;
+ oid_t *oids;
+ size_t oids_len;
+ double scale;
+ double shift;
+};
+typedef struct data_definition_s data_definition_t;
+
+struct snmp_agent_ctx_s {
+ pthread_t thread;
+ pthread_mutex_t lock;
+ pthread_mutex_t agentx_lock;
+ struct tree *tp;
+
+ llist_t *tables;
+ llist_t *scalars;
+};
+typedef struct snmp_agent_ctx_s snmp_agent_ctx_t;
+
+static snmp_agent_ctx_t *g_agent = NULL;
+
+#define CHECK_DD_TYPE(_dd, _p, _pi, _t, _ti) \
+ (_dd->plugin ? !strcmp(_dd->plugin, _p) : 0) && \
+ (_dd->plugin_instance ? !strcmp(_dd->plugin_instance, _pi) : 1) && \
+ (_dd->type ? !strcmp(_dd->type, _t) : 0) && \
+ (_dd->type_instance ? !strcmp(_dd->type_instance, _ti) : 1)
+
+static int snmp_agent_shutdown(void);
+static void *snmp_agent_thread_run(void *arg);
+static int snmp_agent_register_oid(oid_t *oid, Netsnmp_Node_Handler *handler);
+static int snmp_agent_set_vardata(void *dst_buf, size_t *dst_buf_len,
+ u_char asn_type, double scale, double shift,
+ const void *value, size_t len, int type);
+static int snmp_agent_unregister_oid_index(oid_t *oid, int index);
+
+static u_char snmp_agent_get_asn_type(oid *oid, size_t oid_len) {
+ struct tree *node = get_tree(oid, oid_len, g_agent->tp);
+
+ return (node != NULL) ? mib_to_asn_type(node->type) : 0;
+}
+
+static char *snmp_agent_get_oid_name(oid *oid, size_t oid_len) {
+ struct tree *node = get_tree(oid, oid_len, g_agent->tp);
+
+ return (node != NULL) ? node->label : NULL;
+}
+
+static int snmp_agent_oid_to_string(char *buf, size_t buf_size,
+ oid_t const *o) {
+ char oid_str[MAX_OID_LEN][16];
+ char *oid_str_ptr[MAX_OID_LEN];
+
+ for (size_t i = 0; i < o->oid_len; i++) {
+ snprintf(oid_str[i], sizeof(oid_str[i]), "%lu", (unsigned long)o->oid[i]);
+ oid_str_ptr[i] = oid_str[i];
+ }
+
+ return strjoin(buf, buf_size, oid_str_ptr, o->oid_len, ".");
+}
+
+static void snmp_agent_dump_data(void) {
+#if COLLECT_DEBUG
+ char oid_str[DATA_MAX_NAME_LEN];
+
+ for (llentry_t *te = llist_head(g_agent->tables); te != NULL; te = te->next) {
+ table_definition_t *td = te->value;
+
+ DEBUG(PLUGIN_NAME ": Table:");
+ DEBUG(PLUGIN_NAME ": Name: %s", td->name);
+ if (td->index_oid.oid_len != 0) {
+ snmp_agent_oid_to_string(oid_str, sizeof(oid_str), &td->index_oid);
+ DEBUG(PLUGIN_NAME ": IndexOID: %s", oid_str);
+ }
+ if (td->size_oid.oid_len != 0) {
+ snmp_agent_oid_to_string(oid_str, sizeof(oid_str), &td->size_oid);
+ DEBUG(PLUGIN_NAME ": SizeOID: %s", oid_str);
+ }
+
+ for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
+ data_definition_t *dd = de->value;
+
+ DEBUG(PLUGIN_NAME ": Column:");
+ DEBUG(PLUGIN_NAME ": Name: %s", dd->name);
+ if (dd->plugin)
+ DEBUG(PLUGIN_NAME ": Plugin: %s", dd->plugin);
+ if (dd->plugin_instance)
+ DEBUG(PLUGIN_NAME ": PluginInstance: %s", dd->plugin_instance);
+ if (dd->is_instance)
+ DEBUG(PLUGIN_NAME ": Instance: true");
+ if (dd->type)
+ DEBUG(PLUGIN_NAME ": Type: %s", dd->type);
+ if (dd->type_instance)
+ DEBUG(PLUGIN_NAME ": TypeInstance: %s", dd->type_instance);
+ for (size_t i = 0; i < dd->oids_len; i++) {
+ snmp_agent_oid_to_string(oid_str, sizeof(oid_str), &dd->oids[i]);
+ DEBUG(PLUGIN_NAME ": OID[%zu]: %s", i, oid_str);
+ }
+ DEBUG(PLUGIN_NAME ": Scale: %g", dd->scale);
+ DEBUG(PLUGIN_NAME ": Shift: %g", dd->shift);
+ }
+ }
+
+ for (llentry_t *e = llist_head(g_agent->scalars); e != NULL; e = e->next) {
+ data_definition_t *dd = e->value;
+
+ DEBUG(PLUGIN_NAME ": Scalar:");
+ DEBUG(PLUGIN_NAME ": Name: %s", dd->name);
+ if (dd->plugin)
+ DEBUG(PLUGIN_NAME ": Plugin: %s", dd->plugin);
+ if (dd->plugin_instance)
+ DEBUG(PLUGIN_NAME ": PluginInstance: %s", dd->plugin_instance);
+ if (dd->is_instance)
+ DEBUG(PLUGIN_NAME ": Instance: true");
+ if (dd->type)
+ DEBUG(PLUGIN_NAME ": Type: %s", dd->type);
+ if (dd->type_instance)
+ DEBUG(PLUGIN_NAME ": TypeInstance: %s", dd->type_instance);
+ for (size_t i = 0; i < dd->oids_len; i++) {
+ snmp_agent_oid_to_string(oid_str, sizeof(oid_str), &dd->oids[i]);
+ DEBUG(PLUGIN_NAME ": OID[%zu]: %s", i, oid_str);
+ }
+ DEBUG(PLUGIN_NAME ": Scale: %g", dd->scale);
+ DEBUG(PLUGIN_NAME ": Shift: %g", dd->shift);
+ }
+#endif /* COLLECT_DEBUG */
+}
+
+static int snmp_agent_validate_data(void) {
+
+ snmp_agent_dump_data();
+
+ for (llentry_t *te = llist_head(g_agent->tables); te != NULL; te = te->next) {
+ table_definition_t *td = te->value;
+
+ for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
+ data_definition_t *dd = de->value;
+
+ if (!dd->plugin) {
+ ERROR(PLUGIN_NAME ": Plugin not defined for '%s'.'%s'", td->name,
+ dd->name);
+ return -EINVAL;
+ }
+
+ if (dd->plugin_instance) {
+ ERROR(PLUGIN_NAME ": PluginInstance should not be defined for table "
+ "data type '%s'.'%s'",
+ td->name, dd->name);
+ return -EINVAL;
+ }
+
+ if (dd->oids_len == 0) {
+ ERROR(PLUGIN_NAME ": No OIDs defined for '%s'.'%s'", td->name,
+ dd->name);
+ return -EINVAL;
+ }
+
+ if (dd->is_instance) {
+
+ if (dd->type || dd->type_instance) {
+ ERROR(PLUGIN_NAME ": Type and TypeInstance are not valid for "
+ "instance data '%s'.'%s'",
+ td->name, dd->name);
+ return -EINVAL;
+ }
+
+ if (dd->oids_len > 1) {
+ ERROR(
+ PLUGIN_NAME
+ ": Only one OID should be specified for instance data '%s'.'%s'",
+ td->name, dd->name);
+ return -EINVAL;
+ }
+ } else {
+
+ if (!dd->type) {
+ ERROR(PLUGIN_NAME ": Type not defined for data '%s'.'%s'", td->name,
+ dd->name);
+ return -EINVAL;
+ }
+ }
+ }
+ }
+
+ for (llentry_t *e = llist_head(g_agent->scalars); e != NULL; e = e->next) {
+ data_definition_t *dd = e->value;
+
+ if (!dd->plugin) {
+ ERROR(PLUGIN_NAME ": Plugin not defined for '%s'", dd->name);
+ return -EINVAL;
+ }
+
+ if (dd->oids_len == 0) {
+ ERROR(PLUGIN_NAME ": No OIDs defined for '%s'", dd->name);
+ return -EINVAL;
+ }
+
+ if (dd->is_instance) {
+ ERROR(PLUGIN_NAME
+ ": Instance flag can't be specified for scalar data '%s'",
+ dd->name);
+ return -EINVAL;
+ }
+
+ if (!dd->type) {
+ ERROR(PLUGIN_NAME ": Type not defined for data '%s'", dd->name);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static void snmp_agent_generate_oid2string(oid_t *oid, size_t offset,
+ char *key) {
+ int key_len = oid->oid[offset];
+ int i;
+
+ for (i = 0; i < key_len && offset < oid->oid_len; i++)
+ key[i] = oid->oid[++offset];
+
+ key[i] = '\0';
+}
+
+static int snmp_agent_generate_string2oid(oid_t *oid, const char *key) {
+ int key_len = strlen(key);
+
+ oid->oid[oid->oid_len++] = key_len;
+ for (int i = 0; i < key_len; i++) {
+ oid->oid[oid->oid_len++] = key[i];
+ if (oid->oid_len >= MAX_OID_LEN) {
+ ERROR(PLUGIN_NAME ": Conversion key string %s to OID failed", key);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int snmp_agent_register_oid_string(oid_t *oid, const char *key,
+ Netsnmp_Node_Handler *handler) {
+ oid_t new_oid;
+
+ memcpy(&new_oid, oid, sizeof(*oid));
+ int ret = snmp_agent_generate_string2oid(&new_oid, key);
+ if (ret != 0)
+ return ret;
+
+ return snmp_agent_register_oid(&new_oid, handler);
+}
+
+static int snmp_agent_unregister_oid_string(oid_t *oid, const char *key) {
+ oid_t new_oid;
+
+ memcpy(&new_oid, oid, sizeof(*oid));
+ int ret = snmp_agent_generate_string2oid(&new_oid, key);
+ if (ret != 0)
+ return ret;
+
+ return unregister_mib(new_oid.oid, new_oid.oid_len);
+}
+
+static int snmp_agent_table_row_remove(table_definition_t *td,
+ const char *instance) {
+ int *index = NULL;
+ char *ins = NULL;
+
+ if (td->index_oid.oid_len) {
+ if ((c_avl_get(td->instance_index, instance, (void **)&index) != 0) ||
+ (c_avl_get(td->index_instance, index, (void **)&ins) != 0))
+ return 0;
+ } else {
+ if (c_avl_get(td->instance_index, instance, (void **)&ins) != 0)
+ return 0;
+ }
+
+ pthread_mutex_lock(&g_agent->agentx_lock);
+
+ if (td->index_oid.oid_len)
+ snmp_agent_unregister_oid_index(&td->index_oid, *index);
+
+ for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
+ data_definition_t *dd = de->value;
+
+ for (size_t i = 0; i < dd->oids_len; i++)
+ if (td->index_oid.oid_len)
+ snmp_agent_unregister_oid_index(&dd->oids[i], *index);
+ else
+ snmp_agent_unregister_oid_string(&dd->oids[i], ins);
+ }
+
+ pthread_mutex_unlock(&g_agent->agentx_lock);
+
+ DEBUG(PLUGIN_NAME ": Removed row for '%s' table [%d, %s]", td->name,
+ (index != NULL) ? *index : -1, ins);
+
+ notification_t n = {
+ .severity = NOTIF_WARNING, .time = cdtime(), .plugin = PLUGIN_NAME};
+ sstrncpy(n.host, hostname_g, sizeof(n.host));
+ sstrncpy(n.plugin_instance, ins, sizeof(n.plugin_instance));
+ snprintf(n.message, sizeof(n.message),
+ "Removed data row from table %s instance %s index %d", td->name, ins,
+ (index != NULL) ? *index : -1);
+ plugin_dispatch_notification(&n);
+
+ if (td->index_oid.oid_len) {
+ c_avl_remove(td->index_instance, index, NULL, (void **)&ins);
+ c_avl_remove(td->instance_index, instance, NULL, (void **)&index);
+ sfree(index);
+ sfree(ins);
+ } else {
+ c_avl_remove(td->instance_index, instance, NULL, (void **)&ins);
+ sfree(ins);
+ }
+
+ return 0;
+}
+
+static int snmp_agent_clear_missing(const value_list_t *vl,
+ __attribute__((unused)) user_data_t *ud) {
+ if (vl == NULL)
+ return -EINVAL;
+
+ for (llentry_t *te = llist_head(g_agent->tables); te != NULL; te = te->next) {
+ table_definition_t *td = te->value;
+
+ for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
+ data_definition_t *dd = de->value;
+
+ if (!dd->is_instance) {
+ if (CHECK_DD_TYPE(dd, vl->plugin, vl->plugin_instance, vl->type,
+ vl->type_instance)) {
+ snmp_agent_table_row_remove(td, vl->plugin_instance);
+ return 0;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void snmp_agent_free_data(data_definition_t **dd) {
+
+ if (dd == NULL || *dd == NULL)
+ return;
+
+ /* unregister scalar type OID */
+ if ((*dd)->table == NULL) {
+ for (size_t i = 0; i < (*dd)->oids_len; i++)
+ unregister_mib((*dd)->oids[i].oid, (*dd)->oids[i].oid_len);
+ }
+
+ sfree((*dd)->name);
+ sfree((*dd)->plugin);
+ sfree((*dd)->plugin_instance);
+ sfree((*dd)->type);
+ sfree((*dd)->type_instance);
+ sfree((*dd)->oids);
+
+ sfree(*dd);
+
+ return;
+}
+
+static void snmp_agent_free_table_columns(table_definition_t *td) {
+ if (td->columns == NULL)
+ return;
+
+ for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
+ data_definition_t *dd = de->value;
+
+ if (td->index_oid.oid_len) {
+ int *index;
+ char *instance;
+
+ c_avl_iterator_t *iter = c_avl_get_iterator(td->index_instance);
+ while (c_avl_iterator_next(iter, (void *)&index, (void *)&instance) ==
+ 0) {
+ for (size_t i = 0; i < dd->oids_len; i++)
+ snmp_agent_unregister_oid_index(&dd->oids[i], *index);
+ }
+ c_avl_iterator_destroy(iter);
+ } else {
+ char *instance;
+
+ c_avl_iterator_t *iter = c_avl_get_iterator(dd->table->instance_index);
+ while (c_avl_iterator_next(iter, (void *)&instance, (void *)&instance) ==
+ 0) {
+ for (size_t i = 0; i < dd->oids_len; i++)
+ snmp_agent_unregister_oid_string(&dd->oids[i], instance);
+ }
+ c_avl_iterator_destroy(iter);
+ }
+
+ snmp_agent_free_data(&dd);
+ }
+
+ llist_destroy(td->columns);
+ td->columns = NULL;
+} /* void snmp_agent_free_table_columns */
+
+static void snmp_agent_free_table(table_definition_t **td) {
+
+ if (td == NULL || *td == NULL)
+ return;
+
+ if ((*td)->size_oid.oid_len)
+ unregister_mib((*td)->size_oid.oid, (*td)->size_oid.oid_len);
+
+ /* Unregister Index OIDs */
+ if ((*td)->index_oid.oid_len) {
+ int *index;
+ char *instance;
+
+ c_avl_iterator_t *iter = c_avl_get_iterator((*td)->index_instance);
+ while (c_avl_iterator_next(iter, (void *)&index, (void *)&instance) == 0)
+ snmp_agent_unregister_oid_index(&(*td)->index_oid, *index);
+
+ c_avl_iterator_destroy(iter);
+ }
+
+ /* Unregister all table columns and their registered OIDs */
+ snmp_agent_free_table_columns(*td);
+
+ void *key = NULL;
+ void *value = NULL;
+
+ /* index_instance and instance_index contain the same pointers */
+ c_avl_destroy((*td)->index_instance);
+ (*td)->index_instance = NULL;
+
+ if ((*td)->instance_index != NULL) {
+ while (c_avl_pick((*td)->instance_index, &key, &value) == 0) {
+ if (key != value)
+ sfree(key);
+ sfree(value);
+ }
+ c_avl_destroy((*td)->instance_index);
+ (*td)->instance_index = NULL;
+ }
+
+ sfree((*td)->name);
+ sfree(*td);
+
+ return;
+}
+
+static int snmp_agent_form_reply(struct netsnmp_request_info_s *requests,
+ data_definition_t *dd, char *instance,
+ int oid_index) {
+ char name[DATA_MAX_NAME_LEN];
+ format_name(name, sizeof(name), hostname_g, dd->plugin,
+ instance ? instance : dd->plugin_instance, dd->type,
+ dd->type_instance);
+ DEBUG(PLUGIN_NAME ": Identifier '%s'", name);
+
+ value_t *values;
+ size_t values_num;
+ const data_set_t *ds = plugin_get_ds(dd->type);
+ if (ds == NULL) {
+ ERROR(PLUGIN_NAME ": Data set not found for '%s' type", dd->type);
+ return SNMP_NOSUCHINSTANCE;
+ }
+
+ int ret = uc_get_value_by_name(name, &values, &values_num);
+
+ if (ret != 0) {
+ ERROR(PLUGIN_NAME ": Failed to get value for '%s'", name);
+ return SNMP_NOSUCHINSTANCE;
+ }
+
+ assert(ds->ds_num == values_num);
+ assert(oid_index < (int)values_num);
+
+ char data[DATA_MAX_NAME_LEN];
+ size_t data_len = sizeof(data);
+ ret = snmp_agent_set_vardata(
+ data, &data_len, dd->oids[oid_index].type, dd->scale, dd->shift,
+ &values[oid_index], sizeof(values[oid_index]), ds->ds[oid_index].type);
+
+ sfree(values);
+
+ if (ret != 0) {
+ ERROR(PLUGIN_NAME ": Failed to convert '%s' value to snmp data", name);
+ return SNMP_NOSUCHINSTANCE;
+ }
+
+ requests->requestvb->type = dd->oids[oid_index].type;
+ snmp_set_var_typed_value(requests->requestvb, requests->requestvb->type,
+ (const u_char *)data, data_len);
+
+ return SNMP_ERR_NOERROR;
+}
+
+static int
+snmp_agent_table_oid_handler(struct netsnmp_mib_handler_s *handler,
+ struct netsnmp_handler_registration_s *reginfo,
+ struct netsnmp_agent_request_info_s *reqinfo,
+ struct netsnmp_request_info_s *requests) {
+
+ if (reqinfo->mode != MODE_GET && reqinfo->mode != MODE_GETNEXT) {
+ DEBUG(PLUGIN_NAME ": Not supported request mode (%d)", reqinfo->mode);
+ return SNMP_ERR_NOERROR;
+ }
+
+ pthread_mutex_lock(&g_agent->lock);
+
+ oid_t oid;
+ memcpy(oid.oid, requests->requestvb->name,
+ sizeof(oid.oid[0]) * requests->requestvb->name_length);
+ oid.oid_len = requests->requestvb->name_length;
+
+#if COLLECT_DEBUG
+ char oid_str[DATA_MAX_NAME_LEN];
+ snmp_agent_oid_to_string(oid_str, sizeof(oid_str), &oid);
+ DEBUG(PLUGIN_NAME ": Get request received for table OID '%s'", oid_str);
+#endif
+
+ for (llentry_t *te = llist_head(g_agent->tables); te != NULL; te = te->next) {
+ table_definition_t *td = te->value;
+
+ for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
+ data_definition_t *dd = de->value;
+
+ for (size_t i = 0; i < dd->oids_len; i++) {
+ int ret = snmp_oid_ncompare(oid.oid, oid.oid_len, dd->oids[i].oid,
+ dd->oids[i].oid_len,
+ MIN(oid.oid_len, dd->oids[i].oid_len));
+ if (ret != 0)
+ continue;
+
+ char *instance;
+
+ if (!td->index_oid.oid_len) {
+ char key[MAX_OID_LEN];
+
+ memset(key, 0, sizeof(key));
+ snmp_agent_generate_oid2string(
+ &oid, MIN(oid.oid_len, dd->oids[i].oid_len), key);
+
+ ret = c_avl_get(td->instance_index, key, (void **)&instance);
+ if (ret != 0) {
+ DEBUG(PLUGIN_NAME ": Nonexisting index string '%s' requested", key);
+ pthread_mutex_unlock(&g_agent->lock);
+ return SNMP_NOSUCHINSTANCE;
+ }
+ } else {
+ int index = oid.oid[oid.oid_len - 1];
+
+ ret = c_avl_get(td->index_instance, &index, (void **)&instance);
+ if (ret != 0) {
+ DEBUG(PLUGIN_NAME ": Nonexisting index '%d' requested", index);
+ pthread_mutex_unlock(&g_agent->lock);
+ return SNMP_NOSUCHINSTANCE;
+ }
+ }
+
+ if (dd->is_instance) {
+ requests->requestvb->type = ASN_OCTET_STR;
+ snmp_set_var_typed_value(
+ requests->requestvb, requests->requestvb->type,
+ (const u_char *)instance, strlen((instance)));
+
+ pthread_mutex_unlock(&g_agent->lock);
+
+ return SNMP_ERR_NOERROR;
+ }
+
+ ret = snmp_agent_form_reply(requests, dd, instance, i);
+
+ pthread_mutex_unlock(&g_agent->lock);
+
+ return ret;
+ }
+ }
+ }
+
+ pthread_mutex_unlock(&g_agent->lock);
+
+ return SNMP_NOSUCHINSTANCE;
+}
+
+static int snmp_agent_table_index_oid_handler(
+ struct netsnmp_mib_handler_s *handler,
+ struct netsnmp_handler_registration_s *reginfo,
+ struct netsnmp_agent_request_info_s *reqinfo,
+ struct netsnmp_request_info_s *requests) {
+
+ if (reqinfo->mode != MODE_GET && reqinfo->mode != MODE_GETNEXT) {
+ DEBUG(PLUGIN_NAME ": Not supported request mode (%d)", reqinfo->mode);
+ return SNMP_ERR_NOERROR;
+ }
+
+ pthread_mutex_lock(&g_agent->lock);
+
+ oid_t oid;
+ memcpy(oid.oid, requests->requestvb->name,
+ sizeof(oid.oid[0]) * requests->requestvb->name_length);
+ oid.oid_len = requests->requestvb->name_length;
+
+ for (llentry_t *te = llist_head(g_agent->tables); te != NULL; te = te->next) {
+ table_definition_t *td = te->value;
+
+ if (td->index_oid.oid_len &&
+ (snmp_oid_ncompare(oid.oid, oid.oid_len, td->index_oid.oid,
+ td->index_oid.oid_len,
+ MIN(oid.oid_len, td->index_oid.oid_len)) == 0)) {
+
+ DEBUG(PLUGIN_NAME ": Handle '%s' table index OID", td->name);
+
+ int index = oid.oid[oid.oid_len - 1];
+
+ int ret = c_avl_get(td->index_instance, &index, &(void *){NULL});
+ if (ret != 0) {
+ /* nonexisting index requested */
+ pthread_mutex_unlock(&g_agent->lock);
+ return SNMP_NOSUCHINSTANCE;
+ }
+
+ requests->requestvb->type = ASN_INTEGER;
+ snmp_set_var_typed_value(requests->requestvb, requests->requestvb->type,
+ (const u_char *)&index, sizeof(index));
+
+ pthread_mutex_unlock(&g_agent->lock);
+
+ return SNMP_ERR_NOERROR;
+ }
+ }
+
+ pthread_mutex_unlock(&g_agent->lock);
+
+ return SNMP_NOSUCHINSTANCE;
+}
+
+static int snmp_agent_table_size_oid_handler(
+ struct netsnmp_mib_handler_s *handler,
+ struct netsnmp_handler_registration_s *reginfo,
+ struct netsnmp_agent_request_info_s *reqinfo,
+ struct netsnmp_request_info_s *requests) {
+
+ if (reqinfo->mode != MODE_GET && reqinfo->mode != MODE_GETNEXT) {
+ DEBUG(PLUGIN_NAME ": Not supported request mode (%d)", reqinfo->mode);
+ return SNMP_ERR_NOERROR;
+ }
+
+ pthread_mutex_lock(&g_agent->lock);
+
+ oid_t oid;
+ memcpy(oid.oid, requests->requestvb->name,
+ sizeof(oid.oid[0]) * requests->requestvb->name_length);
+ oid.oid_len = requests->requestvb->name_length;
+
+ DEBUG(PLUGIN_NAME ": Get request received for table size OID");
+
+ for (llentry_t *te = llist_head(g_agent->tables); te != NULL; te = te->next) {
+ table_definition_t *td = te->value;
+
+ if (td->size_oid.oid_len &&
+ (snmp_oid_ncompare(oid.oid, oid.oid_len, td->size_oid.oid,
+ td->size_oid.oid_len,
+ MIN(oid.oid_len, td->size_oid.oid_len)) == 0)) {
+ DEBUG(PLUGIN_NAME ": Handle '%s' table size OID", td->name);
+
+ long size = c_avl_size(td->index_instance);
+
+ requests->requestvb->type = td->size_oid.type;
+ snmp_set_var_typed_value(requests->requestvb, requests->requestvb->type,
+ (const u_char *)&size, sizeof(size));
+
+ pthread_mutex_unlock(&g_agent->lock);
+
+ return SNMP_ERR_NOERROR;
+ }
+ }
+
+ pthread_mutex_unlock(&g_agent->lock);
+
+ return SNMP_NOSUCHINSTANCE;
+}
+
+static int
+snmp_agent_scalar_oid_handler(struct netsnmp_mib_handler_s *handler,
+ struct netsnmp_handler_registration_s *reginfo,
+ struct netsnmp_agent_request_info_s *reqinfo,
+ struct netsnmp_request_info_s *requests) {
+
+ if (reqinfo->mode != MODE_GET && reqinfo->mode != MODE_GETNEXT) {
+ DEBUG(PLUGIN_NAME ": Not supported request mode (%d)", reqinfo->mode);
+ return SNMP_ERR_NOERROR;
+ }
+
+ pthread_mutex_lock(&g_agent->lock);
+
+ oid_t oid;
+ memcpy(oid.oid, requests->requestvb->name,
+ sizeof(oid.oid[0]) * requests->requestvb->name_length);
+ oid.oid_len = requests->requestvb->name_length;
+
+#if COLLECT_DEBUG
+ char oid_str[DATA_MAX_NAME_LEN];
+ snmp_agent_oid_to_string(oid_str, sizeof(oid_str), &oid);
+ DEBUG(PLUGIN_NAME ": Get request received for scalar OID '%s'", oid_str);
+#endif
+
+ for (llentry_t *de = llist_head(g_agent->scalars); de != NULL;
+ de = de->next) {
+ data_definition_t *dd = de->value;
+
+ for (size_t i = 0; i < dd->oids_len; i++) {
+
+ int ret = snmp_oid_compare(oid.oid, oid.oid_len, dd->oids[i].oid,
+ dd->oids[i].oid_len);
+ if (ret != 0)
+ continue;
+
+ ret = snmp_agent_form_reply(requests, dd, NULL, i);
+
+ pthread_mutex_unlock(&g_agent->lock);
+
+ return ret;
+ }
+ }
+
+ pthread_mutex_unlock(&g_agent->lock);
+
+ return SNMP_NOSUCHINSTANCE;
+}
+
+static int snmp_agent_register_table_oids(void) {
+
+ for (llentry_t *te = llist_head(g_agent->tables); te != NULL; te = te->next) {
+ table_definition_t *td = te->value;
+
+ if (td->size_oid.oid_len != 0) {
+ td->size_oid.type =
+ snmp_agent_get_asn_type(td->size_oid.oid, td->size_oid.oid_len);
+ td->size_oid.oid_len++;
+ int ret = snmp_agent_register_oid(&td->size_oid,
+ snmp_agent_table_size_oid_handler);
+ if (ret != 0)
+ return ret;
+ }
+
+ for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
+ data_definition_t *dd = de->value;
+
+ for (size_t i = 0; i < dd->oids_len; i++) {
+ dd->oids[i].type =
+ snmp_agent_get_asn_type(dd->oids[i].oid, dd->oids[i].oid_len);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int snmp_agent_register_scalar_oids(void) {
+
+ for (llentry_t *e = llist_head(g_agent->scalars); e != NULL; e = e->next) {
+ data_definition_t *dd = e->value;
+
+ for (size_t i = 0; i < dd->oids_len; i++) {
+
+ dd->oids[i].type =
+ snmp_agent_get_asn_type(dd->oids[i].oid, dd->oids[i].oid_len);
+
+ int ret =
+ snmp_agent_register_oid(&dd->oids[i], snmp_agent_scalar_oid_handler);
+ if (ret != 0)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int snmp_agent_config_data_oids(data_definition_t *dd,
+ oconfig_item_t *ci) {
+ if (ci->values_num < 1) {
+ WARNING(PLUGIN_NAME ": `OIDs' needs at least one argument");
+ return -EINVAL;
+ }
+
+ for (int i = 0; i < ci->values_num; i++)
+ if (ci->values[i].type != OCONFIG_TYPE_STRING) {
+ WARNING(PLUGIN_NAME ": `OIDs' needs only string argument");
+ return -EINVAL;
+ }
+
+ if (dd->oids != NULL)
+ sfree(dd->oids);
+ dd->oids_len = 0;
+ dd->oids = calloc(ci->values_num, sizeof(*dd->oids));
+ if (dd->oids == NULL)
+ return -ENOMEM;
+ dd->oids_len = (size_t)ci->values_num;
+
+ for (int i = 0; i < ci->values_num; i++) {
+ dd->oids[i].oid_len = MAX_OID_LEN;
+
+ if (NULL == snmp_parse_oid(ci->values[i].value.string, dd->oids[i].oid,
+ &dd->oids[i].oid_len)) {
+ ERROR(PLUGIN_NAME ": snmp_parse_oid (%s) failed",
+ ci->values[i].value.string);
+ sfree(dd->oids);
+ dd->oids_len = 0;
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int snmp_agent_config_table_size_oid(table_definition_t *td,
+ oconfig_item_t *ci) {
+ if (ci->values_num < 1) {
+ WARNING(PLUGIN_NAME ": `TableSizeOID' is empty");
+ return -EINVAL;
+ }
+
+ if (ci->values[0].type != OCONFIG_TYPE_STRING) {
+ WARNING(PLUGIN_NAME ": `TableSizeOID' needs only string argument");
+ return -EINVAL;
+ }
+
+ td->size_oid.oid_len = MAX_OID_LEN;
+
+ if (NULL == snmp_parse_oid(ci->values[0].value.string, td->size_oid.oid,
+ &td->size_oid.oid_len)) {
+ ERROR(PLUGIN_NAME ": Failed to parse table size OID (%s)",
+ ci->values[0].value.string);
+ td->size_oid.oid_len = 0;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int snmp_agent_config_table_index_oid(table_definition_t *td,
+ oconfig_item_t *ci) {
+
+ if (ci->values_num < 1) {
+ WARNING(PLUGIN_NAME ": `IndexOID' is empty");
+ return -EINVAL;
+ }
+
+ if (ci->values[0].type != OCONFIG_TYPE_STRING) {
+ WARNING(PLUGIN_NAME ": `IndexOID' needs only string argument");
+ return -EINVAL;
+ }
+
+ td->index_oid.oid_len = MAX_OID_LEN;
+
+ if (NULL == snmp_parse_oid(ci->values[0].value.string, td->index_oid.oid,
+ &td->index_oid.oid_len)) {
+ ERROR(PLUGIN_NAME ": Failed to parse table index OID (%s)",
+ ci->values[0].value.string);
+ td->index_oid.oid_len = 0;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int snmp_agent_config_table_data(table_definition_t *td,
+ oconfig_item_t *ci) {
+ data_definition_t *dd;
+ int ret = 0;
+
+ assert(ci != NULL);
+
+ dd = calloc(1, sizeof(*dd));
+ if (dd == NULL) {
+ ERROR(PLUGIN_NAME ": Failed to allocate memory for table data definition");
+ return -ENOMEM;
+ }
+
+ ret = cf_util_get_string(ci, &dd->name);
+ if (ret != 0) {
+ sfree(dd);
+ return -1;
+ }
+
+ dd->scale = 1.0;
+ dd->shift = 0.0;
+
+ dd->table = td;
+
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *option = ci->children + i;
+
+ if (strcasecmp("Instance", option->key) == 0)
+ ret = cf_util_get_boolean(option, &dd->is_instance);
+ else if (strcasecmp("Plugin", option->key) == 0)
+ ret = cf_util_get_string(option, &dd->plugin);
+ else if (strcasecmp("PluginInstance", option->key) == 0)
+ ret = cf_util_get_string(option, &dd->plugin_instance);
+ else if (strcasecmp("Type", option->key) == 0)
+ ret = cf_util_get_string(option, &dd->type);
+ else if (strcasecmp("TypeInstance", option->key) == 0)
+ ret = cf_util_get_string(option, &dd->type_instance);
+ else if (strcasecmp("Shift", option->key) == 0)
+ ret = cf_util_get_double(option, &dd->shift);
+ else if (strcasecmp("Scale", option->key) == 0)
+ ret = cf_util_get_double(option, &dd->scale);
+ else if (strcasecmp("OIDs", option->key) == 0)
+ ret = snmp_agent_config_data_oids(dd, option);
+ else {
+ WARNING(PLUGIN_NAME ": Option `%s' not allowed here", option->key);
+ ret = -1;
+ }
+
+ if (ret != 0) {
+ snmp_agent_free_data(&dd);
+ return -1;
+ }
+ }
+
+ llentry_t *entry = llentry_create(dd->name, dd);
+ if (entry == NULL) {
+ snmp_agent_free_data(&dd);
+ return -ENOMEM;
+ }
+
+ llist_append(td->columns, entry);
+
+ return 0;
+}
+
+static int snmp_agent_config_data(oconfig_item_t *ci) {
+ data_definition_t *dd;
+ int ret = 0;
+
+ assert(ci != NULL);
+
+ dd = calloc(1, sizeof(*dd));
+ if (dd == NULL) {
+ ERROR(PLUGIN_NAME ": Failed to allocate memory for data definition");
+ return -ENOMEM;
+ }
+
+ ret = cf_util_get_string(ci, &dd->name);
+ if (ret != 0) {
+ free(dd);
+ return -1;
+ }
+
+ dd->scale = 1.0;
+ dd->shift = 0.0;
+
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *option = ci->children + i;
+
+ if (strcasecmp("Instance", option->key) == 0)
+ ret = cf_util_get_boolean(option, &dd->is_instance);
+ else if (strcasecmp("Plugin", option->key) == 0)
+ ret = cf_util_get_string(option, &dd->plugin);
+ else if (strcasecmp("PluginInstance", option->key) == 0)
+ ret = cf_util_get_string(option, &dd->plugin_instance);
+ else if (strcasecmp("Type", option->key) == 0)
+ ret = cf_util_get_string(option, &dd->type);
+ else if (strcasecmp("TypeInstance", option->key) == 0)
+ ret = cf_util_get_string(option, &dd->type_instance);
+ else if (strcasecmp("Shift", option->key) == 0)
+ ret = cf_util_get_double(option, &dd->shift);
+ else if (strcasecmp("Scale", option->key) == 0)
+ ret = cf_util_get_double(option, &dd->scale);
+ else if (strcasecmp("OIDs", option->key) == 0)
+ ret = snmp_agent_config_data_oids(dd, option);
+ else {
+ WARNING(PLUGIN_NAME ": Option `%s' not allowed here", option->key);
+ ret = -1;
+ }
+
+ if (ret != 0) {
+ snmp_agent_free_data(&dd);
+ return -1;
+ }
+ }
+
+ llentry_t *entry = llentry_create(dd->name, dd);
+ if (entry == NULL) {
+ snmp_agent_free_data(&dd);
+ return -ENOMEM;
+ }
+
+ llist_append(g_agent->scalars, entry);
+
+ return 0;
+}
+
+static int num_compare(const int *a, const int *b) {
+ assert((a != NULL) && (b != NULL));
+ if (*a < *b)
+ return -1;
+ else if (*a > *b)
+ return 1;
+ else
+ return 0;
+}
+
+static int snmp_agent_config_table(oconfig_item_t *ci) {
+ table_definition_t *td;
+ int ret = 0;
+
+ assert(ci != NULL);
+
+ td = calloc(1, sizeof(*td));
+ if (td == NULL) {
+ ERROR(PLUGIN_NAME ": Failed to allocate memory for table definition");
+ return -ENOMEM;
+ }
+
+ ret = cf_util_get_string(ci, &td->name);
+ if (ret != 0) {
+ sfree(td);
+ return -1;
+ }
+
+ td->columns = llist_create();
+ if (td->columns == NULL) {
+ ERROR(PLUGIN_NAME ": Failed to allocate memory for columns list");
+ snmp_agent_free_table(&td);
+ return -ENOMEM;
+ }
+
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *option = ci->children + i;
+
+ if (strcasecmp("IndexOID", option->key) == 0)
+ ret = snmp_agent_config_table_index_oid(td, option);
+ else if (strcasecmp("SizeOID", option->key) == 0)
+ ret = snmp_agent_config_table_size_oid(td, option);
+ else if (strcasecmp("Data", option->key) == 0)
+ ret = snmp_agent_config_table_data(td, option);
+ else {
+ WARNING(PLUGIN_NAME ": Option `%s' not allowed here", option->key);
+ ret = -1;
+ }
+
+ if (ret != 0) {
+ snmp_agent_free_table(&td);
+ return -ENOMEM;
+ }
+ }
+
+ td->instance_index =
+ c_avl_create((int (*)(const void *, const void *))strcmp);
+ if (td->instance_index == NULL) {
+ snmp_agent_free_table(&td);
+ return -ENOMEM;
+ }
+
+ td->index_instance =
+ c_avl_create((int (*)(const void *, const void *))num_compare);
+ if (td->index_instance == NULL) {
+ snmp_agent_free_table(&td);
+ return -ENOMEM;
+ }
+
+ llentry_t *entry = llentry_create(td->name, td);
+ if (entry == NULL) {
+ snmp_agent_free_table(&td);
+ return -ENOMEM;
+ }
+ llist_append(g_agent->tables, entry);
+
+ return 0;
+}
+
+static int snmp_agent_get_value_from_ds_type(const value_t *val, int type,
+ double scale, double shift,
+ long *value) {
+ switch (type) {
+ case DS_TYPE_COUNTER:
+ *value = (long)((val->counter * scale) + shift);
+ break;
+ case DS_TYPE_ABSOLUTE:
+ *value = (long)((val->absolute * scale) + shift);
+ break;
+ case DS_TYPE_DERIVE:
+ *value = (long)((val->derive * scale) + shift);
+ break;
+ case DS_TYPE_GAUGE:
+ *value = (long)((val->gauge * scale) + shift);
+ break;
+ case TYPE_STRING:
+ break;
+ default:
+ ERROR(PLUGIN_NAME ": Unknown data source type: %i", type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int snmp_agent_set_vardata(void *data, size_t *data_len, u_char asn_type,
+ double scale, double shift, const void *value,
+ size_t len, int type) {
+
+ int ret;
+ netsnmp_vardata var;
+ const value_t *val;
+ long new_value = 0;
+
+ val = value;
+ var.string = (u_char *)data;
+
+ ret = snmp_agent_get_value_from_ds_type(val, type, scale, shift, &new_value);
+ if (ret != 0)
+ return ret;
+
+ switch (asn_type) {
+ case ASN_INTEGER:
+ case ASN_UINTEGER:
+ case ASN_COUNTER:
+ case ASN_TIMETICKS:
+ case ASN_GAUGE:
+ if (*data_len < sizeof(*var.integer))
+ return -EINVAL;
+ *var.integer = new_value;
+ *data_len = sizeof(*var.integer);
+ break;
+ case ASN_COUNTER64:
+ if (*data_len < sizeof(*var.counter64))
+ return -EINVAL;
+ var.counter64->high = (u_long)((int64_t)new_value >> 32);
+ var.counter64->low = (u_long)((int64_t)new_value & 0xFFFFFFFF);
+ *data_len = sizeof(*var.counter64);
+ break;
+ case ASN_OCTET_STR:
+ if (type == DS_TYPE_GAUGE) {
+ char buf[DATA_MAX_NAME_LEN];
+ snprintf(buf, sizeof(buf), "%.2f", val->gauge);
+ if (*data_len < strlen(buf))
+ return -EINVAL;
+ *data_len = strlen(buf);
+ memcpy(var.string, buf, *data_len);
+ } else {
+ ERROR(PLUGIN_NAME ": Failed to convert %d ds type to %d asn type", type,
+ asn_type);
+ return -EINVAL;
+ }
+ break;
+ default:
+ ERROR(PLUGIN_NAME ": Failed to convert %d ds type to %d asn type", type,
+ asn_type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int snmp_agent_register_oid_index(oid_t *oid, int index,
+ Netsnmp_Node_Handler *handler) {
+ oid_t new_oid;
+ memcpy(&new_oid, oid, sizeof(*oid));
+ new_oid.oid[new_oid.oid_len++] = index;
+ return snmp_agent_register_oid(&new_oid, handler);
+}
+
+static int snmp_agent_unregister_oid_index(oid_t *oid, int index) {
+ oid_t new_oid;
+ memcpy(&new_oid, oid, sizeof(*oid));
+ new_oid.oid[new_oid.oid_len++] = index;
+ return unregister_mib(new_oid.oid, new_oid.oid_len);
+}
+
+static int snmp_agent_update_index(table_definition_t *td,
+ const char *instance) {
+
+ if (c_avl_get(td->instance_index, instance, NULL) == 0)
+ return 0;
+
+ int ret;
+ int *index = NULL;
+ char *ins;
+
+ ins = strdup(instance);
+ if (ins == NULL)
+ return -ENOMEM;
+
+ /* need to generate index for the table */
+ if (td->index_oid.oid_len) {
+ index = calloc(1, sizeof(*index));
+ if (index == NULL) {
+ sfree(ins);
+ return -ENOMEM;
+ }
+
+ *index = c_avl_size(td->instance_index) + 1;
+
+ ret = c_avl_insert(td->instance_index, ins, index);
+ if (ret != 0) {
+ sfree(ins);
+ sfree(index);
+ return ret;
+ }
+
+ ret = c_avl_insert(td->index_instance, index, ins);
+ if (ret < 0) {
+ DEBUG(PLUGIN_NAME ": Failed to update index_instance for '%s' table",
+ td->name);
+ c_avl_remove(td->instance_index, ins, NULL, (void **)&index);
+ sfree(ins);
+ sfree(index);
+ return ret;
+ }
+
+ ret = snmp_agent_register_oid_index(&td->index_oid, *index,
+ snmp_agent_table_index_oid_handler);
+ if (ret != 0)
+ return ret;
+ } else {
+ /* instance as a key is required for any table */
+ ret = c_avl_insert(td->instance_index, ins, ins);
+ if (ret != 0) {
+ sfree(ins);
+ return ret;
+ }
+ }
+
+ /* register new oids for all columns */
+ for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
+ data_definition_t *dd = de->value;
+
+ for (size_t i = 0; i < dd->oids_len; i++) {
+ if (td->index_oid.oid_len) {
+ ret = snmp_agent_register_oid_index(&dd->oids[i], *index,
+ snmp_agent_table_oid_handler);
+ } else {
+ ret = snmp_agent_register_oid_string(&dd->oids[i], ins,
+ snmp_agent_table_oid_handler);
+ }
+
+ if (ret != 0)
+ return ret;
+ }
+ }
+
+ DEBUG(PLUGIN_NAME ": Updated index for '%s' table [%d, %s]", td->name,
+ (index != NULL) ? *index : -1, ins);
+
+ notification_t n = {
+ .severity = NOTIF_OKAY, .time = cdtime(), .plugin = PLUGIN_NAME};
+ sstrncpy(n.host, hostname_g, sizeof(n.host));
+ sstrncpy(n.plugin_instance, ins, sizeof(n.plugin_instance));
+ snprintf(n.message, sizeof(n.message),
+ "Data row added to table %s instance %s index %d", td->name, ins,
+ (index != NULL) ? *index : -1);
+ plugin_dispatch_notification(&n);
+
+ return 0;
+}
+
+static int snmp_agent_write(value_list_t const *vl) {
+
+ if (vl == NULL)
+ return -EINVAL;
+
+ for (llentry_t *te = llist_head(g_agent->tables); te != NULL; te = te->next) {
+ table_definition_t *td = te->value;
+
+ for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
+ data_definition_t *dd = de->value;
+
+ if (!dd->is_instance) {
+ if (CHECK_DD_TYPE(dd, vl->plugin, vl->plugin_instance, vl->type,
+ vl->type_instance)) {
+ snmp_agent_update_index(td, vl->plugin_instance);
+ return 0;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int snmp_agent_collect(const data_set_t *ds, const value_list_t *vl,
+ user_data_t __attribute__((unused)) * user_data) {
+
+ pthread_mutex_lock(&g_agent->lock);
+
+ snmp_agent_write(vl);
+
+ pthread_mutex_unlock(&g_agent->lock);
+
+ return 0;
+}
+
+static int snmp_agent_preinit(void) {
+ if (g_agent != NULL) {
+ /* already initialized if config callback was called before init callback */
+ return 0;
+ }
+
+ g_agent = calloc(1, sizeof(*g_agent));
+ if (g_agent == NULL) {
+ ERROR(PLUGIN_NAME ": Failed to allocate memory for snmp agent context");
+ return -ENOMEM;
+ }
+
+ g_agent->tables = llist_create();
+ g_agent->scalars = llist_create();
+
+ if (g_agent->tables == NULL || g_agent->scalars == NULL) {
+ ERROR(PLUGIN_NAME ": llist_create() failed");
+ llist_destroy(g_agent->scalars);
+ llist_destroy(g_agent->tables);
+ return -ENOMEM;
+ }
+
+ int err;
+ /* make us a agentx client. */
+ err = netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE,
+ 1);
+ if (err != 0) {
+ ERROR(PLUGIN_NAME ": Failed to set agent role (%d)", err);
+ llist_destroy(g_agent->scalars);
+ llist_destroy(g_agent->tables);
+ return -1;
+ }
+
+ /*
+ * For SNMP debug purposes uses snmp_set_do_debugging(1);
+ */
+
+ /* initialize the agent library */
+ err = init_agent(PLUGIN_NAME);
+ if (err != 0) {
+ ERROR(PLUGIN_NAME ": Failed to initialize the agent library (%d)", err);
+ llist_destroy(g_agent->scalars);
+ llist_destroy(g_agent->tables);
+ return -1;
+ }
+
+ init_snmp(PLUGIN_NAME);
+
+ g_agent->tp = read_all_mibs();
+
+ return 0;
+}
+
+static int snmp_agent_init(void) {
+ int ret;
+
+ if (g_agent == NULL || ((llist_head(g_agent->scalars) == NULL) &&
+ (llist_head(g_agent->tables) == NULL))) {
+ ERROR(PLUGIN_NAME ": snmp_agent_init: plugin not configured");
+ return -EINVAL;
+ }
+
+ plugin_register_shutdown(PLUGIN_NAME, snmp_agent_shutdown);
+
+ ret = snmp_agent_register_scalar_oids();
+ if (ret != 0)
+ return ret;
+
+ ret = snmp_agent_register_table_oids();
+ if (ret != 0)
+ return ret;
+
+ ret = pthread_mutex_init(&g_agent->lock, NULL);
+ if (ret != 0) {
+ ERROR(PLUGIN_NAME ": Failed to initialize mutex, err %u", ret);
+ return ret;
+ }
+
+ ret = pthread_mutex_init(&g_agent->agentx_lock, NULL);
+ if (ret != 0) {
+ ERROR(PLUGIN_NAME ": Failed to initialize AgentX mutex, err %u", ret);
+ return ret;
+ }
+
+ /* create a second thread to listen for requests from AgentX*/
+ ret = pthread_create(&g_agent->thread, NULL, &snmp_agent_thread_run, NULL);
+ if (ret != 0) {
+ ERROR(PLUGIN_NAME ": Failed to create a separate thread, err %u", ret);
+ return ret;
+ }
+
+ if (llist_head(g_agent->tables) != NULL) {
+ plugin_register_write(PLUGIN_NAME, snmp_agent_collect, NULL);
+ plugin_register_missing(PLUGIN_NAME, snmp_agent_clear_missing, NULL);
+ }
+
+ return 0;
+}
+
+static void *snmp_agent_thread_run(void __attribute__((unused)) * arg) {
+ INFO(PLUGIN_NAME ": Thread is up and running");
+
+ for (;;) {
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
+ pthread_mutex_lock(&g_agent->agentx_lock);
+ agent_check_and_process(0); /* 0 == don't block */
+ pthread_mutex_unlock(&g_agent->agentx_lock);
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ usleep(10);
+ }
+
+ pthread_exit(0);
+}
+
+static int snmp_agent_register_oid(oid_t *oid, Netsnmp_Node_Handler *handler) {
+ netsnmp_handler_registration *reg;
+ char *oid_name = snmp_agent_get_oid_name(oid->oid, oid->oid_len - 1);
+ char oid_str[DATA_MAX_NAME_LEN];
+
+ snmp_agent_oid_to_string(oid_str, sizeof(oid_str), oid);
+
+ if (oid_name == NULL) {
+ WARNING(PLUGIN_NAME
+ ": Skipped registration: OID (%s) is not found in main tree",
+ oid_str);
+ return 0;
+ }
+
+ reg = netsnmp_create_handler_registration(oid_name, handler, oid->oid,
+ oid->oid_len, HANDLER_CAN_RONLY);
+ if (reg == NULL) {
+ ERROR(PLUGIN_NAME ": Failed to create handler registration for OID (%s)",
+ oid_str);
+ return -1;
+ }
+
+ pthread_mutex_lock(&g_agent->agentx_lock);
+
+ if (netsnmp_register_instance(reg) != MIB_REGISTERED_OK) {
+ ERROR(PLUGIN_NAME ": Failed to register handler for OID (%s)", oid_str);
+ pthread_mutex_unlock(&g_agent->agentx_lock);
+ return -1;
+ }
+
+ pthread_mutex_unlock(&g_agent->agentx_lock);
+
+ DEBUG(PLUGIN_NAME ": Registered handler for OID (%s)", oid_str);
+
+ return 0;
+}
+
+static int snmp_agent_free_config(void) {
+
+ if (g_agent == NULL)
+ return -EINVAL;
+
+ for (llentry_t *te = llist_head(g_agent->tables); te != NULL; te = te->next)
+ snmp_agent_free_table((table_definition_t **)&te->value);
+ llist_destroy(g_agent->tables);
+
+ for (llentry_t *de = llist_head(g_agent->scalars); de != NULL; de = de->next)
+ snmp_agent_free_data((data_definition_t **)&de->value);
+ llist_destroy(g_agent->scalars);
+
+ return 0;
+}
+
+static int snmp_agent_shutdown(void) {
+ int ret = 0;
+
+ DEBUG(PLUGIN_NAME ": snmp_agent_shutdown");
+
+ if (g_agent == NULL) {
+ ERROR(PLUGIN_NAME ": snmp_agent_shutdown: plugin not initialized");
+ return -EINVAL;
+ }
+
+ if (pthread_cancel(g_agent->thread) != 0)
+ ERROR(PLUGIN_NAME ": snmp_agent_shutdown: failed to cancel the thread");
+
+ if (pthread_join(g_agent->thread, NULL) != 0)
+ ERROR(PLUGIN_NAME ": snmp_agent_shutdown: failed to join the thread");
+
+ snmp_agent_free_config();
+
+ snmp_shutdown(PLUGIN_NAME);
+
+ pthread_mutex_destroy(&g_agent->lock);
+ pthread_mutex_destroy(&g_agent->agentx_lock);
+
+ sfree(g_agent);
+
+ return ret;
+}
+
+static int snmp_agent_config(oconfig_item_t *ci) {
+
+ int ret = snmp_agent_preinit();
+
+ if (ret != 0) {
+ sfree(g_agent);
+ return -EINVAL;
+ }
+
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *child = ci->children + i;
+ if (strcasecmp("Data", child->key) == 0) {
+ ret = snmp_agent_config_data(child);
+ } else if (strcasecmp("Table", child->key) == 0) {
+ ret = snmp_agent_config_table(child);
+ } else {
+ ERROR(PLUGIN_NAME ": Unknown configuration option `%s'", child->key);
+ ret = (-EINVAL);
+ }
+
+ if (ret != 0) {
+ ERROR(PLUGIN_NAME ": Failed to parse configuration");
+ snmp_agent_free_config();
+ snmp_shutdown(PLUGIN_NAME);
+ sfree(g_agent);
+ return -EINVAL;
+ }
+ }
+
+ ret = snmp_agent_validate_data();
+ if (ret != 0) {
+ ERROR(PLUGIN_NAME ": Invalid configuration provided");
+ snmp_agent_free_config();
+ snmp_shutdown(PLUGIN_NAME);
+ sfree(g_agent);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void module_register(void) {
+ plugin_register_init(PLUGIN_NAME, snmp_agent_init);
+ plugin_register_complex_config(PLUGIN_NAME, snmp_agent_config);
+}
key[0] = 's';
break;
default:
- return (NULL);
+ return NULL;
}
key[1] = ':';
status = c_avl_get(metrics_tree, key, (void *)&metric);
if (status == 0)
- return (metric);
+ return metric;
key_copy = strdup(key);
if (key_copy == NULL) {
ERROR("statsd plugin: strdup failed.");
- return (NULL);
+ return NULL;
}
metric = calloc(1, sizeof(*metric));
if (metric == NULL) {
ERROR("statsd plugin: calloc failed.");
sfree(key_copy);
- return (NULL);
+ return NULL;
}
metric->type = type;
ERROR("statsd plugin: c_avl_insert failed.");
sfree(key_copy);
sfree(metric);
- return (NULL);
+ return NULL;
}
- return (metric);
+ return metric;
} /* }}} statsd_metric_lookup_unsafe */
static int statsd_metric_set(char const *name, double value, /* {{{ */
metric = statsd_metric_lookup_unsafe(name, type);
if (metric == NULL) {
pthread_mutex_unlock(&metrics_lock);
- return (-1);
+ return -1;
}
metric->value = value;
pthread_mutex_unlock(&metrics_lock);
- return (0);
+ return 0;
} /* }}} int statsd_metric_set */
static int statsd_metric_add(char const *name, double delta, /* {{{ */
metric = statsd_metric_lookup_unsafe(name, type);
if (metric == NULL) {
pthread_mutex_unlock(&metrics_lock);
- return (-1);
+ return -1;
}
metric->value += delta;
pthread_mutex_unlock(&metrics_lock);
- return (0);
+ return 0;
} /* }}} int statsd_metric_add */
static void statsd_metric_free(statsd_metric_t *metric) /* {{{ */
ret_value->gauge = (gauge_t)strtod(str, &endptr);
if ((str == endptr) || ((endptr != NULL) && (*endptr != 0)))
- return (-1);
+ return -1;
- return (0);
+ return 0;
} /* }}} int statsd_parse_value */
static int statsd_handle_counter(char const *name, /* {{{ */
int status;
if ((extra != NULL) && (extra[0] != '@'))
- return (-1);
+ return -1;
scale.gauge = 1.0;
if (extra != NULL) {
status = statsd_parse_value(extra + 1, &scale);
if (status != 0)
- return (status);
+ return status;
if (!isfinite(scale.gauge) || (scale.gauge <= 0.0) || (scale.gauge > 1.0))
- return (-1);
+ return -1;
}
value.gauge = 1.0;
status = statsd_parse_value(value_str, &value);
if (status != 0)
- return (status);
+ return status;
/* Changes to the counter are added to (statsd_metric_t*)->value. ->counter is
* only updated in statsd_metric_submit_unsafe(). */
- return (statsd_metric_add(name, (double)(value.gauge / scale.gauge),
- STATSD_COUNTER));
+ return statsd_metric_add(name, (double)(value.gauge / scale.gauge),
+ STATSD_COUNTER);
} /* }}} int statsd_handle_counter */
static int statsd_handle_gauge(char const *name, /* {{{ */
value.gauge = 0;
status = statsd_parse_value(value_str, &value);
if (status != 0)
- return (status);
+ return status;
if ((value_str[0] == '+') || (value_str[0] == '-'))
- return (statsd_metric_add(name, (double)value.gauge, STATSD_GAUGE));
+ return statsd_metric_add(name, (double)value.gauge, STATSD_GAUGE);
else
- return (statsd_metric_set(name, (double)value.gauge, STATSD_GAUGE));
+ return statsd_metric_set(name, (double)value.gauge, STATSD_GAUGE);
} /* }}} int statsd_handle_gauge */
static int statsd_handle_timer(char const *name, /* {{{ */
int status;
if ((extra != NULL) && (extra[0] != '@'))
- return (-1);
+ return -1;
scale.gauge = 1.0;
if (extra != NULL) {
status = statsd_parse_value(extra + 1, &scale);
if (status != 0)
- return (status);
+ return status;
if (!isfinite(scale.gauge) || (scale.gauge <= 0.0) || (scale.gauge > 1.0))
- return (-1);
+ return -1;
}
value_ms.derive = 0;
status = statsd_parse_value(value_str, &value_ms);
if (status != 0)
- return (status);
+ return status;
value = MS_TO_CDTIME_T(value_ms.gauge / scale.gauge);
metric = statsd_metric_lookup_unsafe(name, STATSD_TIMER);
if (metric == NULL) {
pthread_mutex_unlock(&metrics_lock);
- return (-1);
+ return -1;
}
if (metric->latency == NULL)
metric->latency = latency_counter_create();
if (metric->latency == NULL) {
pthread_mutex_unlock(&metrics_lock);
- return (-1);
+ return -1;
}
latency_counter_add(metric->latency, value);
metric->updates_num++;
pthread_mutex_unlock(&metrics_lock);
- return (0);
+ return 0;
} /* }}} int statsd_handle_timer */
static int statsd_handle_set(char const *name, /* {{{ */
metric = statsd_metric_lookup_unsafe(name, STATSD_SET);
if (metric == NULL) {
pthread_mutex_unlock(&metrics_lock);
- return (-1);
+ return -1;
}
/* Make sure metric->set exists. */
if (metric->set == NULL) {
pthread_mutex_unlock(&metrics_lock);
ERROR("statsd plugin: c_avl_create failed.");
- return (-1);
+ return -1;
}
set_key = strdup(set_key_orig);
if (set_key == NULL) {
pthread_mutex_unlock(&metrics_lock);
ERROR("statsd plugin: strdup failed.");
- return (-1);
+ return -1;
}
status = c_avl_insert(metric->set, set_key, /* value = */ NULL);
ERROR("statsd plugin: c_avl_insert (\"%s\") failed with status %i.",
set_key, status);
sfree(set_key);
- return (-1);
+ return -1;
} else if (status > 0) /* key already exists */
{
sfree(set_key);
metric->updates_num++;
pthread_mutex_unlock(&metrics_lock);
- return (0);
+ return 0;
} /* }}} int statsd_handle_set */
static int statsd_parse_line(char *buffer) /* {{{ */
type = strchr(name, '|');
if (type == NULL)
- return (-1);
+ return -1;
*type = 0;
type++;
value = strrchr(name, ':');
if (value == NULL)
- return (-1);
+ return -1;
*value = 0;
value++;
}
if (strcmp("c", type) == 0)
- return (statsd_handle_counter(name, value, extra));
+ return statsd_handle_counter(name, value, extra);
else if (strcmp("ms", type) == 0)
- return (statsd_handle_timer(name, value, extra));
+ return statsd_handle_timer(name, value, extra);
/* extra is only valid for counters and timers */
if (extra != NULL)
- return (-1);
+ return -1;
if (strcmp("g", type) == 0)
- return (statsd_handle_gauge(name, value));
+ return statsd_handle_gauge(name, value);
else if (strcmp("s", type) == 0)
- return (statsd_handle_set(name, value));
+ return statsd_handle_set(name, value);
else
- return (-1);
+ return -1;
} /* }}} void statsd_parse_line */
static void statsd_parse_buffer(char *buffer) /* {{{ */
if (status != 0) {
ERROR("statsd plugin: getaddrinfo (\"%s\", \"%s\") failed: %s", node,
service, gai_strerror(status));
- return (status);
+ return status;
}
for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
if (fds_num == 0) {
ERROR("statsd plugin: Unable to create listening socket for [%s]:%s.",
(node != NULL) ? node : "::", service);
- return (ENOENT);
+ return ENOENT;
}
*ret_fds = fds;
*ret_fds_num = fds_num;
- return (0);
+ return 0;
} /* }}} int statsd_network_init */
static void *statsd_network_thread(void *args) /* {{{ */
close(fds[i].fd);
sfree(fds);
- return ((void *)0);
+ return (void *)0;
} /* }}} void *statsd_network_thread */
static int statsd_config_timer_percentile(oconfig_item_t *ci) /* {{{ */
status = cf_util_get_double(ci, &percent);
if (status != 0)
- return (status);
+ return status;
if ((percent <= 0.0) || (percent >= 100)) {
ERROR("statsd plugin: The value for \"%s\" must be between 0 and 100, "
"exclusively.",
ci->key);
- return (ERANGE);
+ return ERANGE;
}
- tmp = realloc(conf_timer_percentile, sizeof(*conf_timer_percentile) *
- (conf_timer_percentile_num + 1));
+ tmp =
+ realloc(conf_timer_percentile,
+ sizeof(*conf_timer_percentile) * (conf_timer_percentile_num + 1));
if (tmp == NULL) {
ERROR("statsd plugin: realloc failed.");
- return (ENOMEM);
+ return ENOMEM;
}
conf_timer_percentile = tmp;
conf_timer_percentile[conf_timer_percentile_num] = percent;
conf_timer_percentile_num++;
- return (0);
+ return 0;
} /* }}} int statsd_config_timer_percentile */
static int statsd_config(oconfig_item_t *ci) /* {{{ */
child->key);
}
- return (0);
+ return 0;
} /* }}} int statsd_config */
static int statsd_init(void) /* {{{ */
pthread_mutex_unlock(&metrics_lock);
ERROR("statsd plugin: pthread_create failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (status);
+ return status;
}
}
network_thread_running = 1;
pthread_mutex_unlock(&metrics_lock);
- return (0);
+ return 0;
} /* }}} int statsd_init */
/* Must hold metrics_lock when calling this function. */
void *value;
if ((metric == NULL) || (metric->type != STATSD_SET))
- return (EINVAL);
+ return EINVAL;
if (metric->set == NULL)
- return (0);
+ return 0;
while (c_avl_pick(metric->set, &key, &value) == 0) {
sfree(key);
sfree(value);
}
- return (0);
+ return 0;
} /* }}} int statsd_metric_clear_set_unsafe */
/* Must hold metrics_lock when calling this function. */
/* Make sure all timer metrics share the *same* timestamp. */
vl.time = cdtime();
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-average", name);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-average", name);
vl.values[0].gauge =
have_events
? CDTIME_T_TO_DOUBLE(latency_counter_get_average(metric->latency))
plugin_dispatch_values(&vl);
if (conf_timer_lower) {
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-lower", name);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-lower", name);
vl.values[0].gauge =
have_events
? CDTIME_T_TO_DOUBLE(latency_counter_get_min(metric->latency))
}
if (conf_timer_upper) {
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-upper", name);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-upper", name);
vl.values[0].gauge =
have_events
? CDTIME_T_TO_DOUBLE(latency_counter_get_max(metric->latency))
}
if (conf_timer_sum) {
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-sum", name);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-sum", name);
vl.values[0].gauge =
have_events
? CDTIME_T_TO_DOUBLE(latency_counter_get_sum(metric->latency))
}
for (size_t i = 0; i < conf_timer_percentile_num; i++) {
- ssnprintf(vl.type_instance, sizeof(vl.type_instance),
- "%s-percentile-%.0f", name, conf_timer_percentile[i]);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-percentile-%.0f",
+ name, conf_timer_percentile[i]);
vl.values[0].gauge =
have_events ? CDTIME_T_TO_DOUBLE(latency_counter_get_percentile(
metric->latency, conf_timer_percentile[i]))
* vl.type's above are implicitly set to "latency". */
if (conf_timer_count) {
sstrncpy(vl.type, "gauge", sizeof(vl.type));
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-count", name);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-count", name);
vl.values[0].gauge = latency_counter_get_num(metric->latency);
plugin_dispatch_values(&vl);
}
latency_counter_reset(metric->latency);
- return (0);
+ return 0;
} else if (metric->type == STATSD_SET) {
if (metric->set == NULL)
vl.values[0].gauge = 0.0;
vl.values[0].derive = metric->counter;
}
- return (plugin_dispatch_values(&vl));
+ return plugin_dispatch_values(&vl);
} /* }}} int statsd_metric_submit_unsafe */
static int statsd_read(void) /* {{{ */
if (metrics_tree == NULL) {
pthread_mutex_unlock(&metrics_lock);
- return (0);
+ return 0;
}
iter = c_avl_get_iterator(metrics_tree);
strarray_free(to_be_deleted, to_be_deleted_num);
- return (0);
+ return 0;
} /* }}} int statsd_read */
static int statsd_shutdown(void) /* {{{ */
pthread_mutex_unlock(&metrics_lock);
- return (0);
+ return 0;
} /* }}} int statsd_shutdown */
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 : */
static _Bool values_absolute = 1;
static _Bool values_percentage = 0;
+static _Bool report_io = 1;
static int swap_config(oconfig_item_t *ci) /* {{{ */
{
cf_util_get_boolean(child, &values_absolute);
else if (strcasecmp("ValuesPercentage", child->key) == 0)
cf_util_get_boolean(child, &values_percentage);
+ else if (strcasecmp("ReportIO", child->key) == 0)
+ cf_util_get_boolean(child, &report_io);
else
WARNING("swap plugin: Unknown config option: \"%s\"", child->key);
}
- return (0);
+ return 0;
} /* }}} int swap_config */
static int swap_init(void) /* {{{ */
if (kvm_obj == NULL) {
ERROR("swap plugin: kvm_openfiles failed, %s", errbuf);
- return (-1);
+ return -1;
}
/* #endif HAVE_LIBKVM_GETSWAPINFO */
pagesize = getpagesize();
#endif /* HAVE_PERFSTAT */
- return (0);
+ return 0;
} /* }}} int swap_init */
static void swap_submit_usage(char const *plugin_instance, /* {{{ */
char errbuf[1024];
WARNING("swap plugin: fopen (/proc/swaps) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
fclose(fh);
- return (0);
+ return 0;
} /* }}} int swap_read_separate */
static int swap_read_combined(void) /* {{{ */
char errbuf[1024];
WARNING("swap plugin: fopen (/proc/meminfo) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
fclose(fh);
if (isnan(swap_total) || isnan(swap_free))
- return (ENOENT);
+ return ENOENT;
/* Some systems, OpenVZ for example, don't provide SwapCached. */
if (isnan(swap_cached))
assert(!isnan(swap_used));
if (swap_used < 0.0)
- return (EINVAL);
+ return EINVAL;
swap_submit_usage(NULL, swap_used * 1024.0, swap_free * 1024.0,
isnan(swap_cached) ? NULL : "cached",
isnan(swap_cached) ? NAN : swap_cached * 1024.0);
- return (0);
+ return 0;
} /* }}} int swap_read_combined */
static int swap_read_io(void) /* {{{ */
if (fh == NULL) {
char errbuf[1024];
WARNING("swap: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
} else
old_kernel = 1;
}
fclose(fh);
if (have_data != 0x03)
- return (ENOENT);
+ return ENOENT;
if (report_bytes) {
swap_in = swap_in * pagesize;
swap_submit_derive("in", swap_in);
swap_submit_derive("out", swap_out);
- return (0);
+ return 0;
} /* }}} int swap_read_io */
static int swap_read(void) /* {{{ */
else
swap_read_combined();
- swap_read_io();
+ if (report_io)
+ swap_read_io();
- return (0);
+ return 0;
} /* }}} int swap_read */
- /* #endif KERNEL_LINUX */
+/* #endif KERNEL_LINUX */
/*
* Under Solaris, two mechanisms can be used to read swap statistics, swapctl
char errbuf[1024];
ERROR("swap plugin: swapctl failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
/*
swap_avail = (gauge_t)((ai.ani_max - ai.ani_resv) * pagesize);
swap_submit_usage(NULL, swap_alloc, swap_avail, "reserved", swap_resv);
- return (0);
+ return 0;
} /* }}} int swap_read_kstat */
/* #endif 0 && HAVE_LIBKSTAT */
swap_num = swapctl(SC_GETNSWP, NULL);
if (swap_num < 0) {
ERROR("swap plugin: swapctl (SC_GETNSWP) failed with status %i.", swap_num);
- return (-1);
+ return -1;
} else if (swap_num == 0)
- return (0);
+ return 0;
/* Allocate and initialize the swaptbl_t structure */
s = malloc(swap_num * sizeof(swapent_t) + sizeof(struct swaptable));
if (s == NULL) {
ERROR("swap plugin: malloc failed.");
- return (-1);
+ return -1;
}
/* Memory to store the path names. We only use these paths when the
if (s_paths == NULL) {
ERROR("swap plugin: calloc failed.");
sfree(s);
- return (-1);
+ return -1;
}
for (int i = 0; i < swap_num; i++)
s->swt_ent[i].ste_path = s_paths + (i * PATH_MAX);
sstrerror(errno, errbuf, sizeof(errbuf)));
sfree(s_paths);
sfree(s);
- return (-1);
+ return -1;
} else if (swap_num < status) {
/* more elements returned than requested */
ERROR("swap plugin: I allocated memory for %i structure%s, "
swap_num, (swap_num == 1) ? "" : "s", status);
sfree(s_paths);
sfree(s);
- return (-1);
+ return -1;
} else if (swap_num > status)
/* less elements returned than requested */
swap_num = status;
total, avail);
sfree(s_paths);
sfree(s);
- return (-1);
+ return -1;
}
/* If the "separate" option was specified (report_by_device == 1), all
sfree(s_paths);
sfree(s);
- return (0);
+ return 0;
} /* }}} int swap_read */
/* #endif HAVE_SWAPCTL && HAVE_SWAPCTL_TWO_ARGS */
swap_num = swapctl(SWAP_NSWAP, NULL, 0);
if (swap_num < 0) {
ERROR("swap plugin: swapctl (SWAP_NSWAP) failed with status %i.", swap_num);
- return (-1);
+ return -1;
} else if (swap_num == 0)
- return (0);
+ return 0;
swap_entries = calloc(swap_num, sizeof(*swap_entries));
if (swap_entries == NULL) {
ERROR("swap plugin: calloc failed.");
- return (-1);
+ return -1;
}
status = swapctl(SWAP_STATS, swap_entries, swap_num);
if (status != swap_num) {
ERROR("swap plugin: swapctl (SWAP_STATS) failed with status %i.", status);
sfree(swap_entries);
- return (-1);
+ return -1;
}
#if defined(DEV_BSIZE) && (DEV_BSIZE > 0)
"swap plugin: Total swap space (%g) is less than used swap space (%g).",
total, used);
sfree(swap_entries);
- return (-1);
+ return -1;
}
swap_submit_usage(NULL, used, total - used, NULL, NAN);
sfree(swap_entries);
- return (0);
+ return 0;
} /* }}} int swap_read */
/* #endif HAVE_SWAPCTL && HAVE_SWAPCTL_THREE_ARGS */
sw_usage_len = sizeof(struct xsw_usage);
if (sysctl(mib, mib_len, &sw_usage, &sw_usage_len, NULL, 0) != 0)
- return (-1);
+ return -1;
/* The returned values are bytes. */
swap_submit_usage(NULL, (gauge_t)sw_usage.xsu_used,
(gauge_t)sw_usage.xsu_avail, NULL, NAN);
- return (0);
+ return 0;
} /* }}} int swap_read */
/* #endif VM_SWAPUSAGE */
gauge_t total;
if (kvm_obj == NULL)
- return (-1);
+ return -1;
/* only one structure => only get the grand total, no details */
status = kvm_getswapinfo(kvm_obj, &data_s, 1, 0);
if (status == -1)
- return (-1);
+ return -1;
total = (gauge_t)data_s.ksw_total;
used = (gauge_t)data_s.ksw_used;
swap_submit_usage(NULL, used, total - used, NULL, NAN);
- return (0);
+ return 0;
} /* }}} int swap_read */
/* #endif HAVE_LIBKVM_GETSWAPINFO */
swap = sg_get_swap_stats();
if (swap == NULL)
- return (-1);
+ return -1;
swap_submit_usage(NULL, (gauge_t)swap->used, (gauge_t)swap->free, NULL, NAN);
- return (0);
+ return 0;
} /* }}} int swap_read */
/* #endif HAVE_LIBSTATGRAB */
char errbuf[1024];
WARNING("swap plugin: perfstat_memory_total failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
total = (gauge_t)(pmemory.pgsp_total * pagesize);
reserved = (gauge_t)(pmemory.pgsp_rsvd * pagesize);
swap_submit_usage(NULL, total - free, free, "reserved", reserved);
- swap_submit_derive("in", (derive_t)pmemory.pgspins * pagesize);
- swap_submit_derive("out", (derive_t)pmemory.pgspouts * pagesize);
- return (0);
+ if (report_io) {
+ swap_submit_derive("in", (derive_t)pmemory.pgspins * pagesize);
+ swap_submit_derive("out", (derive_t)pmemory.pgspouts * pagesize);
+ }
+
+ return 0;
} /* }}} int swap_read */
#endif /* HAVE_PERFSTAT */
plugin_register_init("swap", swap_init);
plugin_register_read("swap", swap_read);
} /* void module_register */
-
-/* vim: set fdm=marker : */
--- /dev/null
+/**
+ * collectd - src/synproxy.c
+ * Copyright (C) 2017 Marek Becka
+ *
+ * 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:
+ * Marek Becka <https://github.com/marekbecka>
+ **/
+
+#include "collectd.h"
+
+#include "common.h"
+#include "plugin.h"
+
+#if !KERNEL_LINUX
+#error "No applicable input method."
+#endif
+
+#define SYNPROXY_FIELDS 6
+
+static const char *synproxy_stat_path = "/proc/net/stat/synproxy";
+
+static const char *column_names[SYNPROXY_FIELDS] = {
+ "entries", "syn_received", "invalid",
+ "valid", "retransmission", "reopened"};
+static const char *column_types[SYNPROXY_FIELDS] = {
+ "current_connections", "connections", "cookies", "cookies", "cookies",
+ "connections"};
+
+static void synproxy_submit(value_t *results) {
+ value_list_t vl = VALUE_LIST_INIT;
+
+ /* 1st column (entries) is hardcoded to 0 in kernel code */
+ for (size_t n = 1; n < SYNPROXY_FIELDS; n++) {
+ vl.values = &results[n];
+ vl.values_len = 1;
+
+ sstrncpy(vl.plugin, "synproxy", sizeof(vl.plugin));
+ sstrncpy(vl.type, column_types[n], sizeof(vl.type));
+ sstrncpy(vl.type_instance, column_names[n], sizeof(vl.type_instance));
+
+ plugin_dispatch_values(&vl);
+ }
+}
+
+static int synproxy_read(void) {
+ char buf[1024];
+ value_t results[SYNPROXY_FIELDS];
+ int is_header = 1, status = 0;
+
+ FILE *fh = fopen(synproxy_stat_path, "r");
+ if (fh == NULL) {
+ ERROR("synproxy plugin: unable to open %s", synproxy_stat_path);
+ return -1;
+ }
+
+ memset(results, 0, sizeof(results));
+
+ while (fgets(buf, sizeof(buf), fh) != NULL) {
+ char *fields[SYNPROXY_FIELDS], *endprt;
+
+ if (is_header) {
+ is_header = 0;
+ continue;
+ }
+
+ int numfields = strsplit(buf, fields, STATIC_ARRAY_SIZE(fields));
+ if (numfields != SYNPROXY_FIELDS) {
+ ERROR("synproxy plugin: unexpected number of columns in %s",
+ synproxy_stat_path);
+ status = -1;
+ break;
+ }
+
+ /* 1st column (entries) is hardcoded to 0 in kernel code */
+ for (size_t n = 1; n < SYNPROXY_FIELDS; n++) {
+ char *endptr = NULL;
+ errno = 0;
+
+ results[n].derive += strtoull(fields[n], &endprt, 16);
+ if ((endptr == fields[n]) || errno != 0) {
+ ERROR("synproxy plugin: unable to parse value: %s", fields[n]);
+ fclose(fh);
+ return -1;
+ }
+ }
+ }
+
+ fclose(fh);
+
+ if (status == 0) {
+ synproxy_submit(results);
+ }
+
+ return status;
+}
+
+void module_register(void) {
+ plugin_register_read("synproxy", synproxy_read);
+} /* void module_register */
if (log_level < 0) {
log_level = LOG_INFO;
ERROR("syslog: invalid loglevel [%s] defaulting to 'info'", value);
- return (1);
+ return 1;
}
} else if (strcasecmp(key, "NotifyLevel") == 0) {
notif_severity = parse_notif_severity(value);
if (notif_severity < 0)
- return (1);
+ return 1;
}
- return (0);
+ return 0;
} /* int sl_config */
static void sl_log(int severity, const char *msg,
static int sl_shutdown(void) {
closelog();
- return (0);
+ return 0;
}
static int sl_notification(const notification_t *n,
int status;
if (n->severity > notif_severity)
- return (0);
+ return 0;
switch (n->severity) {
case NOTIF_FAILURE:
#define BUFFER_ADD(...) \
do { \
- status = ssnprintf(&buf[offset], sizeof(buf) - offset, __VA_ARGS__); \
+ status = snprintf(&buf[offset], sizeof(buf) - offset, __VA_ARGS__); \
if (status < 1) \
- return (-1); \
+ return -1; \
else if (((size_t)status) >= (sizeof(buf) - offset)) \
- return (-ENOMEM); \
+ return -ENOMEM; \
else \
offset += ((size_t)status); \
} while (0)
sl_log(log_severity, buf, NULL);
- return (0);
+ return 0;
} /* int sl_notification */
void module_register(void) {
typedef struct {
char *file;
char *sep;
+ char *plugin_name;
char *instance;
tbl_result_t *results;
static void tbl_setup(tbl_t *tbl, char *file) {
tbl->file = sstrdup(file);
tbl->sep = NULL;
+ tbl->plugin_name = NULL;
tbl->instance = NULL;
tbl->results = NULL;
sfree(tbl->file);
sfree(tbl->sep);
+ sfree(tbl->plugin_name);
sfree(tbl->instance);
/* (tbl->results == NULL) -> (tbl->results_num == 0) */
if (0 == strcasecmp(c->key, "Separator"))
tbl_config_set_s(c->key, &tbl->sep, c);
+ else if (0 == strcasecmp(c->key, "Plugin"))
+ tbl_config_set_s(c->key, &tbl->plugin_name, c);
else if (0 == strcasecmp(c->key, "Instance"))
tbl_config_set_s(c->key, &tbl->instance, c);
else if (0 == strcasecmp(c->key, "Result"))
vl.values = values;
vl.values_len = STATIC_ARRAY_SIZE(values);
- sstrncpy(vl.plugin, "table", sizeof(vl.plugin));
+ sstrncpy(vl.plugin, (tbl->plugin_name != NULL) ? tbl->plugin_name : "table",
+ sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, tbl->instance, sizeof(vl.plugin_instance));
sstrncpy(vl.type, res->type, sizeof(vl.type));
plugin_register_complex_config("table", tbl_config);
plugin_register_init("table", tbl_init);
} /* module_register */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
/*
* <Plugin tail>
* <File "/var/log/exim4/mainlog">
- * Instance "exim"
+ * Plugin "mail"
+ * Instance "exim"
* Interval 60
* <Match>
* Regex "S=([1-9][0-9]*)"
oconfig_item_t *ci) {
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("tail plugin: `DSType' needs exactly one string argument.");
- return (-1);
+ return -1;
}
char const *ds_type = ci->values[0].value.string;
int status = latency_config(&cm->latency, ci, "tail");
if (status != 0)
- return (status);
+ return status;
} else if (strncasecmp("Counter", ds_type, strlen("Counter")) == 0) {
cm->flags = UTILS_MATCH_DS_TYPE_COUNTER;
if (strcasecmp("CounterSet", ds_type) == 0)
if (cm->flags == 0) {
WARNING("tail plugin: `%s' is not a valid argument to `DSType'.",
ci->values[0].value.string);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int ctail_config_add_match_dstype */
static int ctail_config_add_match(cu_tail_match_t *tm,
+ const char *plugin_name,
const char *plugin_instance,
oconfig_item_t *ci, cdtime_t interval) {
ctail_config_match_t cm = {0};
if (status == 0) {
// TODO(octo): there's nothing "simple" about the latency stuff …
status = tail_match_add_match_simple(
- tm, cm.regex, cm.excluderegex, cm.flags, "tail", plugin_instance,
+ tm, cm.regex, cm.excluderegex, cm.flags,
+ (plugin_name != NULL) ? plugin_name : "tail", plugin_instance,
cm.type, cm.type_instance, cm.latency, interval);
if (status != 0)
sfree(cm.type_instance);
latency_config_free(cm.latency);
- return (status);
+ return status;
} /* int ctail_config_add_match */
static int ctail_config_add_file(oconfig_item_t *ci) {
cu_tail_match_t *tm;
cdtime_t interval = 0;
+ char *plugin_name = NULL;
char *plugin_instance = NULL;
int num_matches = 0;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("tail plugin: `File' needs exactly one string argument.");
- return (-1);
+ return -1;
}
tm = tail_match_create(ci->values[0].value.string);
if (tm == NULL) {
ERROR("tail plugin: tail_match_create (%s) failed.",
ci->values[0].value.string);
- return (-1);
+ return -1;
}
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *option = ci->children + i;
int status = 0;
- if (strcasecmp("Instance", option->key) == 0)
+ if (strcasecmp("Plugin", option->key) == 0)
+ status = cf_util_get_string (option, &plugin_name);
+ else if (strcasecmp("Instance", option->key) == 0)
status = cf_util_get_string(option, &plugin_instance);
else if (strcasecmp("Interval", option->key) == 0)
cf_util_get_cdtime(option, &interval);
else if (strcasecmp("Match", option->key) == 0) {
- status = ctail_config_add_match(tm, plugin_instance, option, interval);
+ status = ctail_config_add_match(tm, plugin_name, plugin_instance, option,
+ interval);
if (status == 0)
num_matches++;
/* Be mild with failed matches.. */
break;
} /* for (i = 0; i < ci->children_num; i++) */
+ sfree(plugin_name);
sfree(plugin_instance);
if (num_matches == 0) {
ERROR("tail plugin: No (valid) matches found for file `%s'.",
ci->values[0].value.string);
tail_match_destroy(tm);
- return (-1);
+ return -1;
} else {
cu_tail_match_t **temp;
if (temp == NULL) {
ERROR("tail plugin: realloc failed.");
tail_match_destroy(tm);
- return (-1);
+ return -1;
}
tail_match_list = temp;
tail_match_list_num++;
}
- return (0);
+ return 0;
} /* int ctail_config_add_file */
static int ctail_config(oconfig_item_t *ci) {
}
} /* for (i = 0; i < ci->children_num; i++) */
- return (0);
+ return 0;
} /* int ctail_config */
static int ctail_read(user_data_t *ud) {
status = tail_match_read((cu_tail_match_t *)ud->data);
if (status != 0) {
ERROR("tail plugin: tail_match_read failed.");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int ctail_read */
static int ctail_init(void) {
if (tail_match_list_num == 0) {
WARNING("tail plugin: File list is empty. Returning an error.");
- return (-1);
+ return -1;
}
for (size_t i = 0; i < tail_match_list_num; i++) {
- ssnprintf(str, sizeof(str), "tail-%zu", i);
+ snprintf(str, sizeof(str), "tail-%zu", i);
plugin_register_complex_read(NULL, str, ctail_read,
tail_match_list_intervals[i],
});
}
- return (0);
+ return 0;
} /* int ctail_init */
static int ctail_shutdown(void) {
sfree(tail_match_list);
tail_match_list_num = 0;
- return (0);
+ return 0;
} /* int ctail_shutdown */
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 : */
typedef struct metric_definition_s metric_definition_t;
struct instance_definition_s {
+ char *plugin_name;
char *instance;
char *path;
cu_tail_t *tail;
vl.values_len = 1;
vl.values = &v;
- sstrncpy(vl.plugin, "tail_csv", sizeof(vl.plugin));
+ sstrncpy(vl.plugin, (id->plugin_name != NULL) ? id->plugin_name : "tail_csv",
+ sizeof(vl.plugin));
if (id->instance != NULL)
sstrncpy(vl.plugin_instance, id->instance, sizeof(vl.plugin_instance));
sstrncpy(vl.type, md->type, sizeof(vl.type));
vl.time = t;
vl.interval = id->interval;
- return (plugin_dispatch_values(&vl));
+ return plugin_dispatch_values(&vl);
}
static cdtime_t parse_time(char const *tbuf) {
errno = 0;
t = strtod(tbuf, &endptr);
if ((errno != 0) || (endptr == NULL) || (endptr[0] != 0))
- return (cdtime());
+ return cdtime();
- return (DOUBLE_TO_CDTIME_T(t));
+ return DOUBLE_TO_CDTIME_T(t);
}
static int tcsv_read_metric(instance_definition_t *id, metric_definition_t *md,
int status;
if (md->data_source_type == -1)
- return (EINVAL);
+ return EINVAL;
assert(md->value_from >= 0);
if (((size_t)md->value_from) >= fields_num)
- return (EINVAL);
+ return EINVAL;
status = parse_value(fields[md->value_from], &v, md->data_source_type);
if (status != 0)
- return (status);
+ return status;
if (id->time_from >= 0) {
if (((size_t)id->time_from) >= fields_num)
- return (EINVAL);
+ return EINVAL;
t = parse_time(fields[id->time_from]);
}
- return (tcsv_submit(id, md, v, t));
+ return tcsv_submit(id, md, v, t);
}
static _Bool tcsv_check_index(ssize_t index, size_t fields_num,
ERROR("tail_csv plugin: Metric \"%s\": Request for index %zd when "
"only %zu fields are available.",
name, index, fields_num);
- return (0);
+ return 0;
}
static int tcsv_read_buffer(instance_definition_t *id, char *buffer,
/* Ignore empty lines. */
if ((buffer_size == 0) || (buffer[0] == '#'))
- return (0);
+ return 0;
/* Count the number of fields. */
metrics_num = 1;
ERROR("tail_csv plugin: last line of `%s' does not contain "
"enough values.",
id->path);
- return (-1);
+ return -1;
}
/* Create a list of all values */
metrics = calloc(metrics_num, sizeof(*metrics));
if (metrics == NULL) {
ERROR("tail_csv plugin: calloc failed.");
- return (ENOMEM);
+ return ENOMEM;
}
ptr = buffer;
/* Free up resources */
sfree(metrics);
- return (0);
+ return 0;
}
static int tcsv_read(user_data_t *ud) {
id->tail = cu_tail_create(id->path);
if (id->tail == NULL) {
ERROR("tail_csv plugin: cu_tail_create (\"%s\") failed.", id->path);
- return (-1);
+ return -1;
}
}
ERROR("tail_csv plugin: File \"%s\": cu_tail_readline failed "
"with status %i.",
id->path, status);
- return (-1);
+ return -1;
}
buffer_len = strlen(buffer);
tcsv_read_buffer(id, buffer, buffer_len);
}
- return (0);
+ return 0;
}
static void tcsv_metric_definition_destroy(void *arg) {
WARNING("tail_csv plugin: The \"%s\" config option needs exactly one "
"integer argument.",
ci->key);
- return (-1);
+ return -1;
}
if (ci->values[0].value.number < 0) {
WARNING("tail_csv plugin: The \"%s\" config option must be positive "
"(or zero).",
ci->key);
- return (-1);
+ return -1;
}
*ret_index = (ssize_t)ci->values[0].value.number;
- return (0);
+ return 0;
}
/* Parse metric */
md = calloc(1, sizeof(*md));
if (md == NULL)
- return (-1);
+ return -1;
md->name = NULL;
md->type = NULL;
md->instance = NULL;
status = cf_util_get_string(ci, &md->name);
if (status != 0) {
sfree(md);
- return (-1);
+ return -1;
}
for (int i = 0; i < ci->children_num; ++i) {
if (status != 0) {
tcsv_metric_definition_destroy(md);
- return (-1);
+ return -1;
}
/* Verify all necessary options have been set. */
}
if (status != 0) {
tcsv_metric_definition_destroy(md);
- return (status);
+ return status;
}
if (metric_head == NULL)
last->next = md;
}
- return (0);
+ return 0;
}
static void tcsv_instance_definition_destroy(void *arg) {
cu_tail_destroy(id->tail);
id->tail = NULL;
+ sfree(id->plugin_name);
sfree(id->instance);
sfree(id->path);
sfree(id->metric_list);
if (ci->values_num < 1) {
WARNING("tail_csv plugin: The `Collect' config option needs at least one "
"argument.");
- return (-1);
+ return -1;
}
metric_list_size = id->metric_list_len + (size_t)ci->values_num;
metric_list =
realloc(id->metric_list, sizeof(*id->metric_list) * metric_list_size);
if (metric_list == NULL)
- return (-1);
+ return -1;
id->metric_list = metric_list;
for (int i = 0; i < ci->values_num; i++) {
id->metric_list_len++;
}
- return (0);
+ return 0;
}
/* <File /> block */
id = calloc(1, sizeof(*id));
if (id == NULL)
- return (-1);
+ return -1;
+ id->plugin_name = NULL;
id->instance = NULL;
id->path = NULL;
id->metric_list = NULL;
status = cf_util_get_string(ci, &id->path);
if (status != 0) {
sfree(id);
- return (status);
+ return status;
}
/* Use default interval. */
cf_util_get_cdtime(option, &id->interval);
else if (strcasecmp("TimeFrom", option->key) == 0)
status = tcsv_config_get_index(option, &id->time_from);
+ else if (strcasecmp("Plugin", option->key) == 0)
+ status = cf_util_get_string(option, &id->plugin_name);
else {
WARNING("tail_csv plugin: Option `%s' not allowed here.", option->key);
status = -1;
if (status != 0) {
tcsv_instance_definition_destroy(id);
- return (-1);
+ return -1;
}
/* Verify all necessary options have been set. */
if (status != 0) {
tcsv_instance_definition_destroy(id);
- return (-1);
+ return -1;
}
- ssnprintf(cb_name, sizeof(cb_name), "tail_csv/%s", id->path);
+ snprintf(cb_name, sizeof(cb_name), "tail_csv/%s", id->path);
status = plugin_register_complex_read(
NULL, cb_name, tcsv_read, id->interval,
});
if (status != 0) {
ERROR("tail_csv plugin: Registering complex read function failed.");
- tcsv_instance_definition_destroy(id);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
/* Parse blocks */
child->key);
}
- return (0);
+ return 0;
} /* int tcsv_config */
static int tcsv_init(void) { /* {{{ */
metric_definition_t *md;
if (have_init)
- return (0);
+ return 0;
for (md = metric_head; md != NULL; md = md->next) {
data_set_t const *ds;
md->data_source_type = ds->ds->type;
}
- return (0);
+ return 0;
} /* }}} int tcsv_init */
static int tcsv_shutdown(void) {
tcsv_metric_definition_destroy(metric_head);
metric_head = NULL;
- return (0);
+ return 0;
}
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 : */
numtape = 0;
if (kc == NULL)
- return (-1);
+ return -1;
for (numtape = 0, ksp_chain = kc->kc_chain;
(numtape < MAX_NUMTAPE) && (ksp_chain != NULL);
ksp[numtape++] = ksp_chain;
}
- return (0);
+ return 0;
} /* int tape_init */
static void tape_submit(const char *plugin_instance, const char *type,
static kstat_io_t kio;
if (kc == NULL)
- return (-1);
+ return -1;
if (numtape <= 0)
- return (-1);
+ return -1;
for (int i = 0; i < numtape; i++) {
if (kstat_read(kc, ksp[i], &kio) == -1)
}
}
- return (0);
+ return 0;
}
void module_register(void) {
ERROR("Target `notification': The `%s' option requires exactly one string "
"argument.",
ci->key);
- return (-1);
+ return -1;
}
if ((strcasecmp("FAILURE", ci->values[0].value.string) == 0) ||
data->severity = NOTIF_FAILURE;
}
- return (0);
+ return 0;
} /* }}} int tn_config_add_severity */
static int tn_config_add_string(char **dest, /* {{{ */
char *temp;
if (dest == NULL)
- return (-EINVAL);
+ return -EINVAL;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
ERROR("Target `notification': The `%s' option requires exactly one string "
"argument.",
ci->key);
- return (-1);
+ return -1;
}
if (ci->values[0].value.string[0] == 0) {
ERROR(
"Target `notification': The `%s' option does not accept empty strings.",
ci->key);
- return (-1);
+ return -1;
}
temp = sstrdup(ci->values[0].value.string);
if (temp == NULL) {
ERROR("tn_config_add_string: sstrdup failed.");
- return (-1);
+ return -1;
}
free(*dest);
*dest = temp;
- return (0);
+ return 0;
} /* }}} int tn_config_add_string */
static int tn_destroy(void **user_data) /* {{{ */
tn_data_t *data;
if (user_data == NULL)
- return (-EINVAL);
+ return -EINVAL;
data = *user_data;
if (data == NULL)
- return (0);
+ return 0;
sfree(data->message);
sfree(data);
- return (0);
+ return 0;
} /* }}} int tn_destroy */
static int tn_create(const oconfig_item_t *ci, void **user_data) /* {{{ */
data = calloc(1, sizeof(*data));
if (data == NULL) {
ERROR("tn_create: calloc failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
data->message = NULL;
if (status != 0) {
tn_destroy((void *)&data);
- return (status);
+ return status;
}
*user_data = data;
- return (0);
+ return 0;
} /* }}} int tn_create */
static int tn_invoke(const data_set_t *ds, value_list_t *vl, /* {{{ */
int rates_failed;
if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
- return (-EINVAL);
+ return -EINVAL;
data = *user_data;
if (data == NULL) {
ERROR("Target `notification': Invoke: `data' is NULL.");
- return (-EINVAL);
+ return -EINVAL;
}
/* Initialize the structure. */
char template[DATA_MAX_NAME_LEN];
char value_str[DATA_MAX_NAME_LEN];
- ssnprintf(template, sizeof(template), "%%{ds:%s}", ds->ds[i].name);
+ const char *format = "%%{ds:%.*s}";
+ snprintf(template, sizeof(template), format,
+ DATA_MAX_NAME_LEN - strlen(format), ds->ds[i].name);
if (ds->ds[i].type != DS_TYPE_GAUGE) {
if ((rates == NULL) && (rates_failed == 0)) {
/* If this is a gauge value, use the current value. */
if (ds->ds[i].type == DS_TYPE_GAUGE)
- ssnprintf(value_str, sizeof(value_str), GAUGE_FORMAT,
- (double)vl->values[i].gauge);
+ snprintf(value_str, sizeof(value_str), GAUGE_FORMAT,
+ (double)vl->values[i].gauge);
/* If it's a counter, try to use the current rate. This may fail, if the
* value has been renamed. */
else if (rates != NULL)
- ssnprintf(value_str, sizeof(value_str), GAUGE_FORMAT, (double)rates[i]);
+ snprintf(value_str, sizeof(value_str), GAUGE_FORMAT, (double)rates[i]);
/* Since we don't know any better, use the string `unknown'. */
else
sstrncpy(value_str, "unknown", sizeof(value_str));
plugin_dispatch_notification(&n);
- return (FC_TARGET_CONTINUE);
+ return FC_TARGET_CONTINUE;
} /* }}} int tn_invoke */
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 : */
char *dest;
if (orig == NULL)
- return (NULL);
+ return NULL;
sz = strlen(orig) + 1;
dest = malloc(sz);
if (dest == NULL)
- return (NULL);
+ return NULL;
memcpy(dest, orig, sz);
- return (dest);
+ return dest;
} /* }}} char *tr_strdup */
static void tr_action_destroy(tr_action_t *act) /* {{{ */
int status;
if (dest == NULL)
- return (-EINVAL);
+ return -EINVAL;
if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) ||
(ci->values[1].type != OCONFIG_TYPE_STRING)) {
ERROR("Target `replace': The `%s' option requires exactly two string "
"arguments.",
ci->key);
- return (-1);
+ return -1;
}
act = calloc(1, sizeof(*act));
if (act == NULL) {
ERROR("tr_config_add_action: calloc failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
act->replacement = NULL;
"failed: %s.",
ci->values[0].value.string, errbuf);
sfree(act);
- return (-EINVAL);
+ return -EINVAL;
}
act->replacement = tr_strdup(ci->values[1].value.string);
if (act->replacement == NULL) {
ERROR("tr_config_add_action: tr_strdup failed.");
tr_action_destroy(act);
- return (-ENOMEM);
+ return -ENOMEM;
}
/* Insert action at end of list. */
prev->next = act;
}
- return (0);
+ return 0;
} /* }}} int tr_config_add_action */
static int tr_config_add_meta_action(tr_meta_data_action_t **dest, /* {{{ */
int status;
if (dest == NULL)
- return (-EINVAL);
+ return -EINVAL;
if (should_delete) {
if ((ci->values_num != 2) || (ci->values[0].type != OCONFIG_TYPE_STRING) ||
ERROR("Target `replace': The `%s' option requires exactly two string "
"arguments.",
ci->key);
- return (-1);
+ return -1;
}
} else {
if ((ci->values_num != 3) || (ci->values[0].type != OCONFIG_TYPE_STRING) ||
ERROR("Target `replace': The `%s' option requires exactly three string "
"arguments.",
ci->key);
- return (-1);
+ return -1;
}
}
ERROR("Target `replace': The `%s' option does not accept empty string as "
"first argument.",
ci->key);
- return (-1);
+ return -1;
}
act = calloc(1, sizeof(*act));
if (act == NULL) {
ERROR("tr_config_add_meta_action: calloc failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
act->key = NULL;
ci->values[1].value.string, errbuf);
sfree(act->key);
sfree(act);
- return (-EINVAL);
+ return -EINVAL;
}
act->key = tr_strdup(ci->values[0].value.string);
if (act->key == NULL) {
ERROR("tr_config_add_meta_action: tr_strdup failed.");
tr_meta_data_action_destroy(act);
- return (-ENOMEM);
+ return -ENOMEM;
}
if (!should_delete) {
if (act->replacement == NULL) {
ERROR("tr_config_add_meta_action: tr_strdup failed.");
tr_meta_data_action_destroy(act);
- return (-ENOMEM);
+ return -ENOMEM;
}
}
prev->next = act;
}
- return (0);
+ return 0;
} /* }}} int tr_config_add_meta_action */
static int tr_action_invoke(tr_action_t *act_head, /* {{{ */
regmatch_t matches[8] = {[0] = {0}};
if (act_head == NULL)
- return (-EINVAL);
+ return -EINVAL;
sstrncpy(buffer, buffer_in, sizeof(buffer));
if ((may_be_empty == 0) && (buffer[0] == 0)) {
WARNING("Target `replace': Replacement resulted in an empty string, "
"which is not allowed for this buffer (`host' or `plugin').");
- return (0);
+ return 0;
}
DEBUG("target_replace plugin: tr_action_invoke: -> buffer = %s;", buffer);
sstrncpy(buffer_in, buffer, buffer_in_size);
- return (0);
+ return 0;
} /* }}} int tr_action_invoke */
static int tr_meta_data_action_invoke(/* {{{ */
regmatch_t matches[8] = {[0] = {0}};
if (act_head == NULL)
- return (-EINVAL);
+ return -EINVAL;
if ((*dest) == NULL) /* nothing to do */
- return (0);
+ return 0;
for (tr_meta_data_action_t *act = act_head; act != NULL; act = act->next) {
char temp[DATA_MAX_NAME_LEN];
if (meta_data_status != 0) {
ERROR("Target `replace': Unable to retrieve metadata value for `%s'.",
act->key);
- return (meta_data_status);
+ return meta_data_status;
}
DEBUG("target_replace plugin: tr_meta_data_action_invoke: `%s' "
if ((result = meta_data_create()) == NULL) {
ERROR("Target `replace': failed to create metadata for `%s'.", act->key);
sfree(value);
- return (-ENOMEM);
+ return -ENOMEM;
}
meta_data_status = meta_data_add_string(result, act->key, temp);
act->key);
meta_data_destroy(result);
sfree(value);
- return (meta_data_status);
+ return meta_data_status;
}
meta_data_clone_merge(dest, result);
sfree(value);
} /* for (act = act_head; act != NULL; act = act->next) */
- return (0);
+ return 0;
} /* }}} int tr_meta_data_action_invoke */
static int tr_destroy(void **user_data) /* {{{ */
tr_data_t *data;
if (user_data == NULL)
- return (-EINVAL);
+ return -EINVAL;
data = *user_data;
if (data == NULL)
- return (0);
+ return 0;
tr_action_destroy(data->host);
tr_action_destroy(data->plugin);
tr_meta_data_action_destroy(data->meta);
sfree(data);
- return (0);
+ return 0;
} /* }}} int tr_destroy */
static int tr_create(const oconfig_item_t *ci, void **user_data) /* {{{ */
data = calloc(1, sizeof(*data));
if (data == NULL) {
ERROR("tr_create: calloc failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
data->host = NULL;
if (status != 0) {
tr_destroy((void *)&data);
- return (status);
+ return status;
}
*user_data = data;
- return (0);
+ return 0;
} /* }}} int tr_create */
static int tr_invoke(const data_set_t *ds, value_list_t *vl, /* {{{ */
tr_data_t *data;
if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
- return (-EINVAL);
+ return -EINVAL;
data = *user_data;
if (data == NULL) {
ERROR("Target `replace': Invoke: `data' is NULL.");
- return (-EINVAL);
+ return -EINVAL;
}
if (data->meta != NULL) {
/* HANDLE_FIELD (type, 0); */
HANDLE_FIELD(type_instance, 1);
- return (FC_TARGET_CONTINUE);
+ return FC_TARGET_CONTINUE;
} /* }}} int tr_invoke */
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 : */
curr_counter = (uint64_t)vl->values[dsrc_index].counter;
- ssnprintf(key_prev_counter, sizeof(key_prev_counter),
- "target_scale[%p,%i]:prev_counter", (void *)data, dsrc_index);
- ssnprintf(key_int_counter, sizeof(key_int_counter),
- "target_scale[%p,%i]:int_counter", (void *)data, dsrc_index);
- ssnprintf(key_int_fraction, sizeof(key_int_fraction),
- "target_scale[%p,%i]:int_fraction", (void *)data, dsrc_index);
+ snprintf(key_prev_counter, sizeof(key_prev_counter),
+ "target_scale[%p,%i]:prev_counter", (void *)data, dsrc_index);
+ snprintf(key_int_counter, sizeof(key_int_counter),
+ "target_scale[%p,%i]:int_counter", (void *)data, dsrc_index);
+ snprintf(key_int_fraction, sizeof(key_int_fraction),
+ "target_scale[%p,%i]:int_fraction", (void *)data, dsrc_index);
prev_counter = curr_counter;
int_counter = 0;
uc_meta_data_add_unsigned_int(vl, key_int_counter, int_counter);
uc_meta_data_add_double(vl, key_int_fraction, int_fraction);
- return (0);
+ return 0;
} /* }}} int ts_invoke_counter */
static int ts_invoke_gauge(const data_set_t *ds, value_list_t *vl, /* {{{ */
if (!isnan(data->offset))
vl->values[dsrc_index].gauge += data->offset;
- return (0);
+ return 0;
} /* }}} int ts_invoke_gauge */
static int ts_invoke_derive(const data_set_t *ds, value_list_t *vl, /* {{{ */
curr_derive = (int64_t)vl->values[dsrc_index].derive;
- ssnprintf(key_prev_derive, sizeof(key_prev_derive),
- "target_scale[%p,%i]:prev_derive", (void *)data, dsrc_index);
- ssnprintf(key_int_derive, sizeof(key_int_derive),
- "target_scale[%p,%i]:int_derive", (void *)data, dsrc_index);
- ssnprintf(key_int_fraction, sizeof(key_int_fraction),
- "target_scale[%p,%i]:int_fraction", (void *)data, dsrc_index);
+ snprintf(key_prev_derive, sizeof(key_prev_derive),
+ "target_scale[%p,%i]:prev_derive", (void *)data, dsrc_index);
+ snprintf(key_int_derive, sizeof(key_int_derive),
+ "target_scale[%p,%i]:int_derive", (void *)data, dsrc_index);
+ snprintf(key_int_fraction, sizeof(key_int_fraction),
+ "target_scale[%p,%i]:int_fraction", (void *)data, dsrc_index);
prev_derive = curr_derive;
int_derive = 0;
uc_meta_data_add_signed_int(vl, key_int_derive, int_derive);
uc_meta_data_add_double(vl, key_int_fraction, int_fraction);
- return (0);
+ return 0;
} /* }}} int ts_invoke_derive */
static int ts_invoke_absolute(const data_set_t *ds, value_list_t *vl, /* {{{ */
curr_absolute = (uint64_t)vl->values[dsrc_index].absolute;
- ssnprintf(key_int_fraction, sizeof(key_int_fraction),
- "target_scale[%p,%i]:int_fraction", (void *)data, dsrc_index);
+ snprintf(key_int_fraction, sizeof(key_int_fraction),
+ "target_scale[%p,%i]:int_fraction", (void *)data, dsrc_index);
int_fraction = 0.0;
/* Update to the new absolute value */
uc_meta_data_add_double(vl, key_int_fraction, int_fraction);
- return (0);
+ return 0;
} /* }}} int ts_invoke_absolute */
static int ts_config_set_double(double *ret, oconfig_item_t *ci) /* {{{ */
WARNING("scale target: The `%s' config option needs "
"exactly one numeric argument.",
ci->key);
- return (-1);
+ return -1;
}
*ret = ci->values[0].value.number;
DEBUG("ts_config_set_double: *ret = %g", *ret);
- return (0);
+ return 0;
} /* }}} int ts_config_set_double */
static int ts_config_add_data_source(ts_data_t *data, /* {{{ */
/* Check number of arbuments. */
if (ci->values_num < 1) {
ERROR("`value' match: `%s' needs at least one argument.", ci->key);
- return (-1);
+ return -1;
}
/* Check type of arguments */
ci->key, i + 1,
(ci->values[i].type == OCONFIG_TYPE_BOOLEAN) ? "truth value"
: "number");
- return (-1);
+ return -1;
}
/* Allocate space for the char pointers */
temp = realloc(data->data_sources, new_data_sources_num * sizeof(char *));
if (temp == NULL) {
ERROR("`value' match: realloc failed.");
- return (-1);
+ return -1;
}
data->data_sources = temp;
data->data_sources_num++;
}
- return (0);
+ return 0;
} /* }}} int ts_config_add_data_source */
static int ts_destroy(void **user_data) /* {{{ */
ts_data_t *data;
if (user_data == NULL)
- return (-EINVAL);
+ return -EINVAL;
data = (ts_data_t *)*user_data;
sfree(data);
*user_data = NULL;
- return (0);
+ return 0;
} /* }}} int ts_destroy */
static int ts_create(const oconfig_item_t *ci, void **user_data) /* {{{ */
data = calloc(1, sizeof(*data));
if (data == NULL) {
ERROR("ts_create: calloc failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
data->factor = NAN;
if (status != 0) {
ts_destroy((void *)&data);
- return (status);
+ return status;
}
*user_data = data;
- return (0);
+ return 0;
} /* }}} int ts_create */
static int ts_invoke(const data_set_t *ds, value_list_t *vl, /* {{{ */
ts_data_t *data;
if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
- return (-EINVAL);
+ return -EINVAL;
data = *user_data;
if (data == NULL) {
ERROR("Target `scale': Invoke: `data' is NULL.");
- return (-EINVAL);
+ return -EINVAL;
}
for (size_t i = 0; i < ds->ds_num; i++) {
ds->ds[i].type);
}
- return (FC_TARGET_CONTINUE);
+ return FC_TARGET_CONTINUE;
} /* }}} int ts_invoke */
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 : */
ERROR("ts_util_get_key_and_string_wo_strdup: The %s option requires "
"exactly two string arguments.",
ci->key);
- return (-1);
+ return -1;
}
*ret_key = ci->values[0].value.string;
*ret_string = ci->values[1].value.string;
- return (0);
+ return 0;
} /* }}} int ts_util_get_key_and_string_wo_strdup */
static int ts_config_add_string(char **dest, /* {{{ */
status = cf_util_get_string(ci, &tmp);
if (status != 0)
- return (status);
+ return status;
if (!may_be_empty && (strlen(tmp) == 0)) {
ERROR("Target `set': The `%s' option does not accept empty strings.",
ci->key);
sfree(tmp);
- return (-1);
+ return -1;
}
*dest = tmp;
- return (0);
+ return 0;
} /* }}} int ts_config_add_string */
static int ts_config_add_meta(meta_data_t **dest, /* {{{ */
status = ts_util_get_key_and_string_wo_strdup(ci, &key, &string);
if (status != 0)
- return (status);
+ return status;
if (strlen(key) == 0) {
ERROR("Target `set': The `%s' option does not accept empty string as "
"first argument.",
ci->key);
- return (-1);
+ return -1;
}
if (!may_be_empty && (strlen(string) == 0)) {
ERROR("Target `set': The `%s' option does not accept empty string as "
"second argument.",
ci->key);
- return (-1);
+ return -1;
}
if ((*dest) == NULL) {
/* Create a new meta_data_t */
if ((*dest = meta_data_create()) == NULL) {
ERROR("Target `set': failed to create a meta data for `%s'.", ci->key);
- return (-ENOMEM);
+ return -ENOMEM;
}
}
- return (meta_data_add_string(*dest, key, string));
+ return meta_data_add_string(*dest, key, string);
} /* }}} int ts_config_add_meta */
static int ts_config_add_meta_delete(ts_key_list_t **dest, /* {{{ */
entry = calloc(1, sizeof(*entry));
if (entry == NULL) {
ERROR("ts_config_add_meta_delete: calloc failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
if (cf_util_get_string(ci, &entry->key) != 0) {
ts_key_list_free(entry);
- return (-1); /* An error has already been reported. */
+ return -1; /* An error has already been reported. */
}
if (strlen(entry->key) == 0) {
"first argument.",
ci->key);
ts_key_list_free(entry);
- return (-1);
+ return -1;
}
entry->next = *dest;
*dest = entry;
- return (0);
+ return 0;
} /* }}} int ts_config_add_meta_delete */
static void ts_subst(char *dest, size_t size, const char *string, /* {{{ */
char *value_str;
const char *key = meta_toc[i];
- ssnprintf(meta_name, sizeof(meta_name), "%%{meta:%s}", key);
+ snprintf(meta_name, sizeof(meta_name), "%%{meta:%s}", key);
if (meta_data_as_string(vl->meta, key, &value_str) != 0)
continue;
ts_data_t *data;
if (user_data == NULL)
- return (-EINVAL);
+ return -EINVAL;
data = *user_data;
if (data == NULL)
- return (0);
+ return 0;
free(data->host);
free(data->plugin);
ts_key_list_free(data->meta_delete);
free(data);
- return (0);
+ return 0;
} /* }}} int ts_destroy */
static int ts_create(const oconfig_item_t *ci, void **user_data) /* {{{ */
data = calloc(1, sizeof(*data));
if (data == NULL) {
ERROR("ts_create: calloc failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
data->host = NULL;
if (status != 0) {
ts_destroy((void *)&data);
- return (status);
+ return status;
}
*user_data = data;
- return (0);
+ return 0;
} /* }}} int ts_create */
static int ts_invoke(const data_set_t *ds, value_list_t *vl, /* {{{ */
meta_data_t *new_meta = NULL;
if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
- return (-EINVAL);
+ return -EINVAL;
data = *user_data;
if (data == NULL) {
ERROR("Target `set': Invoke: `data' is NULL.");
- return (-EINVAL);
+ return -EINVAL;
}
orig = *vl;
if ((new_meta = meta_data_create()) == NULL) {
ERROR("Target `set': failed to create replacement metadata.");
- return (-ENOMEM);
+ return -ENOMEM;
}
int status = meta_data_toc(data->meta, &meta_toc);
key);
strarray_free(meta_toc, meta_entries);
meta_data_destroy(new_meta);
- return (status);
+ return status;
}
ts_subst(temp, sizeof(temp), string, &orig);
ERROR("Target `set': Unable to set metadata value `%s'.", key);
strarray_free(meta_toc, meta_entries);
meta_data_destroy(new_meta);
- return (status);
+ return status;
}
}
meta_data_delete(vl->meta, l->key);
}
- return (FC_TARGET_CONTINUE);
+ return FC_TARGET_CONTINUE;
} /* }}} int ts_invoke */
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 : */
/* Can't upgrade if both instances have been set. */
if ((vl->plugin_instance[0] != 0) && (vl->type_instance[0] != 0))
- return (FC_TARGET_CONTINUE);
+ return FC_TARGET_CONTINUE;
/* Copy everything: Time, interval, host, ... */
memcpy(&new_vl, vl, sizeof(new_vl));
plugin_dispatch_values(&new_vl);
/* Abort processing */
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
} /* }}} int v5_df */
/*
static int v5_interface(const data_set_t *ds, value_list_t *vl) /* {{{ */
{
if ((vl->plugin_instance[0] != 0) || (vl->type_instance[0] == 0))
- return (FC_TARGET_CONTINUE);
+ return FC_TARGET_CONTINUE;
v5_swap_instances(vl);
- return (FC_TARGET_CONTINUE);
+ return FC_TARGET_CONTINUE;
} /* }}} int v5_interface */
/*
value_list_t new_vl;
if (vl->values_len != 5)
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
/* Copy everything: Time, interval, host, ... */
memcpy(&new_vl, vl, sizeof(new_vl));
plugin_dispatch_values(&new_vl);
/* Abort processing */
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
} /* }}} int v5_mysql_qcache */
/*
value_list_t new_vl;
if (vl->values_len != 4)
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
/* Copy everything: Time, interval, host, ... */
memcpy(&new_vl, vl, sizeof(new_vl));
plugin_dispatch_values(&new_vl);
/* Abort processing */
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
} /* }}} int v5_mysql_threads */
/*
_Bool is_hits;
if (vl->values_len != 4)
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
if (strcmp("hits", vl->type_instance) == 0)
is_hits = 1;
else if (strcmp("misses", vl->type_instance) == 0)
is_hits = 0;
else
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
/* Copy everything: Time, interval, host, ... */
memcpy(&new_vl, vl, sizeof(new_vl));
/* Dispatch new value lists instead of this one */
new_vl.values[0].derive = (derive_t)vl->values[0].counter;
- ssnprintf(new_vl.type_instance, sizeof(new_vl.type_instance),
- "demand_data-%s", is_hits ? "hit" : "miss");
+ snprintf(new_vl.type_instance, sizeof(new_vl.type_instance), "demand_data-%s",
+ is_hits ? "hit" : "miss");
plugin_dispatch_values(&new_vl);
new_vl.values[0].derive = (derive_t)vl->values[1].counter;
- ssnprintf(new_vl.type_instance, sizeof(new_vl.type_instance),
- "demand_metadata-%s", is_hits ? "hit" : "miss");
+ snprintf(new_vl.type_instance, sizeof(new_vl.type_instance),
+ "demand_metadata-%s", is_hits ? "hit" : "miss");
plugin_dispatch_values(&new_vl);
new_vl.values[0].derive = (derive_t)vl->values[2].counter;
- ssnprintf(new_vl.type_instance, sizeof(new_vl.type_instance),
- "prefetch_data-%s", is_hits ? "hit" : "miss");
+ snprintf(new_vl.type_instance, sizeof(new_vl.type_instance),
+ "prefetch_data-%s", is_hits ? "hit" : "miss");
plugin_dispatch_values(&new_vl);
new_vl.values[0].derive = (derive_t)vl->values[3].counter;
- ssnprintf(new_vl.type_instance, sizeof(new_vl.type_instance),
- "prefetch_metadata-%s", is_hits ? "hit" : "miss");
+ snprintf(new_vl.type_instance, sizeof(new_vl.type_instance),
+ "prefetch_metadata-%s", is_hits ? "hit" : "miss");
plugin_dispatch_values(&new_vl);
/* Abort processing */
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
} /* }}} int v5_zfs_arc_counts */
/*
value_list_t new_vl;
if (vl->values_len != 2)
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
/* Copy everything: Time, interval, host, ... */
memcpy(&new_vl, vl, sizeof(new_vl));
plugin_dispatch_values(&new_vl);
/* Abort processing */
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
} /* }}} int v5_zfs_arc_l2_bytes */
/*
value_list_t new_vl;
if (vl->values_len != 1)
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
/* Copy everything: Time, interval, host, ... */
memcpy(&new_vl, vl, sizeof(new_vl));
plugin_dispatch_values(&new_vl);
/* Abort processing */
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
} /* }}} int v5_zfs_arc_l2_size */
/*
value_list_t new_vl;
if (vl->values_len != 1)
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
/* Copy everything: Time, interval, host, ... */
memcpy(&new_vl, vl, sizeof(new_vl));
plugin_dispatch_values(&new_vl);
/* Abort processing */
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
} /* }}} int v5_zfs_arc_ratio */
/*
value_list_t new_vl;
if (vl->values_len != 4)
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
/* Copy everything: Time, interval, host, ... */
memcpy(&new_vl, vl, sizeof(new_vl));
plugin_dispatch_values(&new_vl);
/* Abort processing */
- return (FC_TARGET_STOP);
+ return FC_TARGET_STOP;
} /* }}} int v5_zfs_arc_size */
static int v5_destroy(void **user_data) /* {{{ */
{
- return (0);
+ return 0;
} /* }}} int v5_destroy */
static int v5_create(const oconfig_item_t *ci, void **user_data) /* {{{ */
{
*user_data = NULL;
- return (0);
+ return 0;
} /* }}} int v5_create */
static int v5_invoke(const data_set_t *ds, value_list_t *vl, /* {{{ */
notification_meta_t __attribute__((unused)) * *meta,
void __attribute__((unused)) * *user_data) {
if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
- return (-EINVAL);
+ return -EINVAL;
if (strcmp("df", vl->type) == 0)
- return (v5_df(ds, vl));
+ return v5_df(ds, vl);
else if (strcmp("interface", vl->plugin) == 0)
- return (v5_interface(ds, vl));
+ return v5_interface(ds, vl);
else if (strcmp("mysql_qcache", vl->type) == 0)
- return (v5_mysql_qcache(ds, vl));
+ return v5_mysql_qcache(ds, vl);
else if (strcmp("mysql_threads", vl->type) == 0)
- return (v5_mysql_threads(ds, vl));
+ return v5_mysql_threads(ds, vl);
else if (strcmp("arc_counts", vl->type) == 0)
- return (v5_zfs_arc_counts(ds, vl));
+ return v5_zfs_arc_counts(ds, vl);
else if (strcmp("arc_l2_bytes", vl->type) == 0)
- return (v5_zfs_arc_l2_bytes(ds, vl));
+ return v5_zfs_arc_l2_bytes(ds, vl);
else if (strcmp("arc_l2_size", vl->type) == 0)
- return (v5_zfs_arc_l2_size(ds, vl));
+ return v5_zfs_arc_l2_size(ds, vl);
else if (strcmp("arc_ratio", vl->type) == 0)
- return (v5_zfs_arc_ratio(ds, vl));
+ return v5_zfs_arc_ratio(ds, vl);
else if (strcmp("arc_size", vl->type) == 0)
- return (v5_zfs_arc_size(ds, vl));
+ return v5_zfs_arc_size(ds, vl);
- return (FC_TARGET_CONTINUE);
+ return FC_TARGET_CONTINUE;
} /* }}} int v5_invoke */
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 : */
#include "common.h"
#include "plugin.h"
-#if defined(__OpenBSD__) || defined(__NetBSD__)
+#if defined(__OpenBSD__)
+#define HAVE_KVM_GETFILES 1
+#endif
+
+#if defined(__NetBSD__)
#undef HAVE_SYSCTLBYNAME /* force HAVE_LIBKVM_NLIST path */
#endif
-#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST && !KERNEL_AIX
+#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_KVM_GETFILES && \
+ !HAVE_LIBKVM_NLIST && !KERNEL_AIX
#error "No applicable input method."
#endif
#include <netinet/tcpip.h>
/* #endif HAVE_SYSCTLBYNAME */
-/* This is for OpenBSD and NetBSD. */
+#elif HAVE_KVM_GETFILES
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#define _KERNEL /* for DTYPE_SOCKET */
+#include <sys/file.h>
+#undef _KERNEL
+
+#include <netinet/in.h>
+
+#include <kvm.h>
+/* #endif HAVE_KVM_GETFILES */
+
+/* This is for NetBSD. */
#elif HAVE_LIBKVM_NLIST
#include <arpa/inet.h>
#include <net/route.h>
#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",
if (((port_collect_listening != 0) && (pe->flags & PORT_IS_LISTENING)) ||
(pe->flags & PORT_COLLECT_LOCAL)) {
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance),
- "%" PRIu16 "-local", pe->port);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance),
+ "%" PRIu16 "-local", pe->port);
for (int i = 1; i <= TCP_STATE_MAX; i++) {
vl.values[0].gauge = pe->count_local[i];
}
if (pe->flags & PORT_COLLECT_REMOTE) {
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance),
- "%" PRIu16 "-remote", pe->port);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance),
+ "%" PRIu16 "-remote", pe->port);
for (int i = 1; i <= TCP_STATE_MAX; i++) {
vl.values[0].gauge = pe->count_remote[i];
if ((ret == NULL) && (create != 0)) {
ret = calloc(1, sizeof(*ret));
if (ret == NULL)
- return (NULL);
+ return NULL;
ret->port = port;
ret->next = port_list_head;
port_list_head = ret;
}
- return (ret);
+ return ret;
} /* port_entry_t *conn_get_port_entry */
/* Removes ports that were added automatically due to the `ListeningPorts'
NOTICE("tcpconns plugin: Ignoring connection with "
"unknown state 0x%02" PRIx8 ".",
state);
- return (-1);
+ return -1;
}
count_total[state]++;
if (pe != NULL)
pe->count_remote[state]++;
- return (0);
+ return 0;
} /* int conn_handle_ports */
#if KERNEL_LINUX
ERROR("tcpconns plugin: conn_read_netlink: socket(AF_NETLINK, SOCK_RAW, "
"NETLINK_INET_DIAG) failed: %s",
sstrerror(errno, buf, sizeof(buf)));
- return (-1);
+ return -1;
}
struct sockaddr_nl nladdr = {.nl_family = AF_NETLINK};
ERROR("tcpconns plugin: conn_read_netlink: sendmsg(2) failed: %s",
sstrerror(errno, buf, sizeof(buf)));
close(fd);
- return (-1);
+ return -1;
}
iov.iov_base = buf;
ERROR("tcpconns plugin: conn_read_netlink: recvmsg(2) failed: %s",
sstrerror(errno, buf, sizeof(buf)));
close(fd);
- return (-1);
+ return -1;
} else if (status == 0) {
close(fd);
DEBUG("tcpconns plugin: conn_read_netlink: Unexpected zero-sized "
"reply from netlink socket.");
- return (0);
+ return 0;
}
h = (struct nlmsghdr *)buf;
if (h->nlmsg_type == NLMSG_DONE) {
close(fd);
- return (0);
+ return 0;
} else if (h->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *msg_error;
msg_error->error);
close(fd);
- return (1);
+ return 1;
}
r = NLMSG_DATA(h);
} /* while (1) */
/* Not reached because the while() loop above handles the exit condition. */
- return (0);
+ return 0;
#else
- return (1);
+ return 1;
#endif /* HAVE_STRUCT_LINUX_INET_DIAG_REQ */
} /* int conn_read_netlink */
while ((buffer_len > 0) && (buffer[buffer_len - 1] < 32))
buffer[--buffer_len] = '\0';
if (buffer_len <= 0)
- return (-1);
+ return -1;
fields_len = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields));
if (fields_len < 12) {
DEBUG("tcpconns plugin: Got %i fields, expected at least 12.", fields_len);
- return (-1);
+ return -1;
}
port_local_str = strchr(fields[1], ':');
port_remote_str = strchr(fields[2], ':');
if ((port_local_str == NULL) || (port_remote_str == NULL))
- return (-1);
+ return -1;
port_local_str++;
port_remote_str++;
if ((*port_local_str == '\0') || (*port_remote_str == '\0'))
- return (-1);
+ return -1;
endptr = NULL;
port_local = (uint16_t)strtol(port_local_str, &endptr, 16);
if ((endptr == NULL) || (*endptr != '\0'))
- return (-1);
+ return -1;
endptr = NULL;
port_remote = (uint16_t)strtol(port_remote_str, &endptr, 16);
if ((endptr == NULL) || (*endptr != '\0'))
- return (-1);
+ return -1;
endptr = NULL;
state = (uint8_t)strtol(fields[3], &endptr, 16);
if ((endptr == NULL) || (*endptr != '\0'))
- return (-1);
+ return -1;
- return (conn_handle_ports(port_local, port_remote, state));
+ return conn_handle_ports(port_local, port_remote, state);
} /* int conn_handle_line */
static int conn_read_file(const char *file) {
fh = fopen(file, "r");
if (fh == NULL)
- return (-1);
+ return -1;
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
conn_handle_line(buffer);
fclose(fh);
- return (0);
+ return 0;
} /* int conn_read_file */
/* #endif KERNEL_LINUX */
if ((port < 1) || (port > 65535)) {
ERROR("tcpconns plugin: Invalid port: %i", port);
- return (1);
+ return 1;
}
pe = conn_get_port_entry((uint16_t)port, 1 /* create */);
if (pe == NULL) {
ERROR("tcpconns plugin: conn_get_port_entry failed.");
- return (1);
+ return 1;
}
if (strcasecmp(key, "LocalPort") == 0)
else
port_collect_total = 0;
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int conn_config */
#if KERNEL_LINUX
if (port_collect_total == 0 && port_list_head == NULL)
port_collect_listening = 1;
- return (0);
+ return 0;
} /* int conn_init */
static int conn_read(void) {
linux_source = SRC_PROC;
/* return success here to avoid the "plugin failed" message. */
- return (0);
+ return 0;
}
}
if (status == 0)
conn_submit_all();
else
- return (status);
+ return status;
- return (0);
+ return 0;
} /* int conn_read */
/* #endif KERNEL_LINUX */
status = sysctlbyname("net.inet.tcp.pcblist", NULL, &buffer_len, 0, 0);
if (status < 0) {
ERROR("tcpconns plugin: sysctlbyname failed.");
- return (-1);
+ return -1;
}
buffer = malloc(buffer_len);
if (buffer == NULL) {
ERROR("tcpconns plugin: malloc failed.");
- return (-1);
+ return -1;
}
status = sysctlbyname("net.inet.tcp.pcblist", buffer, &buffer_len, 0, 0);
if (status < 0) {
ERROR("tcpconns plugin: sysctlbyname failed.");
sfree(buffer);
- return (-1);
+ return -1;
}
if (buffer_len <= sizeof(struct xinpgen)) {
ERROR("tcpconns plugin: (buffer_len <= sizeof (struct xinpgen))");
sfree(buffer);
- return (-1);
+ return -1;
}
in_orig = (struct xinpgen *)buffer;
conn_submit_all();
- return (0);
+ return 0;
} /* 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;
if (status != size) {
ERROR("tcpconns plugin: kvm_read failed (got %i, expected %i): %s\n",
status, size, kvm_geterr(kvmd));
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int kread */
static int conn_init(void) {
kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, buf);
if (kvmd == NULL) {
ERROR("tcpconns plugin: kvm_openfiles failed: %s", buf);
- return (-1);
+ return -1;
}
status = kvm_nlist(kvmd, nl);
if (status < 0) {
ERROR("tcpconns plugin: kvm_nlist failed with status %i.", status);
- return (-1);
+ return -1;
}
if (nl[N_TCBTABLE].n_type == 0) {
ERROR("tcpconns plugin: Error looking up kernel's namelist: "
"N_TCBTABLE is invalid.");
- return (-1);
+ return -1;
}
inpcbtable_off = (u_long)nl[N_TCBTABLE].n_value;
inpcbtable_ptr = (struct inpcbtable *)nl[N_TCBTABLE].n_value;
- return (0);
+ return 0;
} /* int conn_init */
static int conn_read(void) {
/* Read the pcbtable from the kernel */
status = kread(inpcbtable_off, &table, sizeof(table));
if (status != 0)
- return (-1);
+ return -1;
#if defined(__OpenBSD__) || \
(defined(__NetBSD_Version__) && __NetBSD_Version__ > 699002700)
/* Read the pcb pointed to by `next' into `inpcb' */
status = kread((u_long)next, &inpcb, sizeof(inpcb));
if (status != 0)
- return (-1);
+ return -1;
/* Advance `next' */
#if defined(__OpenBSD__) || \
status = kread((u_long)inpcb.inp_ppcb, &tcpcb, sizeof(tcpcb));
if (status != 0)
- return (-1);
+ return -1;
conn_handle_ports(ntohs(inpcb.inp_lport), ntohs(inpcb.inp_fport),
tcpcb.t_state);
} /* while (next != head) */
conn_submit_all();
- return (0);
+ return 0;
}
/* #endif HAVE_LIBKVM_NLIST */
size = netinfo(NETINFO_TCP, 0, 0, 0);
if (size < 0) {
ERROR("tcpconns plugin: netinfo failed return: %i", size);
- return (-1);
+ return -1;
}
if (size == 0)
- return (0);
+ return 0;
if ((size - sizeof(struct netinfo_header)) % sizeof(struct netinfo_conn)) {
ERROR("tcpconns plugin: invalid buffer size");
- return (-1);
+ return -1;
}
data = malloc(size);
if (data == NULL) {
ERROR("tcpconns plugin: malloc failed");
- return (-1);
+ return -1;
}
if (netinfo(NETINFO_TCP, data, &size, 0) < 0) {
ERROR("tcpconns plugin: netinfo failed");
free(data);
- return (-1);
+ return -1;
}
header = (struct netinfo_header *)data;
conn_submit_all();
- return (0);
+ return 0;
}
#endif /* KERNEL_AIX */
#endif
plugin_register_read("tcpconns", conn_read);
} /* void module_register */
-
-/*
- * vim: set shiftwidth=2 softtabstop=2 tabstop=8 fdm=marker :
- */
/* Check port range */
if ((vserver_port <= 0) || (vserver_port > 65535)) {
ERROR("teamspeak2 plugin: VServer port is invalid: %i", vserver_port);
- return (-1);
+ return -1;
}
/* Allocate memory */
entry = calloc(1, sizeof(*entry));
if (entry == NULL) {
ERROR("teamspeak2 plugin: calloc failed.");
- return (-1);
+ return -1;
}
/* Save data */
INFO("teamspeak2 plugin: Registered new vserver: %i", vserver_port);
- return (0);
+ return 0;
} /* int tss2_add_vserver */
static void tss2_submit_gauge(const char *plugin_instance, const char *type,
*ret_read_fh = global_read_fh;
if (ret_write_fh != NULL)
*ret_write_fh = global_write_fh;
- return (0);
+ return 0;
}
/* Get all addrs for this hostname */
&ai_hints, &ai_head);
if (status != 0) {
ERROR("teamspeak2 plugin: getaddrinfo failed: %s", gai_strerror(status));
- return (-1);
+ return -1;
}
/* Try all given hosts until we can connect to one */
/* Check if we really got connected */
if (sd < 0)
- return (-1);
+ return -1;
/* Create file objects from sockets */
global_read_fh = fdopen(sd, "r");
ERROR("teamspeak2 plugin: fdopen failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
close(sd);
- return (-1);
+ return -1;
}
global_write_fh = fdopen(sd, "w");
ERROR("teamspeak2 plugin: fdopen failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
tss2_close_socket();
- return (-1);
+ return -1;
}
{ /* Check that the server correctly identifies itself. */
"to server. Expected ``[TS]'', got ``%s''.",
buffer);
tss2_close_socket();
- return (-1);
+ return -1;
}
DEBUG("teamspeak2 plugin: Server send correct banner, connected!");
}
*ret_read_fh = global_read_fh;
if (ret_write_fh != NULL)
*ret_write_fh = global_write_fh;
- return (0);
+ return 0;
} /* int tss2_get_socket */
static int tss2_send_request(FILE *fh, const char *request) {
if (status < 0) {
ERROR("teamspeak2 plugin: fputs failed.");
tss2_close_socket();
- return (-1);
+ return -1;
}
fflush(fh);
- return (0);
+ return 0;
} /* int tss2_send_request */
static int tss2_receive_line(FILE *fh, char *buffer, int buffer_size) {
ERROR("teamspeak2 plugin: fgets failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
tss2_close_socket();
- return (-1);
+ return -1;
}
buffer[buffer_size - 1] = 0;
- return (0);
+ return 0;
} /* int tss2_receive_line */
static int tss2_select_vserver(FILE *read_fh, FILE *write_fh,
int status;
/* Send request */
- ssnprintf(command, sizeof(command), "sel %i\r\n", vserver->port);
+ snprintf(command, sizeof(command), "sel %i\r\n", vserver->port);
status = tss2_send_request(write_fh, command);
if (status != 0) {
ERROR("teamspeak2 plugin: tss2_send_request (%s) failed.", command);
- return (-1);
+ return -1;
}
/* Get answer */
status = tss2_receive_line(read_fh, response, sizeof(response));
if (status != 0) {
ERROR("teamspeak2 plugin: tss2_receive_line failed.");
- return (-1);
+ return -1;
}
response[sizeof(response) - 1] = 0;
/* Check answer */
if ((strncasecmp("OK", response, 2) == 0) &&
((response[2] == 0) || (response[2] == '\n') || (response[2] == '\r')))
- return (0);
+ return 0;
ERROR("teamspeak2 plugin: Command ``%s'' failed. "
"Response received from server was: ``%s''.",
command, response);
- return (-1);
+ return -1;
} /* int tss2_select_vserver */
static int tss2_vserver_gapl(FILE *read_fh, FILE *write_fh,
status = tss2_send_request(write_fh, "gapl\r\n");
if (status != 0) {
ERROR("teamspeak2 plugin: tss2_send_request (gapl) failed.");
- return (-1);
+ return -1;
}
while (42) {
read_fh = NULL;
write_fh = NULL;
ERROR("teamspeak2 plugin: tss2_receive_line failed.");
- return (-1);
+ return -1;
}
buffer[sizeof(buffer) - 1] = 0;
break;
} else if (strncasecmp("ERROR", buffer, 5) == 0) {
ERROR("teamspeak2 plugin: Server returned an error: %s", buffer);
- return (-1);
+ return -1;
} else {
WARNING("teamspeak2 plugin: Server returned unexpected string: %s",
buffer);
}
*ret_value = packet_loss;
- return (0);
+ return 0;
} /* int tss2_vserver_gapl */
static int tss2_read_vserver(vserver_list_t *vserver) {
status = tss2_get_socket(&read_fh, &write_fh);
if (status != 0) {
ERROR("teamspeak2 plugin: tss2_get_socket failed.");
- return (-1);
+ return -1;
}
if (vserver == NULL) {
status = tss2_send_request(write_fh, "gi\r\n");
} else {
/* Request server information */
- ssnprintf(plugin_instance, sizeof(plugin_instance), "vserver%i",
- vserver->port);
+ snprintf(plugin_instance, sizeof(plugin_instance), "vserver%i",
+ vserver->port);
/* Select the server */
status = tss2_select_vserver(read_fh, write_fh, vserver);
if (status != 0)
- return (status);
+ return status;
status = tss2_send_request(write_fh, "si\r\n");
}
if (status != 0) {
ERROR("teamspeak2 plugin: tss2_send_request failed.");
- return (-1);
+ return -1;
}
/* Loop until break */
tss2_submit_gauge(plugin_instance, "gauge", "servers", servers);
if (valid == 0)
- return (-1);
- return (0);
+ return -1;
+ return 0;
} /* int tss2_read_vserver */
static int tss2_config(const char *key, const char *value) {
temp = strdup(value);
if (temp == NULL) {
ERROR("teamspeak2 plugin: strdup failed.");
- return (1);
+ return 1;
}
sfree(config_host);
config_host = temp;
temp = strdup(value);
if (temp == NULL) {
ERROR("teamspeak2 plugin: strdup failed.");
- return (1);
+ return 1;
}
sfree(config_port);
config_port = temp;
status = tss2_add_vserver(atoi(value));
if (status != 0)
- return (1);
+ return 1;
} else {
/* Unknown variable found */
- return (-1);
+ return -1;
}
return 0;
}
if (success == 0)
- return (-1);
- return (0);
+ return -1;
+ return 0;
} /* int tss2_read */
static int tss2_shutdown(void) {
sfree(config_host);
sfree(config_port);
- return (0);
+ return 0;
} /* int tss2_shutdown */
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 : */
#include "common.h"
#include "plugin.h"
-#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H && HAVE_MATH_H
-#include <math.h>
+#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#include <termios.h>
#else
status = write(fd, pkt_request, sizeof(pkt_request));
if (status <= 0) {
- ERROR("ted plugin: swrite failed.");
- return (-1);
+ ERROR("ted plugin: write failed.");
+ return -1;
}
/* Loop until we find the end of the package */
{
WARNING("ted plugin: Timeout while waiting for file descriptor "
"to become ready.");
- return (-1);
+ return -1;
} else if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) {
/* Some signal or something. Start over.. */
continue;
char errbuf[1024];
ERROR("ted plugin: select failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
receive_buffer_length = read(fd, receive_buffer, sizeof(receive_buffer));
continue;
ERROR("ted plugin: read(2) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
} else if (receive_buffer_length == 0) {
/* Should we close the FD in this case? */
WARNING("ted plugin: Received EOF from file descriptor.");
- return (-1);
+ return -1;
} else if (((size_t)receive_buffer_length) > sizeof(receive_buffer)) {
ERROR("ted plugin: read(2) returned invalid value %zi.",
receive_buffer_length);
- return (-1);
+ return -1;
}
/*
/* Check for errors inside the loop. */
if ((end_flag == 0) || (package_buffer_pos != EXPECTED_PACKAGE_LENGTH))
- return (-1);
+ return -1;
/*
* Power is at positions 247 and 248 (LSB first) in [10kW].
((int)package_buffer[251]));
/* success */
- return (0);
+ return 0;
} /* int ted_read_value */
static int ted_open_device(void) {
struct termios options;
if (fd >= 0)
- return (0);
+ return 0;
dev = DEFAULT_DEVICE;
if (conf_device != NULL)
fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
if (fd < 0) {
ERROR("ted plugin: Unable to open device %s.", dev);
- return (-1);
+ return -1;
}
/* Get the current options for the port... */
tcsetattr(fd, TCSANOW, &options);
INFO("ted plugin: Successfully opened %s.", dev);
- return (0);
+ return 0;
} /* int ted_open_device */
static void ted_submit(const char *type, double value) {
tmp = atoi(value);
if (tmp < 0) {
WARNING("ted plugin: Invalid retry count: %i", tmp);
- return (1);
+ return 1;
}
conf_retries = tmp;
} else {
ERROR("ted plugin: Unknown config option: %s", key);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int ted_config */
static int ted_read(void) {
status = ted_open_device();
if (status != 0)
- return (-1);
+ return -1;
power = NAN;
voltage = NAN;
}
if (status != 0)
- return (-1);
+ return -1;
ted_submit("power", power);
ted_submit("voltage", voltage);
- return (0);
+ return 0;
} /* int ted_read */
static int ted_shutdown(void) {
fd = -1;
}
- return (0);
+ return 0;
} /* int ted_shutdown */
void module_register(void) {
plugin_register_read("ted", ted_read);
plugin_register_shutdown("ted", ted_shutdown);
} /* void module_register */
-
-/* vim: set sw=4 et : */
if (strcmp(expect, got__) != 0) { \
printf("not ok %i - %s = \"%s\", want \"%s\"\n", ++check_count__, \
#actual, got__, expect); \
- return (-1); \
+ return -1; \
} \
printf("ok %i - %s = \"%s\"\n", ++check_count__, #actual, got__); \
} while (0)
if (got__ != want__) { \
printf("not ok %i - %s = %d, want %d\n", ++check_count__, #actual, \
got__, want__); \
- return (-1); \
+ return -1; \
} \
printf("ok %i - %s = %d\n", ++check_count__, #actual, got__); \
} while (0)
if (got__ != want__) { \
printf("not ok %i - %s = %" PRIu64 ", want %" PRIu64 "\n", \
++check_count__, #actual, got__, want__); \
- return (-1); \
+ return -1; \
} \
printf("ok %i - %s = %" PRIu64 "\n", ++check_count__, #actual, got__); \
} while (0)
do { \
double want__ = (double)expect; \
double got__ = (double)actual; \
- if (isnan(want__) && !isnan(got__)) { \
+ if ((isnan(want__) && !isnan(got__)) || \
+ (!isnan(want__) && isnan(got__))) { \
printf("not ok %i - %s = %.15g, want %.15g\n", ++check_count__, #actual, \
got__, want__); \
- return (-1); \
+ return -1; \
} else if (!isnan(want__) && (((want__ - got__) < -DBL_PRECISION) || \
((want__ - got__) > DBL_PRECISION))) { \
printf("not ok %i - %s = %.15g, want %.15g\n", ++check_count__, #actual, \
got__, want__); \
- return (-1); \
+ return -1; \
} \
printf("ok %i - %s = %.15g\n", ++check_count__, #actual, got__); \
} while (0)
if (device_list && ignorelist_match(device_list, name))
return -1;
- ssnprintf(filename, sizeof(filename), "%s/%s/temp", dirname_sysfs, name);
+ snprintf(filename, sizeof(filename), "%s/%s/temp", dirname_sysfs, name);
if (parse_value_file(filename, &value, DS_TYPE_GAUGE) == 0) {
value.gauge /= 1000.0;
thermal_submit(name, TEMP, value);
success = 1;
}
- ssnprintf(filename, sizeof(filename), "%s/%s/cur_state", dirname_sysfs, name);
+ snprintf(filename, sizeof(filename), "%s/%s/cur_state", dirname_sysfs, name);
if (parse_value_file(filename, &value, DS_TYPE_GAUGE) == 0) {
thermal_submit(name, COOLING_DEV, value);
success = 1;
}
- return (success ? 0 : -1);
+ return success ? 0 : -1;
}
static int thermal_procfs_device_read(const char __attribute__((unused)) * dir,
* temperature: 55 C
*/
- len = ssnprintf(filename, sizeof(filename), "%s/%s/temperature",
- dirname_procfs, name);
+ len = snprintf(filename, sizeof(filename), "%s/%s/temperature",
+ dirname_procfs, name);
if ((len < 0) || ((size_t)len >= sizeof(filename)))
return -1;
}
static int thermal_sysfs_read(void) {
- return walk_directory(dirname_sysfs, thermal_sysfs_device_read,
- /* user_data = */ NULL, /* include hidden */ 0);
+ return walk_directory(dirname_sysfs, thermal_sysfs_device_read, NULL, 0);
}
static int thermal_procfs_read(void) {
- return walk_directory(dirname_procfs, thermal_procfs_device_read,
- /* user_data = */ NULL, /* include hidden */ 0);
+ return walk_directory(dirname_procfs, thermal_procfs_device_read, NULL, 0);
}
static int thermal_init(void) {
if (format_name(name, sizeof(name), th->host, th->plugin, th->plugin_instance,
th->type, th->type_instance) != 0) {
ERROR("ut_threshold_add: format_name failed.");
- return (-1);
+ return -1;
}
name_copy = strdup(name);
if (name_copy == NULL) {
ERROR("ut_threshold_add: strdup failed.");
- return (-1);
+ return -1;
}
th_copy = malloc(sizeof(*th_copy));
if (th_copy == NULL) {
sfree(name_copy);
ERROR("ut_threshold_add: malloc failed.");
- return (-1);
+ return -1;
}
memcpy(th_copy, th, sizeof(threshold_t));
sfree(th_copy);
}
- return (status);
+ return status;
} /* }}} int ut_threshold_add */
/*
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("threshold values: The `DataSource' option needs exactly one "
"string argument.");
- return (-1);
+ return -1;
}
sstrncpy(th->data_source, ci->values[0].value.string,
sizeof(th->data_source));
- return (0);
+ return 0;
} /* int ut_config_type_datasource */
static int ut_config_type_instance(threshold_t *th, oconfig_item_t *ci) {
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("threshold values: The `Instance' option needs exactly one "
"string argument.");
- return (-1);
+ return -1;
}
sstrncpy(th->type_instance, ci->values[0].value.string,
sizeof(th->type_instance));
- return (0);
+ return 0;
} /* int ut_config_type_instance */
static int ut_config_type_max(threshold_t *th, oconfig_item_t *ci) {
WARNING("threshold values: The `%s' option needs exactly one "
"number argument.",
ci->key);
- return (-1);
+ return -1;
}
if (strcasecmp(ci->key, "WarningMax") == 0)
else
th->failure_max = ci->values[0].value.number;
- return (0);
+ return 0;
} /* int ut_config_type_max */
static int ut_config_type_min(threshold_t *th, oconfig_item_t *ci) {
WARNING("threshold values: The `%s' option needs exactly one "
"number argument.",
ci->key);
- return (-1);
+ return -1;
}
if (strcasecmp(ci->key, "WarningMin") == 0)
else
th->failure_min = ci->values[0].value.number;
- return (0);
+ return 0;
} /* int ut_config_type_min */
static int ut_config_type_hits(threshold_t *th, oconfig_item_t *ci) {
WARNING("threshold values: The `%s' option needs exactly one "
"number argument.",
ci->key);
- return (-1);
+ return -1;
}
th->hits = ci->values[0].value.number;
- return (0);
+ return 0;
} /* int ut_config_type_hits */
static int ut_config_type_hysteresis(threshold_t *th, oconfig_item_t *ci) {
WARNING("threshold values: The `%s' option needs exactly one "
"number argument.",
ci->key);
- return (-1);
+ return -1;
}
th->hysteresis = ci->values[0].value.number;
- return (0);
+ return 0;
} /* int ut_config_type_hysteresis */
static int ut_config_type(const threshold_t *th_orig, oconfig_item_t *ci) {
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("threshold values: The `Type' block needs exactly one string "
"argument.");
- return (-1);
+ return -1;
}
if (ci->children_num < 1) {
WARNING("threshold values: The `Type' block needs at least one option.");
- return (-1);
+ return -1;
}
memcpy(&th, th_orig, sizeof(th));
status = ut_threshold_add(&th);
}
- return (status);
+ return status;
} /* int ut_config_type */
static int ut_config_plugin_instance(threshold_t *th, oconfig_item_t *ci) {
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("threshold values: The `Instance' option needs exactly one "
"string argument.");
- return (-1);
+ return -1;
}
sstrncpy(th->plugin_instance, ci->values[0].value.string,
sizeof(th->plugin_instance));
- return (0);
+ return 0;
} /* int ut_config_plugin_instance */
static int ut_config_plugin(const threshold_t *th_orig, oconfig_item_t *ci) {
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("threshold values: The `Plugin' block needs exactly one string "
"argument.");
- return (-1);
+ return -1;
}
if (ci->children_num < 1) {
WARNING("threshold values: The `Plugin' block needs at least one nested "
"block.");
- return (-1);
+ return -1;
}
memcpy(&th, th_orig, sizeof(th));
break;
}
- return (status);
+ return status;
} /* int ut_config_plugin */
static int ut_config_host(const threshold_t *th_orig, oconfig_item_t *ci) {
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("threshold values: The `Host' block needs exactly one string "
"argument.");
- return (-1);
+ return -1;
}
if (ci->children_num < 1) {
WARNING("threshold values: The `Host' block needs at least one nested "
"block.");
- return (-1);
+ return -1;
}
memcpy(&th, th_orig, sizeof(th));
break;
}
- return (status);
+ return status;
} /* int ut_config_host */
- /*
- * End of the functions used to configure threshold values.
- */
+/*
+ * End of the functions used to configure threshold values.
+ */
/* }}} */
/*
DEBUG("ut_report_state: th->hits = %d, uc_get_hits = %d", th->hits,
uc_get_hits(ds, vl));
(void)uc_inc_hits(ds, vl, 1); /* increase hit counter */
- return (0);
+ return 0;
}
} /* end check hits */
* state is `okay', then only report if `persist_ok` flag is set. */
if (state == state_old) {
if ((th->flags & UT_FLAG_PERSIST) == 0)
- return (0);
+ return 0;
else if ((state == STATE_OKAY) && ((th->flags & UT_FLAG_PERSIST_OK) == 0))
- return (0);
+ return 0;
}
if (state != state_old)
n.time = vl->time;
- status = ssnprintf(buf, bufsize, "Host %s, plugin %s", vl->host, vl->plugin);
+ status = snprintf(buf, bufsize, "Host %s, plugin %s", vl->host, vl->plugin);
buf += status;
bufsize -= status;
if (vl->plugin_instance[0] != '\0') {
- status = ssnprintf(buf, bufsize, " (instance %s)", vl->plugin_instance);
+ status = snprintf(buf, bufsize, " (instance %s)", vl->plugin_instance);
buf += status;
bufsize -= status;
}
- status = ssnprintf(buf, bufsize, " type %s", vl->type);
+ status = snprintf(buf, bufsize, " type %s", vl->type);
buf += status;
bufsize -= status;
if (vl->type_instance[0] != '\0') {
- status = ssnprintf(buf, bufsize, " (instance %s)", vl->type_instance);
+ status = snprintf(buf, bufsize, " (instance %s)", vl->type_instance);
buf += status;
bufsize -= status;
}
/* Send an okay notification */
if (state == STATE_OKAY) {
if (state_old == STATE_MISSING)
- ssnprintf(buf, bufsize, ": Value is no longer missing.");
+ snprintf(buf, bufsize, ": Value is no longer missing.");
else
- ssnprintf(buf, bufsize, ": All data sources are within range again. "
- "Current value of \"%s\" is %f.",
- ds->ds[ds_index].name, values[ds_index]);
+ snprintf(buf, bufsize, ": All data sources are within range again. "
+ "Current value of \"%s\" is %f.",
+ ds->ds[ds_index].name, values[ds_index]);
} else {
double min;
double max;
if (th->flags & UT_FLAG_INVERT) {
if (!isnan(min) && !isnan(max)) {
- ssnprintf(buf, bufsize,
- ": Data source \"%s\" is currently "
- "%f. That is within the %s region of %f%s and %f%s.",
- ds->ds[ds_index].name, values[ds_index],
- (state == STATE_ERROR) ? "failure" : "warning", min,
- ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "", max,
- ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
+ snprintf(buf, bufsize,
+ ": Data source \"%s\" is currently "
+ "%f. That is within the %s region of %f%s and %f%s.",
+ ds->ds[ds_index].name, values[ds_index],
+ (state == STATE_ERROR) ? "failure" : "warning", min,
+ ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "", max,
+ ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
} else {
- ssnprintf(buf, bufsize, ": Data source \"%s\" is currently "
- "%f. That is %s the %s threshold of %f%s.",
- ds->ds[ds_index].name, values[ds_index],
- isnan(min) ? "below" : "above",
- (state == STATE_ERROR) ? "failure" : "warning",
- isnan(min) ? max : min,
- ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
+ snprintf(buf, bufsize, ": Data source \"%s\" is currently "
+ "%f. That is %s the %s threshold of %f%s.",
+ ds->ds[ds_index].name, values[ds_index],
+ isnan(min) ? "below" : "above",
+ (state == STATE_ERROR) ? "failure" : "warning",
+ isnan(min) ? max : min,
+ ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
}
} else if (th->flags & UT_FLAG_PERCENTAGE) {
gauge_t value;
else
value = 100.0 * values[ds_index] / sum;
- ssnprintf(buf, bufsize,
- ": Data source \"%s\" is currently "
- "%g (%.2f%%). That is %s the %s threshold of %.2f%%.",
- ds->ds[ds_index].name, values[ds_index], value,
- (value < min) ? "below" : "above",
- (state == STATE_ERROR) ? "failure" : "warning",
- (value < min) ? min : max);
+ snprintf(buf, bufsize,
+ ": Data source \"%s\" is currently "
+ "%g (%.2f%%). That is %s the %s threshold of %.2f%%.",
+ ds->ds[ds_index].name, values[ds_index], value,
+ (value < min) ? "below" : "above",
+ (state == STATE_ERROR) ? "failure" : "warning",
+ (value < min) ? min : max);
} else /* is not inverted */
{
- ssnprintf(buf, bufsize, ": Data source \"%s\" is currently "
- "%f. That is %s the %s threshold of %f.",
- ds->ds[ds_index].name, values[ds_index],
- (values[ds_index] < min) ? "below" : "above",
- (state == STATE_ERROR) ? "failure" : "warning",
- (values[ds_index] < min) ? min : max);
+ snprintf(buf, bufsize, ": Data source \"%s\" is currently "
+ "%f. That is %s the %s threshold of %f.",
+ ds->ds[ds_index].name, values[ds_index],
+ (values[ds_index] < min) ? "below" : "above",
+ (state == STATE_ERROR) ? "failure" : "warning",
+ (values[ds_index] < min) ? min : max);
}
}
plugin_dispatch_notification(&n);
plugin_notification_meta_free(n.meta);
- return (0);
+ return 0;
} /* }}} int ut_report_state */
/*
if (ds != NULL) {
ds_name = ds->ds[ds_index].name;
if ((th->data_source[0] != 0) && (strcmp(ds_name, th->data_source) != 0))
- return (STATE_OKAY);
+ return STATE_OKAY;
}
if ((th->flags & UT_FLAG_INVERT) != 0) {
}
if (is_failure != 0)
- return (STATE_ERROR);
+ return STATE_ERROR;
if (is_warning != 0)
- return (STATE_WARNING);
+ return STATE_WARNING;
- return (STATE_OKAY);
+ return STATE_OKAY;
} /* }}} int ut_check_one_data_source */
/*
if (ret_ds_index != NULL)
*ret_ds_index = ds_index;
- return (ret);
+ return ret;
} /* }}} int ut_check_one_threshold */
/*
int worst_ds_index = -1;
if (threshold_tree == NULL)
- return (0);
+ return 0;
/* Is this lock really necessary? So far, thresholds are only inserted at
* startup. -octo */
th = threshold_search(vl);
pthread_mutex_unlock(&threshold_lock);
if (th == NULL)
- return (0);
+ return 0;
DEBUG("ut_check_threshold: Found matching threshold(s)");
values = uc_get_rate(ds, vl);
if (values == NULL)
- return (0);
+ return 0;
while (th != NULL) {
int ds_index = -1;
if (status < 0) {
ERROR("ut_check_threshold: ut_check_one_threshold failed.");
sfree(values);
- return (-1);
+ return -1;
}
if (worst_state < status) {
if (status != 0) {
ERROR("ut_check_threshold: ut_report_state failed.");
sfree(values);
- return (-1);
+ return -1;
}
sfree(values);
- return (0);
+ return 0;
} /* }}} int ut_check_threshold */
/*
cdtime_t now;
if (threshold_tree == NULL)
- return (0);
+ return 0;
th = threshold_search(vl);
/* dispatch notifications for "interesting" values only */
if ((th == NULL) || ((th->flags & UT_FLAG_INTERESTING) == 0))
- return (0);
+ return 0;
now = cdtime();
missing_time = now - vl->time;
FORMAT_VL(identifier, sizeof(identifier), vl);
NOTIFICATION_INIT_VL(&n, vl);
- ssnprintf(n.message, sizeof(n.message),
- "%s has not been updated for %.3f seconds.", identifier,
- CDTIME_T_TO_DOUBLE(missing_time));
+ snprintf(n.message, sizeof(n.message),
+ "%s has not been updated for %.3f seconds.", identifier,
+ CDTIME_T_TO_DOUBLE(missing_time));
n.time = now;
plugin_dispatch_notification(&n);
- return (0);
+ return 0;
} /* }}} int ut_missing */
static int ut_config(oconfig_item_t *ci) { /* {{{ */
threshold_tree = c_avl_create((int (*)(const void *, const void *))strcmp);
if (threshold_tree == NULL) {
ERROR("ut_config: c_avl_create failed.");
- return (-1);
+ return -1;
}
}
/* user data = */ NULL);
}
- return (status);
+ return status;
} /* }}} int um_config */
void module_register(void) {
plugin_register_complex_config("threshold", ut_config);
}
-
-/* vim: set sw=2 ts=8 sts=2 tw=78 et fdm=marker : */
temp = strdup(value);
if (temp == NULL) {
ERROR("tokyotyrant plugin: Host strdup failed.");
- return (1);
+ return 1;
}
sfree(config_host);
config_host = temp;
temp = strdup(value);
if (temp == NULL) {
ERROR("tokyotyrant plugin: Port strdup failed.");
- return (1);
+ return 1;
}
sfree(config_port);
config_port = temp;
} else {
ERROR("tokyotyrant plugin: error: unrecognized configuration key %s", key);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
static void printerr(void) {
tt_open_db();
if (rdb == NULL)
- return (-1);
+ return -1;
rnum = tcrdbrnum(rdb);
tt_submit(rnum, "records");
size = tcrdbsize(rdb);
tt_submit(size, "file_size");
- return (0);
+ return 0;
}
static int tt_shutdown(void) {
if (!tcrdbclose(rdb)) {
printerr();
tcrdbdel(rdb);
- return (1);
+ return 1;
}
tcrdbdel(rdb);
rdb = NULL;
}
- return (0);
+ return 0;
}
void module_register(void) {
plugin_register_read("tokyotyrant", tt_read);
plugin_register_shutdown("tokyotyrant", tt_shutdown);
}
-
-/* vim: set sw=8 ts=8 tw=78 : */
}
}
- ssnprintf(pathname, sizeof(pathname), "/dev/cpu/%d/msr", cpu);
+ snprintf(pathname, sizeof(pathname), "/dev/cpu/%d/msr", cpu);
fd = open(pathname, O_RDONLY);
if (fd < 0) {
ERROR("turbostat plugin: failed to open %s", pathname);
DEBUG("turbostat plugin: submit stats for cpu: %d, core: %d, pkg: %d",
t->cpu_id, c->core_id, p->package_id);
- ssnprintf(name, sizeof(name), "cpu%02d", t->cpu_id);
+ snprintf(name, sizeof(name), "cpu%02d", t->cpu_id);
if (!aperf_mperf_unstable)
turbostat_submit(name, "percent", "c0", 100.0 * t->mperf / t->tsc);
/* If not using logical core numbering, set core id */
if (!config_lcn) {
- ssnprintf(name, sizeof(name), "core%02d", c->core_id);
+ if (topology.num_packages > 1)
+ snprintf(name, sizeof(name), "pkg%02d-core%02d", p->package_id, c->core_id);
+ else
+ snprintf(name, sizeof(name), "core%02d", c->core_id);
}
if (do_core_cstate & (1 << 3))
if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
goto done;
- ssnprintf(name, sizeof(name), "pkg%02d", p->package_id);
+ snprintf(name, sizeof(name), "pkg%02d", p->package_id);
if (do_ptm)
turbostat_submit(name, "temperature", NULL, p->pkg_temp_c);
int matches;
char character;
- ssnprintf(path, sizeof(path),
- "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu);
+ snprintf(path, sizeof(path),
+ "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", cpu);
filep = fopen(path, "r");
if (!filep) {
ERROR("turbostat plugin: Failed to open '%s'", path);
retval = func(cpu_num);
if (retval) {
fclose(fp);
- return (retval);
+ return retval;
}
}
fclose(fp);
clock_last_update value:GAUGE:U:U
clock_mode value:GAUGE:0:U
clock_reachability value:GAUGE:0:U
-clock_skew_ppm value:GAUGE:-2:2
+clock_skew_ppm value:GAUGE:0:1000000
clock_state value:GAUGE:0:U
clock_stratum value:GAUGE:0:U
compression uncompressed:DERIVE:0:U, compressed:DERIVE:0:U
connections value:DERIVE:0:U
conntrack value:GAUGE:0:4294967295
contextswitch value:DERIVE:0:U
+cookies 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
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
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
flow value:GAUGE:0:U
fork_rate value:DERIVE:0:U
frequency value:GAUGE:0:U
-frequency_error value:GAUGE:-2:2
+frequency_error value:GAUGE:-1000000:1000000
frequency_offset value:GAUGE:-1000000:1000000
fscache_stat value:DERIVE:0:U
gauge value:GAUGE:U:U
if_tx_packets value:DERIVE:0:U
invocations value:DERIVE:0:U
io_octets rx:DERIVE:0:U, tx:DERIVE:0:U
+io_ops read:DERIVE:0:U, write:DERIVE:0:U
io_packets rx:DERIVE:0:U, tx:DERIVE:0:U
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
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
ping_droprate value:GAUGE:0:100
ping_stddev value:GAUGE:0:65535
players value:GAUGE:0:1000000
+pools value:GAUGE:0:U
power value:GAUGE:U:U
pressure value:GAUGE:0:U
protocol_counter value:DERIVE:0:U
timeleft value:GAUGE:0:U
total_bytes value:DERIVE:0:U
total_connections value:DERIVE:0:U
+total_events value:DERIVE:0:U
total_objects value:DERIVE:0:U
total_operations value:DERIVE:0:U
total_requests value:DERIVE:0:U
char errbuf[1024];
ERROR("unixsock plugin: socket failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
sa.sun_family = AF_UNIX;
ERROR("unixsock plugin: bind failed: %s", errbuf);
close(sock_fd);
sock_fd = -1;
- return (-1);
+ return -1;
}
status = chmod(sa.sun_path, sock_perms);
sstrerror(errno, errbuf, sizeof(errbuf)));
close(sock_fd);
sock_fd = -1;
- return (-1);
+ return -1;
}
status = listen(sock_fd, 8);
sstrerror(errno, errbuf, sizeof(errbuf)));
close(sock_fd);
sock_fd = -1;
- return (-1);
+ return -1;
}
do {
}
} while (0);
- return (0);
+ return 0;
} /* int us_open_socket */
static void *us_handle_client(void *arg) {
close(fdin);
close(fdout);
pthread_exit((void *)1);
- return ((void *)1);
+ return (void *)1;
}
fhout = fdopen(fdout, "w");
fclose(fhin); /* this closes fdin as well */
close(fdout);
pthread_exit((void *)1);
- return ((void *)1);
+ return (void *)1;
}
/* change output buffer to line buffered mode */
fclose(fhin);
fclose(fhout);
pthread_exit((void *)1);
- return ((void *)0);
+ return (void *)0;
}
while (42) {
fclose(fhin);
fclose(fhout);
pthread_exit((void *)1);
- return ((void *)1);
+ return (void *)1;
}
if (strcasecmp(fields[0], "getval") == 0) {
fclose(fhout);
pthread_exit((void *)0);
- return ((void *)0);
+ return (void *)0;
} /* void *us_handle_client */
static void *us_server_thread(void __attribute__((unused)) * arg) {
sstrerror(errno, errbuf, sizeof(errbuf)));
}
- return ((void *)0);
+ return (void *)0;
} /* void *us_server_thread */
static int us_config(const char *key, const char *val) {
if (strcasecmp(key, "SocketFile") == 0) {
char *new_sock_file = strdup(val);
if (new_sock_file == NULL)
- return (1);
+ return 1;
sfree(sock_file);
sock_file = new_sock_file;
} else if (strcasecmp(key, "SocketGroup") == 0) {
char *new_sock_group = strdup(val);
if (new_sock_group == NULL)
- return (1);
+ return 1;
sfree(sock_group);
sock_group = new_sock_group;
else
delete_socket = 0;
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int us_config */
static int us_init(void) {
/* Initialize only once. */
if (have_init != 0)
- return (0);
+ return 0;
have_init = 1;
loop = 1;
char errbuf[1024];
ERROR("unixsock plugin: pthread_create failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int us_init */
static int us_shutdown(void) {
plugin_unregister_init("unixsock");
plugin_unregister_shutdown("unixsock");
- return (0);
+ return 0;
} /* int us_shutdown */
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 : */
#include "plugin.h"
#if KERNEL_LINUX
-#define STAT_FILE "/proc/stat"
-/* Using /proc filesystem to retrieve the boot time, Linux only. */
+#include <sys/sysinfo.h>
/* #endif KERNEL_LINUX */
#elif HAVE_LIBKSTAT
/*
* Global variables
*/
-/* boottime always used, no OS distinction */
-static time_t boottime;
#if HAVE_LIBKSTAT
extern kstat_ctl_t *kc;
plugin_dispatch_values(&vl);
}
-static int uptime_init(void) /* {{{ */
-{
/*
* On most unix systems the uptime is calculated by looking at the boot
* time (stored in unix time, since epoch) and the current one. We are
* the boot time, the plugin is unregistered and there is no chance to
* try again later. Nevertheless, this is very unlikely to happen.
*/
-
+static time_t uptime_get_sys(void) { /* {{{ */
+ time_t result;
#if KERNEL_LINUX
- unsigned long starttime;
- char buffer[1024];
- int ret;
- FILE *fh;
-
- ret = 0;
-
- fh = fopen(STAT_FILE, "r");
+ struct sysinfo info;
+ int status;
- if (fh == NULL) {
+ status = sysinfo(&info);
+ if (status != 0) {
char errbuf[1024];
- ERROR("uptime plugin: Cannot open " STAT_FILE ": %s",
+ ERROR("uptime plugin: Error calling sysinfo: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
- while (fgets(buffer, 1024, fh) != NULL) {
- /* look for the btime string and read the value */
- ret = sscanf(buffer, "btime %lu", &starttime);
- /* avoid further loops if btime has been found and read
- * correctly (hopefully) */
- if (ret == 1)
- break;
- }
-
- fclose(fh);
-
- /* loop done, check if no value has been found/read */
- if (ret != 1) {
- ERROR("uptime plugin: No value read from " STAT_FILE "");
- return (-1);
- }
-
- boottime = (time_t)starttime;
-
- if (boottime == 0) {
- ERROR("uptime plugin: btime read from " STAT_FILE ", "
- "but `boottime' is zero!");
- return (-1);
- }
+ result = (time_t)info.uptime;
/* #endif KERNEL_LINUX */
#elif HAVE_LIBKSTAT
* went fine. */
if (kc == NULL) {
ERROR("uptime plugin: kstat chain control structure not available.");
- return (-1);
+ return -1;
}
ksp = kstat_lookup(kc, "unix", 0, "system_misc");
if (ksp == NULL) {
ERROR("uptime plugin: Cannot find unix:0:system_misc kstat.");
- return (-1);
+ return -1;
}
if (kstat_read(kc, ksp, NULL) < 0) {
ERROR("uptime plugin: kstat_read failed.");
- return (-1);
+ return -1;
}
knp = (kstat_named_t *)kstat_data_lookup(ksp, "boot_time");
if (knp == NULL) {
ERROR("uptime plugin: kstat_data_lookup (boot_time) failed.");
- return (-1);
+ return -1;
}
- boottime = (time_t)knp->value.ui32;
-
- if (boottime == 0) {
+ if (knp->value.ui32 == 0) {
ERROR("uptime plugin: kstat_data_lookup returned success, "
"but `boottime' is zero!");
- return (-1);
+ return -1;
}
+
+ result = time(NULL) - (time_t)knp->value.ui32;
/* #endif HAVE_LIBKSTAT */
#elif HAVE_SYS_SYSCTL_H
char errbuf[1024];
ERROR("uptime plugin: No value read from sysctl interface: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
- boottime = boottv.tv_sec;
-
- if (boottime == 0) {
+ if (boottv.tv_sec == 0) {
ERROR("uptime plugin: sysctl(3) returned success, "
"but `boottime' is zero!");
- return (-1);
+ return -1;
}
+
+ result = time(NULL) - boottv.tv_sec;
/* #endif HAVE_SYS_SYSCTL_H */
#elif HAVE_PERFSTAT
char errbuf[1024];
ERROR("uptime plugin: perfstat_cpu_total: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
hertz = sysconf(_SC_CLK_TCK);
if (hertz <= 0)
hertz = HZ;
- boottime = time(NULL) - cputotal.lbolt / hertz;
+ result = cputotal.lbolt / hertz;
#endif /* HAVE_PERFSTAT */
- return (0);
-} /* }}} int uptime_init */
+ return result;
+} /* }}} int uptime_get_sys */
static int uptime_read(void) {
gauge_t uptime;
time_t elapsed;
/* calculate the amount of time elapsed since boot, AKA uptime */
- elapsed = time(NULL) - boottime;
+ elapsed = uptime_get_sys();
uptime = (gauge_t)elapsed;
uptime_submit(uptime);
- return (0);
+ return 0;
}
void module_register(void) {
- plugin_register_init("uptime", uptime_init);
plugin_register_read("uptime", uptime_read);
} /* void module_register */
us = sg_get_user_stats();
#endif
if (us == NULL)
- return (-1);
+ return -1;
users_submit((gauge_t)
#if HAVE_LIBSTATGRAB_0_90
#error "No applicable input method."
#endif
- return (0);
+ return 0;
} /* int users_read */
void module_register(void) {
if ((ret_flush == NULL) || (opts == NULL)) {
errno = EINVAL;
cmd_error(CMD_ERROR, err, "Invalid arguments to cmd_parse_flush.");
- return (CMD_ERROR);
+ return CMD_ERROR;
}
for (size_t i = 0; i < argc; i++) {
if (status == CMD_NO_OPTION)
cmd_error(CMD_PARSE_ERROR, err, "Invalid option string `%s'.", argv[i]);
cmd_destroy_flush(ret_flush);
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
}
if (strcasecmp("plugin", opt_key) == 0) {
if (id == NULL) {
cmd_error(CMD_ERROR, err, "realloc failed.");
cmd_destroy_flush(ret_flush);
- return (CMD_ERROR);
+ return CMD_ERROR;
}
ret_flush->identifiers = id;
opts->identifier_default_host) != 0) {
cmd_error(CMD_PARSE_ERROR, err, "Invalid identifier `%s'.", opt_value);
cmd_destroy_flush(ret_flush);
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
}
} else if (strcasecmp("timeout", opt_key) == 0) {
char *endptr;
cmd_error(CMD_PARSE_ERROR, err,
"Invalid value for option `timeout': %s", opt_value);
cmd_destroy_flush(ret_flush);
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
} else if (ret_flush->timeout < 0.0) {
ret_flush->timeout = 0.0;
}
} else {
cmd_error(CMD_PARSE_ERROR, err, "Cannot parse option `%s'.", opt_key);
cmd_destroy_flush(ret_flush);
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
}
}
- return (CMD_OK);
+ return CMD_OK;
} /* cmd_status_t cmd_parse_flush */
cmd_status_t cmd_handle_flush(FILE *fh, char *buffer) {
int status;
if ((fh == NULL) || (buffer == NULL))
- return (-1);
+ return -1;
DEBUG("utils_cmd_flush: cmd_handle_flush (fh = %p, buffer = %s);", (void *)fh,
buffer);
if ((status = cmd_parse(buffer, &cmd, NULL, &err)) != CMD_OK)
- return (status);
+ return status;
if (cmd.type != CMD_FLUSH) {
cmd_error(CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.",
CMD_TO_STRING(cmd.type));
cmd_destroy(&cmd);
- return (CMD_UNKNOWN_COMMAND);
+ return CMD_UNKNOWN_COMMAND;
}
for (size_t i = 0; (i == 0) || (i < cmd.cmd.flush.plugins_num); i++) {
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++;
cmd_error(CMD_OK, &err, "Done: %i successful, %i errors", success, error);
cmd_destroy(&cmd);
- return (0);
+ return 0;
#undef PRINT_TO_SOCK
} /* cmd_status_t cmd_handle_flush */
sfree(flush->identifiers);
flush->identifiers_num = 0;
} /* void cmd_destroy_flush */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
void cmd_destroy_flush(cmd_flush_t *flush);
#endif /* UTILS_CMD_FLUSH_H */
-
-/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
size_t i;
if ((fh == NULL) || (buffer == NULL))
- return (-1);
+ return -1;
DEBUG("utils_cmd_getthreshold: handle_getthreshold (fh = %p, buffer = %s);",
(void *)fh, buffer);
status = parse_string(&buffer, &command);
if (status != 0) {
print_to_socket(fh, "-1 Cannot parse command.\n");
- return (-1);
+ return -1;
}
assert(command != NULL);
if (strcasecmp("GETTHRESHOLD", command) != 0) {
print_to_socket(fh, "-1 Unexpected command: `%s'.\n", command);
- return (-1);
+ return -1;
}
identifier = NULL;
status = parse_string(&buffer, &identifier);
if (status != 0) {
print_to_socket(fh, "-1 Cannot parse identifier.\n");
- return (-1);
+ return -1;
}
assert(identifier != NULL);
if (*buffer != 0) {
print_to_socket(fh, "-1 Garbage after end of command: %s\n", buffer);
- return (-1);
+ return -1;
}
/* parse_identifier() modifies its first argument,
DEBUG("handle_getthreshold: Cannot parse identifier `%s'.", identifier);
print_to_socket(fh, "-1 Cannot parse identifier `%s'.\n", identifier);
sfree(identifier_copy);
- return (-1);
+ return -1;
}
value_list_t vl = {.values = NULL};
if (status == ENOENT) {
print_to_socket(fh, "-1 No threshold found for identifier %s\n",
identifier);
- return (0);
+ return 0;
} else if (status != 0) {
print_to_socket(fh, "-1 Error while looking up threshold: %i\n", status);
- return (-1);
+ return -1;
}
/* Lets count the number of lines we'll return. */
if (threshold.hits > 1)
print_to_socket(fh, "Hits: %i\n", threshold.hits);
- return (0);
+ return 0;
} /* int handle_getthreshold */
-
-/* vim: set sw=2 sts=2 ts=8 et : */
int handle_getthreshold(FILE *fh, char *buffer);
#endif /* UTILS_CMD_GETTHRESHOLD_H */
-
-/* vim: set sw=2 sts=2 ts=8 : */
if ((ret_getval == NULL) || (opts == NULL)) {
errno = EINVAL;
cmd_error(CMD_ERROR, err, "Invalid arguments to cmd_parse_getval.");
- return (CMD_ERROR);
+ return CMD_ERROR;
}
if (argc != 1) {
else
cmd_error(CMD_PARSE_ERROR, err, "Garbage after identifier: `%s'.",
argv[1]);
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
}
/* parse_identifier() modifies its first argument,
cmd_error(CMD_PARSE_ERROR, err, "Cannot parse identifier `%s'.",
identifier_copy);
sfree(identifier_copy);
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
}
ret_getval->raw_identifier = identifier_copy;
- return (CMD_OK);
+ return CMD_OK;
} /* cmd_status_t cmd_parse_getval */
#define print_to_socket(fh, ...) \
const data_set_t *ds;
if ((fh == NULL) || (buffer == NULL))
- return (-1);
+ return -1;
DEBUG("utils_cmd_getval: cmd_handle_getval (fh = %p, buffer = %s);",
(void *)fh, buffer);
if ((status = cmd_parse(buffer, &cmd, NULL, &err)) != CMD_OK)
- return (status);
+ return status;
if (cmd.type != CMD_GETVAL) {
cmd_error(CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.",
CMD_TO_STRING(cmd.type));
cmd_destroy(&cmd);
- return (CMD_UNKNOWN_COMMAND);
+ return CMD_UNKNOWN_COMMAND;
}
ds = plugin_get_ds(cmd.cmd.getval.identifier.type);
cmd_error(CMD_ERROR, &err, "Type `%s' is unknown.\n",
cmd.cmd.getval.identifier.type);
cmd_destroy(&cmd);
- return (-1);
+ return -1;
}
values = NULL;
if (status != 0) {
cmd_error(CMD_ERROR, &err, "No such value.");
cmd_destroy(&cmd);
- return (CMD_ERROR);
+ return CMD_ERROR;
}
if (ds->ds_num != values_num) {
cmd_error(CMD_ERROR, &err, "Error reading value from cache.");
sfree(values);
cmd_destroy(&cmd);
- return (CMD_ERROR);
+ return CMD_ERROR;
}
print_to_socket(fh, "%zu Value%s found\n", values_num,
sfree(values);
cmd_destroy(&cmd);
- return (CMD_OK);
+ return CMD_OK;
} /* cmd_status_t cmd_handle_getval */
void cmd_destroy_getval(cmd_getval_t *getval) {
sfree(getval->raw_identifier);
} /* void cmd_destroy_getval */
-
-/* vim: set sw=2 sts=2 ts=8 : */
void cmd_destroy_getval(cmd_getval_t *getval);
#endif /* UTILS_CMD_GETVAL_H */
-
-/* vim: set sw=2 sts=2 ts=8 : */
if (argc != 0) {
cmd_error(CMD_PARSE_ERROR, err, "Garbage after end of command: `%s'.",
argv[0]);
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
}
- return (CMD_OK);
+ return CMD_OK;
} /* cmd_status_t cmd_parse_listval */
#define free_everything_and_return(status) \
} \
sfree(names); \
sfree(times); \
- return (status); \
+ return status; \
} while (0)
#define print_to_socket(fh, ...) \
buffer);
if ((status = cmd_parse(buffer, &cmd, NULL, &err)) != CMD_OK)
- return (status);
+ return status;
if (cmd.type != CMD_LISTVAL) {
cmd_error(CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.",
CMD_TO_STRING(cmd.type));
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 : */
void cmd_destroy_listval(cmd_listval_t *listval);
#endif /* UTILS_CMD_LISTVAL_H */
-
-/* vim: set sw=2 sts=2 ts=8 : */
else if (strcasecmp(value, "Okay") == 0)
n->severity = NOTIF_OKAY;
else
- return (-1);
+ return -1;
- return (0);
+ return 0;
} /* int set_option_severity */
static int set_option_time(notification_t *n, const char *value) {
|| (endptr == value) /* Invalid string */
|| (endptr == NULL) /* This should not happen */
|| (*endptr != 0)) /* Trailing chars */
- return (-1);
+ return -1;
n->time = DOUBLE_TO_CDTIME_T(tmp);
- return (0);
+ return 0;
} /* int set_option_time */
static int set_option(notification_t *n, const char *option,
const char *value) {
if ((n == NULL) || (option == NULL) || (value == NULL))
- return (-1);
+ return -1;
DEBUG("utils_cmd_putnotif: set_option (option = %s, value = %s);", option,
value);
if (option[0] != '\0' && option[1] == ':') {
/* Refuse empty key */
if (option[2] == '\0')
- return (1);
+ return 1;
if (option[0] == 's')
return plugin_notification_meta_add_string(n, option + 2, value);
else
- return (1);
+ return 1;
}
if (strcasecmp("severity", option) == 0)
- return (set_option_severity(n, value));
+ return set_option_severity(n, value);
else if (strcasecmp("time", option) == 0)
- return (set_option_time(n, value));
+ return set_option_time(n, value);
else if (strcasecmp("message", option) == 0)
sstrncpy(n->message, value, sizeof(n->message));
else if (strcasecmp("host", option) == 0)
else if (strcasecmp("type_instance", option) == 0)
sstrncpy(n->type_instance, value, sizeof(n->type_instance));
else
- return (1);
+ return 1;
- return (0);
+ return 0;
} /* int set_option */
int handle_putnotif(FILE *fh, char *buffer) {
int status;
if ((fh == NULL) || (buffer == NULL))
- return (-1);
+ return -1;
DEBUG("utils_cmd_putnotif: handle_putnotif (fh = %p, buffer = %s);",
(void *)fh, buffer);
status = parse_string(&buffer, &command);
if (status != 0) {
print_to_socket(fh, "-1 Cannot parse command.\n");
- return (-1);
+ return -1;
}
assert(command != NULL);
if (strcasecmp("PUTNOTIF", command) != 0) {
print_to_socket(fh, "-1 Unexpected command: `%s'.\n", command);
- return (-1);
+ return -1;
}
status = 0;
print_to_socket(fh, "0 Success\n");
}
- return (0);
+ return 0;
} /* int handle_putnotif */
-
-/* vim: set shiftwidth=2 softtabstop=2 tabstop=8 : */
int handle_putnotif(FILE *fh, char *buffer);
-/* vim: set shiftwidth=2 softtabstop=2 tabstop=8 : */
-
#endif /* UTILS_CMD_PUTNOTIF_H */
static int set_option(value_list_t *vl, const char *key, const char *value) {
if ((vl == NULL) || (key == NULL) || (value == NULL))
- return (-1);
+ return -1;
if (strcasecmp("interval", key) == 0) {
double tmp;
if ((errno == 0) && (endptr != NULL) && (endptr != value) && (tmp > 0.0))
vl->interval = DOUBLE_TO_CDTIME_T(tmp);
} else
- return (1);
+ return 1;
- return (0);
+ return 0;
} /* int set_option */
/*
if ((ret_putval == NULL) || (opts == NULL)) {
errno = EINVAL;
cmd_error(CMD_ERROR, err, "Invalid arguments to cmd_parse_putval.");
- return (CMD_ERROR);
+ return CMD_ERROR;
}
if (argc < 2) {
cmd_error(CMD_PARSE_ERROR, err, "Missing identifier and/or value-list.");
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
}
identifier = argv[0];
cmd_error(CMD_PARSE_ERROR, err, "Cannot parse identifier `%s'.",
identifier_copy);
sfree(identifier_copy);
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
}
if ((strlen(hostname) >= sizeof(vl.host)) ||
(strlen(type_instance) >= sizeof(vl.type_instance)))) {
cmd_error(CMD_PARSE_ERROR, err, "Identifier too long.");
sfree(identifier_copy);
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
}
sstrncpy(vl.host, hostname, sizeof(vl.host));
if (ds == NULL) {
cmd_error(CMD_PARSE_ERROR, err, "1 Type `%s' isn't defined.", type);
sfree(identifier_copy);
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
}
hostname = NULL;
cmd_error(CMD_ERROR, err, "malloc failed.");
cmd_destroy_putval(ret_putval);
sfree(vl.values);
- return (CMD_ERROR);
+ return CMD_ERROR;
}
/* All the remaining fields are part of the option list. */
if (result != CMD_OK)
cmd_destroy_putval(ret_putval);
- return (result);
+ return result;
} /* cmd_status_t cmd_parse_putval */
void cmd_destroy_putval(cmd_putval_t *putval) {
(void *)fh, buffer);
if ((status = cmd_parse(buffer, &cmd, NULL, &err)) != CMD_OK)
- return (status);
+ return status;
if (cmd.type != CMD_PUTVAL) {
cmd_error(CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.",
CMD_TO_STRING(cmd.type));
cmd_destroy(&cmd);
- return (CMD_UNKNOWN_COMMAND);
+ return CMD_UNKNOWN_COMMAND;
}
for (size_t i = 0; i < cmd.cmd.putval.vl_num; ++i)
(cmd.cmd.putval.vl_num == 1) ? "value has" : "values have");
cmd_destroy(&cmd);
- return (CMD_OK);
+ return CMD_OK;
} /* int cmd_handle_putval */
int cmd_create_putval(char *ret, size_t ret_len, /* {{{ */
status = FORMAT_VL(buffer_ident, sizeof(buffer_ident), vl);
if (status != 0)
- return (status);
+ return status;
escape_string(buffer_ident, sizeof(buffer_ident));
status = format_values(buffer_values, sizeof(buffer_values), ds, vl,
/* store rates = */ 0);
if (status != 0)
- return (status);
+ return status;
escape_string(buffer_values, sizeof(buffer_values));
- ssnprintf(ret, ret_len, "PUTVAL %s interval=%.3f %s", buffer_ident,
- (vl->interval > 0) ? CDTIME_T_TO_DOUBLE(vl->interval)
- : CDTIME_T_TO_DOUBLE(plugin_get_interval()),
- buffer_values);
+ snprintf(ret, ret_len, "PUTVAL %s interval=%.3f %s", buffer_ident,
+ (vl->interval > 0) ? CDTIME_T_TO_DOUBLE(vl->interval)
+ : CDTIME_T_TO_DOUBLE(plugin_get_interval()),
+ buffer_values);
- return (0);
+ return 0;
} /* }}} int cmd_create_putval */
* Sebastian 'tokkee' Harl <sh at tokkee.org>
**/
+#include "utils_cmds.h"
#include "daemon/common.h"
#include "utils_cmd_flush.h"
#include "utils_cmd_getval.h"
#include "utils_cmd_listval.h"
#include "utils_cmd_putval.h"
-#include "utils_cmds.h"
#include "utils_parse_option.h"
#include <stdbool.h>
fields = malloc((estimate + 1) * sizeof(*fields));
if (fields == NULL) {
cmd_error(CMD_ERROR, err, "malloc failed.");
- return (CMD_ERROR);
+ return CMD_ERROR;
}
#define END_FIELD() \
if (string[1] == '\0') {
free(fields);
cmd_error(CMD_PARSE_ERROR, err, "Backslash at end of string.");
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
}
/* un-escape the next character; skip backslash */
if (in_quotes) {
free(fields);
cmd_error(CMD_PARSE_ERROR, err, "Unterminated quoted string.");
- return (CMD_PARSE_ERROR);
+ return CMD_PARSE_ERROR;
}
#undef NEW_FIELD
*ret_fields = fields;
else
free(fields);
- return (CMD_OK);
+ return CMD_OK;
} /* int cmd_split */
/*
} else {
ret_cmd->type = CMD_UNKNOWN;
cmd_error(CMD_UNKNOWN_COMMAND, err, "Unknown command `%s'.", command);
- return (CMD_UNKNOWN_COMMAND);
+ return CMD_UNKNOWN_COMMAND;
}
if (status != CMD_OK)
ret_cmd->type = CMD_UNKNOWN;
- return (status);
+ return status;
} /* cmd_status_t cmd_parsev */
cmd_status_t cmd_parse(char *buffer, cmd_t *ret_cmd, const cmd_options_t *opts,
status = cmd_parsev(fields_num, fields, ret_cmd, opts, err);
free(fields);
- return (status);
+ return status;
} /* cmd_status_t cmd_parse */
void cmd_destroy(cmd_t *cmd) {
if (field == NULL) {
errno = EINVAL;
cmd_error(CMD_ERROR, err, "Invalid argument to cmd_parse_option.");
- return (CMD_ERROR);
+ return CMD_ERROR;
}
key = value = field;
value++;
if ((value[0] != '=') || (value == key)) {
/* Whether this is a fatal error is up to the caller. */
- return (CMD_NO_OPTION);
+ return CMD_NO_OPTION;
}
*value = '\0';
value++;
if (ret_value != NULL)
*ret_value = value;
- return (CMD_OK);
+ return CMD_OK;
} /* cmd_status_t cmd_parse_option */
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 : */
free(input);
}
- return (test_result);
+ return test_result;
}
int main(int argc, char **argv) {
if (s == NULL)
return 0;
- if ((curl == NULL) || (hostname == NULL) || (plugin == NULL)) {
+ if ((curl == NULL) || (plugin == NULL)) {
ERROR("curl stats: dispatch() called with missing arguments "
- "(curl=%p; hostname=%s; plugin=%s)",
- curl, hostname == NULL ? "<NULL>" : hostname,
- plugin == NULL ? "<NULL>" : plugin);
+ "(curl=%p; plugin=%s)",
+ curl, plugin == NULL ? "<NULL>" : plugin);
return -1;
}
- sstrncpy(vl.host, hostname, sizeof(vl.host));
+ if (hostname != NULL)
+ sstrncpy(vl.host, hostname, sizeof(vl.host));
sstrncpy(vl.plugin, plugin, sizeof(vl.plugin));
if (plugin_instance != NULL)
sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance));
WARNING("db query utils: The `%s' config option "
"needs exactly one string argument.",
ci->key);
- return (-1);
+ return -1;
}
string = strdup(ci->values[0].value.string);
if (string == NULL) {
ERROR("db query utils: strdup failed.");
- return (-1);
+ return -1;
}
if (*ret_string != NULL)
free(*ret_string);
*ret_string = string;
- return (0);
+ return 0;
} /* }}} int udb_config_set_string */
static int udb_config_add_string(char ***ret_array, /* {{{ */
WARNING("db query utils: The `%s' config option "
"needs at least one argument.",
ci->key);
- return (-1);
+ return -1;
}
for (int i = 0; i < ci->values_num; i++) {
WARNING("db query utils: Argument %i to the `%s' option "
"is not a string.",
i + 1, ci->key);
- return (-1);
+ return -1;
}
}
array = realloc(*ret_array, sizeof(char *) * (array_len + ci->values_num));
if (array == NULL) {
ERROR("db query utils: realloc failed.");
- return (-1);
+ return -1;
}
*ret_array = array;
if (array[array_len] == NULL) {
ERROR("db query utils: strdup failed.");
*ret_array_len = array_len;
- return (-1);
+ return -1;
}
array_len++;
}
*ret_array_len = array_len;
- return (0);
+ return 0;
} /* }}} int udb_config_add_string */
static int udb_config_set_uint(unsigned int *ret_value, /* {{{ */
WARNING("db query utils: The `%s' config option "
"needs exactly one numeric argument.",
ci->key);
- return (-1);
+ return -1;
}
tmp = ci->values[0].value.number;
if ((tmp < 0.0) || (tmp > ((double)UINT_MAX)))
- return (-ERANGE);
+ return -ERANGE;
*ret_value = (unsigned int)(tmp + .5);
- return (0);
+ return 0;
} /* }}} int udb_config_set_uint */
/*
vl.values = calloc(r->values_num, sizeof(*vl.values));
if (vl.values == NULL) {
ERROR("db query utils: calloc failed.");
- return (-1);
+ return -1;
}
vl.values_len = r_area->ds->ds_num;
value_str, DS_TYPE_TO_STRING(r_area->ds->ds[i].type));
errno = EINVAL;
free(vl.values);
- return (-1);
+ return -1;
}
}
ERROR(
"udb_result_submit: creating type_instance failed with status %d.",
status);
- return (status);
+ return status;
}
} else {
char tmp[DATA_MAX_NAME_LEN];
ERROR(
"udb_result_submit: creating type_instance failed with status %d.",
status);
- return (status);
+ return status;
}
tmp[sizeof(tmp) - 1] = 0;
vl.meta = meta_data_create();
if (vl.meta == NULL) {
ERROR("db query utils:: meta_data_create failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
for (size_t i = 0; i < r->metadata_num; i++) {
ERROR("db query utils:: meta_data_add_string failed.");
meta_data_destroy(vl.meta);
vl.meta = NULL;
- return (status);
+ return status;
}
}
}
vl.meta = NULL;
}
sfree(vl.values);
- return (0);
+ return 0;
} /* }}} void udb_result_submit */
static void udb_result_finish_result(udb_result_t const *r, /* {{{ */
udb_result_preparation_area_t *prep_area,
char **column_names, size_t column_num) {
if ((r == NULL) || (prep_area == NULL))
- return (-EINVAL);
+ return -EINVAL;
#define BAIL_OUT(status) \
prep_area->ds = NULL; \
} /* }}} for (i = 0; i < r->metadata_num; i++) */
#undef BAIL_OUT
- return (0);
+ return 0;
} /* }}} int udb_result_prepare_result */
static void udb_result_free(udb_result_t *r) /* {{{ */
r = calloc(1, sizeof(*r));
if (r == NULL) {
ERROR("db query utils: calloc failed.");
- return (-1);
+ return -1;
}
r->type = NULL;
r->instance_prefix = NULL;
if (status != 0) {
udb_result_free(r);
- return (-1);
+ return -1;
}
/* If all went well, add this result to the list of results. */
last->next = r;
}
- return (0);
+ return 0;
} /* }}} int udb_result_create */
/*
int status;
if ((ret_query_list == NULL) || (ret_query_list_len == NULL))
- return (-EINVAL);
+ return -EINVAL;
query_list = *ret_query_list;
query_list_len = *ret_query_list_len;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("db query utils: The `Query' block "
"needs exactly one string argument.");
- return (-1);
+ return -1;
}
q = calloc(1, sizeof(*q));
if (q == NULL) {
ERROR("db query utils: calloc failed.");
- return (-1);
+ return -1;
}
q->min_version = 0;
q->max_version = UINT_MAX;
status = udb_config_set_string(&q->name, ci);
if (status != 0) {
sfree(q);
- return (status);
+ return status;
}
/* Fill the `udb_query_t' structure.. */
if (status != 0) {
udb_query_free_one(q);
- return (-1);
+ return -1;
}
*ret_query_list = query_list;
*ret_query_list_len = query_list_len;
- return (0);
+ return 0;
} /* }}} int udb_query_create */
void udb_query_free(udb_query_t **query_list, size_t query_list_len) /* {{{ */
(dst_list_len == NULL)) {
ERROR("db query utils: udb_query_pick_from_list_by_name: "
"Invalid argument.");
- return (-EINVAL);
+ return -EINVAL;
}
num_added = 0;
tmp_list = realloc(*dst_list, (tmp_list_len + 1) * sizeof(udb_query_t *));
if (tmp_list == NULL) {
ERROR("db query utils: realloc failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
tmp_list[tmp_list_len] = src_list[i];
ERROR("db query utils: Cannot find query `%s'. Make sure the <Query> "
"block is above the database definition!",
name);
- return (-ENOENT);
+ return -ENOENT;
} else {
DEBUG("db query utils: Added %i versions of query `%s'.", num_added, name);
}
- return (0);
+ return 0;
} /* }}} int udb_query_pick_from_list_by_name */
int udb_query_pick_from_list(oconfig_item_t *ci, /* {{{ */
(dst_list_len == NULL)) {
ERROR("db query utils: udb_query_pick_from_list: "
"Invalid argument.");
- return (-EINVAL);
+ return -EINVAL;
}
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
ERROR("db query utils: The `%s' config option "
"needs exactly one string argument.",
ci->key);
- return (-1);
+ return -1;
}
name = ci->values[0].value.string;
- return (udb_query_pick_from_list_by_name(name, src_list, src_list_len,
- dst_list, dst_list_len));
+ return udb_query_pick_from_list_by_name(name, src_list, src_list_len,
+ dst_list, dst_list_len);
} /* }}} int udb_query_pick_from_list */
const char *udb_query_get_name(udb_query_t *q) /* {{{ */
{
if (q == NULL)
- return (NULL);
+ return NULL;
- return (q->name);
+ return q->name;
} /* }}} const char *udb_query_get_name */
const char *udb_query_get_statement(udb_query_t *q) /* {{{ */
{
if (q == NULL)
- return (NULL);
+ return NULL;
- return (q->statement);
+ return q->statement;
} /* }}} const char *udb_query_get_statement */
void udb_query_set_user_data(udb_query_t *q, void *user_data) /* {{{ */
void *udb_query_get_user_data(udb_query_t *q) /* {{{ */
{
if (q == NULL)
- return (NULL);
+ return NULL;
- return (q->user_data);
+ return q->user_data;
} /* }}} void *udb_query_get_user_data */
int udb_query_check_version(udb_query_t *q, unsigned int version) /* {{{ */
{
if (q == NULL)
- return (-EINVAL);
+ return -EINVAL;
if ((version < q->min_version) || (version > q->max_version))
- return (0);
+ return 0;
- return (1);
+ return 1;
} /* }}} int udb_query_check_version */
void udb_query_finish_result(udb_query_t const *q, /* {{{ */
int status;
if ((q == NULL) || (prep_area == NULL))
- return (-EINVAL);
+ return -EINVAL;
if ((prep_area->column_num < 1) || (prep_area->host == NULL) ||
(prep_area->plugin == NULL) || (prep_area->db_name == NULL)) {
ERROR("db query utils: Query `%s': Query is not prepared; "
"can't handle result.",
q->name);
- return (-EINVAL);
+ return -EINVAL;
}
#if defined(COLLECT_DEBUG) && COLLECT_DEBUG /* {{{ */
ERROR("db query utils: udb_query_handle_result (%s, %s): "
"All results failed.",
prep_area->db_name, q->name);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int udb_query_handle_result */
int udb_query_prepare_result(udb_query_t const *q, /* {{{ */
int status;
if ((q == NULL) || (prep_area == NULL))
- return (-EINVAL);
+ return -EINVAL;
udb_query_finish_result(q, prep_area);
ERROR("db query utils: Query `%s': Prepare failed: Out of memory.",
q->name);
udb_query_finish_result(q, prep_area);
- return (-ENOMEM);
+ return -ENOMEM;
}
#if defined(COLLECT_DEBUG) && COLLECT_DEBUG
"Column `%s' from `PluginInstanceFrom' could not be found.",
q->plugin_instance_from);
udb_query_finish_result(q, prep_area);
- return (-ENOENT);
+ return -ENOENT;
}
}
/* }}} */
"preparation areas.",
q->name);
udb_query_finish_result(q, prep_area);
- return (-EINVAL);
+ return -EINVAL;
}
status = udb_result_prepare_result(r, r_area, column_names, column_num);
if (status != 0) {
udb_query_finish_result(q, prep_area);
- return (status);
+ return status;
}
}
- return (0);
+ return 0;
} /* }}} int udb_query_prepare_result */
udb_query_preparation_area_t *
next_r_area = &r_area->next;
}
- return (q_area);
+ return q_area;
} /* }}} udb_query_preparation_area_t *udb_query_allocate_preparation_area */
void udb_query_delete_preparation_area(
free(q_area);
} /* }}} void udb_query_delete_preparation_area */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
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 : */
break;
if (i >= 16)
- return (0);
+ return 0;
- return (a->s6_addr[i] > b->s6_addr[i] ? 1 : -1);
+ return a->s6_addr[i] > b->s6_addr[i] ? 1 : -1;
} /* int cmp_addrinfo */
static inline int ignore_list_match(const struct in6_addr *addr) {
for (ip_list_t *ptr = IgnoreList; ptr != NULL; ptr = ptr->next)
if (cmp_in6_addr(addr, &ptr->addr) == 0)
- return (1);
- return (0);
+ return 1;
+ return 0;
} /* int ignore_list_match */
static void ignore_list_add(const struct in6_addr *addr) {
uint16_t payload_len;
if (0 > len)
- return (0);
+ return 0;
offset = sizeof(struct ip6_hdr);
nexthdr = ipv6->ip6_nxt;
payload_len = ntohs(ipv6->ip6_plen);
if (ignore_list_match(&c_src_addr))
- return (0);
+ return 0;
/* Parse extension headers. This only handles the standard headers, as
* defined in RFC 2460, correctly. Fragments are discarded. */
/* Catch broken packets */
if ((offset + sizeof(struct ip6_ext)) > (unsigned int)len)
- return (0);
+ return 0;
/* Cannot handle fragments. */
if (IPPROTO_FRAGMENT == nexthdr)
- return (0);
+ return 0;
memcpy(&ext_hdr, (char *)ipv6 + offset, sizeof(struct ip6_ext));
nexthdr = ext_hdr.ip6e_nxt;
/* This header is longer than the packets payload.. WTF? */
if (ext_hdr_len > payload_len)
- return (0);
+ return 0;
offset += ext_hdr_len;
payload_len -= ext_hdr_len;
/* Catch broken and empty packets */
if (((offset + payload_len) > (unsigned int)len) || (payload_len == 0) ||
(payload_len > PCAP_SNAPLEN))
- return (0);
+ return 0;
if (IPPROTO_UDP != nexthdr)
- return (0);
+ return 0;
memcpy(buf, (char *)ipv6 + offset, payload_len);
if (handle_udp((struct udphdr *)buf, payload_len) == 0)
- return (0);
+ return 0;
- return (1); /* Success */
+ return 1; /* Success */
} /* int handle_ipv6 */
/* #endif HAVE_IPV6 */
#else /* if !HAVE_IPV6 */
static int handle_ipv6(__attribute__((unused)) void *pkg,
__attribute__((unused)) int len) {
- return (0);
+ return 0;
}
#endif /* !HAVE_IPV6 */
struct in6_addr c_dst_addr;
if (ip->ip_v == 6)
- return (handle_ipv6((void *)ip, len));
+ return handle_ipv6((void *)ip, len);
in6_addr_from_buffer(&c_src_addr, &ip->ip_src.s_addr,
sizeof(ip->ip_src.s_addr), AF_INET);
in6_addr_from_buffer(&c_dst_addr, &ip->ip_dst.s_addr,
sizeof(ip->ip_dst.s_addr), AF_INET);
if (ignore_list_match(&c_src_addr))
- return (0);
+ return 0;
if (IPPROTO_UDP != ip->ip_p)
return 0;
memcpy(buf, ((char *)ip) + offset, len - offset);
return 0;
memcpy(buf, pkt, len);
if (ETHERTYPE_IPV6 == etype)
- return (handle_ipv6((void *)buf, len));
+ return handle_ipv6((void *)buf, len);
else
return handle_ip((struct ip *)buf, len);
}
uint16_t etype;
if ((0 > len) || ((unsigned int)len < sizeof(struct sll_header)))
- return (0);
+ return 0;
hdr = (struct sll_header *)pkt;
pkt = (u_char *)(hdr + 1);
return 0;
if (ETHERTYPE_IPV6 == etype)
- return (handle_ipv6((void *)pkt, len));
+ return handle_ipv6((void *)pkt, len);
else
return handle_ip((struct ip *)pkt, len);
}
switch (t) {
#if (defined(__NAMESER)) && (__NAMESER >= 19991001)
case ns_t_a:
- return ("A");
+ return "A";
case ns_t_ns:
- return ("NS");
+ return "NS";
case ns_t_md:
- return ("MD");
+ return "MD";
case ns_t_mf:
- return ("MF");
+ return "MF";
case ns_t_cname:
- return ("CNAME");
+ return "CNAME";
case ns_t_soa:
- return ("SOA");
+ return "SOA";
case ns_t_mb:
- return ("MB");
+ return "MB";
case ns_t_mg:
- return ("MG");
+ return "MG";
case ns_t_mr:
- return ("MR");
+ return "MR";
case ns_t_null:
- return ("NULL");
+ return "NULL";
case ns_t_wks:
- return ("WKS");
+ return "WKS";
case ns_t_ptr:
- return ("PTR");
+ return "PTR";
case ns_t_hinfo:
- return ("HINFO");
+ return "HINFO";
case ns_t_minfo:
- return ("MINFO");
+ return "MINFO";
case ns_t_mx:
- return ("MX");
+ return "MX";
case ns_t_txt:
- return ("TXT");
+ return "TXT";
case ns_t_rp:
- return ("RP");
+ return "RP";
case ns_t_afsdb:
- return ("AFSDB");
+ return "AFSDB";
case ns_t_x25:
- return ("X25");
+ return "X25";
case ns_t_isdn:
- return ("ISDN");
+ return "ISDN";
case ns_t_rt:
- return ("RT");
+ return "RT";
case ns_t_nsap:
- return ("NSAP");
+ return "NSAP";
case ns_t_nsap_ptr:
- return ("NSAP-PTR");
+ return "NSAP-PTR";
case ns_t_sig:
- return ("SIG");
+ return "SIG";
case ns_t_key:
- return ("KEY");
+ return "KEY";
case ns_t_px:
- return ("PX");
+ return "PX";
case ns_t_gpos:
- return ("GPOS");
+ return "GPOS";
case ns_t_aaaa:
- return ("AAAA");
+ return "AAAA";
case ns_t_loc:
- return ("LOC");
+ return "LOC";
case ns_t_nxt:
- return ("NXT");
+ return "NXT";
case ns_t_eid:
- return ("EID");
+ return "EID";
case ns_t_nimloc:
- return ("NIMLOC");
+ return "NIMLOC";
case ns_t_srv:
- return ("SRV");
+ return "SRV";
case ns_t_atma:
- return ("ATMA");
+ return "ATMA";
case ns_t_naptr:
- return ("NAPTR");
+ return "NAPTR";
case ns_t_opt:
- return ("OPT");
+ return "OPT";
#if __NAMESER >= 19991006
case ns_t_kx:
- return ("KX");
+ return "KX";
case ns_t_cert:
- return ("CERT");
+ return "CERT";
case ns_t_a6:
- return ("A6");
+ return "A6";
case ns_t_dname:
- return ("DNAME");
+ return "DNAME";
case ns_t_sink:
- return ("SINK");
+ return "SINK";
case ns_t_tsig:
- return ("TSIG");
+ return "TSIG";
#endif
#if __NAMESER >= 20090302
case ns_t_apl:
- return ("APL");
+ return "APL";
case ns_t_ds:
- return ("DS");
+ return "DS";
case ns_t_sshfp:
- return ("SSHFP");
+ return "SSHFP";
case ns_t_ipseckey:
- return ("IPSECKEY");
+ return "IPSECKEY";
case ns_t_rrsig:
- return ("RRSIG");
+ return "RRSIG";
case ns_t_nsec:
- return ("NSEC");
+ return "NSEC";
case ns_t_dnskey:
- return ("DNSKEY");
+ return "DNSKEY";
case ns_t_dhcid:
- return ("DHCID");
+ return "DHCID";
case ns_t_nsec3:
- return ("NSEC3");
+ return "NSEC3";
case ns_t_nsec3param:
- return ("NSEC3PARAM");
+ return "NSEC3PARAM";
case ns_t_hip:
- return ("HIP");
+ return "HIP";
case ns_t_spf:
- return ("SPF");
+ return "SPF";
case ns_t_ixfr:
- return ("IXFR");
+ return "IXFR";
#endif
case ns_t_axfr:
- return ("AXFR");
+ return "AXFR";
case ns_t_mailb:
- return ("MAILB");
+ return "MAILB";
case ns_t_maila:
- return ("MAILA");
+ return "MAILA";
case ns_t_any:
- return ("ANY");
+ return "ANY";
#if __NAMESER >= 19991006
case ns_t_zxfr:
- return ("ZXFR");
+ return "ZXFR";
#endif
#if __NAMESER >= 20090302
case ns_t_dlv:
- return ("DLV");
+ return "DLV";
#endif
/* #endif __NAMESER >= 19991001 */
#elif (defined(__BIND)) && (__BIND >= 19950621)
case T_A:
- return ("A"); /* 1 ... */
+ return "A"; /* 1 ... */
case T_NS:
- return ("NS");
+ return "NS";
case T_MD:
- return ("MD");
+ return "MD";
case T_MF:
- return ("MF");
+ return "MF";
case T_CNAME:
- return ("CNAME");
+ return "CNAME";
case T_SOA:
- return ("SOA");
+ return "SOA";
case T_MB:
- return ("MB");
+ return "MB";
case T_MG:
- return ("MG");
+ return "MG";
case T_MR:
- return ("MR");
+ return "MR";
case T_NULL:
- return ("NULL");
+ return "NULL";
case T_WKS:
- return ("WKS");
+ return "WKS";
case T_PTR:
- return ("PTR");
+ return "PTR";
case T_HINFO:
- return ("HINFO");
+ return "HINFO";
case T_MINFO:
- return ("MINFO");
+ return "MINFO";
case T_MX:
- return ("MX");
+ return "MX";
case T_TXT:
- return ("TXT");
+ return "TXT";
case T_RP:
- return ("RP");
+ return "RP";
case T_AFSDB:
- return ("AFSDB");
+ return "AFSDB";
case T_X25:
- return ("X25");
+ return "X25";
case T_ISDN:
- return ("ISDN");
+ return "ISDN";
case T_RT:
- return ("RT");
+ return "RT";
case T_NSAP:
- return ("NSAP");
+ return "NSAP";
case T_NSAP_PTR:
- return ("NSAP_PTR");
+ return "NSAP_PTR";
case T_SIG:
- return ("SIG");
+ return "SIG";
case T_KEY:
- return ("KEY");
+ return "KEY";
case T_PX:
- return ("PX");
+ return "PX";
case T_GPOS:
- return ("GPOS");
+ return "GPOS";
case T_AAAA:
- return ("AAAA");
+ return "AAAA";
case T_LOC:
- return ("LOC");
+ return "LOC";
case T_NXT:
- return ("NXT");
+ return "NXT";
case T_EID:
- return ("EID");
+ return "EID";
case T_NIMLOC:
- return ("NIMLOC");
+ return "NIMLOC";
case T_SRV:
- return ("SRV");
+ return "SRV";
case T_ATMA:
- return ("ATMA");
+ return "ATMA";
case T_NAPTR:
- return ("NAPTR"); /* ... 35 */
+ return "NAPTR"; /* ... 35 */
#if (__BIND >= 19960801)
case T_KX:
- return ("KX"); /* 36 ... */
+ return "KX"; /* 36 ... */
case T_CERT:
- return ("CERT");
+ return "CERT";
case T_A6:
- return ("A6");
+ return "A6";
case T_DNAME:
- return ("DNAME");
+ return "DNAME";
case T_SINK:
- return ("SINK");
+ return "SINK";
case T_OPT:
- return ("OPT");
+ return "OPT";
case T_APL:
- return ("APL");
+ return "APL";
case T_DS:
- return ("DS");
+ return "DS";
case T_SSHFP:
- return ("SSHFP");
+ return "SSHFP";
case T_RRSIG:
- return ("RRSIG");
+ return "RRSIG";
case T_NSEC:
- return ("NSEC");
+ return "NSEC";
case T_DNSKEY:
- return ("DNSKEY"); /* ... 48 */
+ return "DNSKEY"; /* ... 48 */
case T_TKEY:
- return ("TKEY"); /* 249 */
+ return "TKEY"; /* 249 */
#endif /* __BIND >= 19960801 */
case T_TSIG:
- return ("TSIG"); /* 250 ... */
+ return "TSIG"; /* 250 ... */
case T_IXFR:
- return ("IXFR");
+ return "IXFR";
case T_AXFR:
- return ("AXFR");
+ return "AXFR";
case T_MAILB:
- return ("MAILB");
+ return "MAILB";
case T_MAILA:
- return ("MAILA");
+ return "MAILA";
case T_ANY:
- return ("ANY"); /* ... 255 */
+ return "ANY"; /* ... 255 */
#endif /* __BIND >= 19950621 */
default:
- ssnprintf(buf, sizeof(buf), "#%i", t);
- return (buf);
+ snprintf(buf, sizeof(buf), "#%i", t);
+ return buf;
} /* switch (t) */
}
case 5:
return "Update";
default:
- ssnprintf(buf, sizeof(buf), "Opcode%d", o);
+ snprintf(buf, sizeof(buf), "Opcode%d", o);
return buf;
}
}
switch (rcode) {
#if (defined(__NAMESER)) && (__NAMESER >= 19991006)
case ns_r_noerror:
- return ("NOERROR");
+ return "NOERROR";
case ns_r_formerr:
- return ("FORMERR");
+ return "FORMERR";
case ns_r_servfail:
- return ("SERVFAIL");
+ return "SERVFAIL";
case ns_r_nxdomain:
- return ("NXDOMAIN");
+ return "NXDOMAIN";
case ns_r_notimpl:
- return ("NOTIMPL");
+ return "NOTIMPL";
case ns_r_refused:
- return ("REFUSED");
+ return "REFUSED";
case ns_r_yxdomain:
- return ("YXDOMAIN");
+ return "YXDOMAIN";
case ns_r_yxrrset:
- return ("YXRRSET");
+ return "YXRRSET";
case ns_r_nxrrset:
- return ("NXRRSET");
+ return "NXRRSET";
case ns_r_notauth:
- return ("NOTAUTH");
+ return "NOTAUTH";
case ns_r_notzone:
- return ("NOTZONE");
+ return "NOTZONE";
case ns_r_max:
- return ("MAX");
+ return "MAX";
case ns_r_badsig:
- return ("BADSIG");
+ return "BADSIG";
case ns_r_badkey:
- return ("BADKEY");
+ return "BADKEY";
case ns_r_badtime:
- return ("BADTIME");
+ return "BADTIME";
/* #endif __NAMESER >= 19991006 */
#elif (defined(__BIND)) && (__BIND >= 19950621)
case NOERROR:
- return ("NOERROR");
+ return "NOERROR";
case FORMERR:
- return ("FORMERR");
+ return "FORMERR";
case SERVFAIL:
- return ("SERVFAIL");
+ return "SERVFAIL";
case NXDOMAIN:
- return ("NXDOMAIN");
+ return "NXDOMAIN";
case NOTIMP:
- return ("NOTIMP");
+ return "NOTIMP";
case REFUSED:
- return ("REFUSED");
+ return "REFUSED";
#if defined(YXDOMAIN) && defined(NXRRSET)
case YXDOMAIN:
- return ("YXDOMAIN");
+ return "YXDOMAIN";
case YXRRSET:
- return ("YXRRSET");
+ return "YXRRSET";
case NXRRSET:
- return ("NXRRSET");
+ return "NXRRSET";
case NOTAUTH:
- return ("NOTAUTH");
+ return "NOTAUTH";
case NOTZONE:
- return ("NOTZONE");
+ return "NOTZONE";
#endif /* RFC2136 rcodes */
#endif /* __BIND >= 19950621 */
default:
- ssnprintf(buf, sizeof(buf), "RCode%i", rcode);
- return (buf);
+ snprintf(buf, sizeof(buf), "RCode%i", rcode);
+ return buf;
}
} /* const char *rcode_str (int rcode) */
return 0;
} /* static int main(int argc, char *argv[]) */
#endif
-/*
- * vim:shiftwidth=4:tabstop=8:softtabstop=4
- */
--- /dev/null
+/*
+ * collectd - src/utils_dpdk.c
+ * MIT License
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Maryam Tahhan <maryam.tahhan@intel.com>
+ * Harry van Haaren <harry.van.haaren@intel.com>
+ * Taras Chornyi <tarasx.chornyi@intel.com>
+ * Serhiy Pshyk <serhiyx.pshyk@intel.com>
+ * Krzysztof Matczak <krzysztofx.matczak@intel.com>
+ */
+
+#include "collectd.h"
+
+#include <poll.h>
+#include <semaphore.h>
+#include <sys/mman.h>
+
+#include <rte_config.h>
+#include <rte_eal.h>
+#include <rte_ethdev.h>
+
+#include "common.h"
+#include "utils_dpdk.h"
+
+#define DPDK_DEFAULT_RTE_CONFIG "/var/run/.rte_config"
+#define DPDK_EAL_ARGC 10
+// Complete trace should fit into 1024 chars. Trace contain some headers
+// and text together with traced data from pipe. This is the reason why
+// we need to limit DPDK_MAX_BUFFER_SIZE value.
+#define DPDK_MAX_BUFFER_SIZE 896
+#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;
+ char shm_name[DATA_MAX_NAME_LEN];
+
+ 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);
+
+ snprintf(phc->eal_config.coremask, DATA_MAX_NAME_LEN, "%s", "0xf");
+ snprintf(phc->eal_config.memory_channels, DATA_MAX_NAME_LEN, "%s", "1");
+ snprintf(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("FilePrefix", child->key) == 0) {
+ char prefix[DATA_MAX_NAME_LEN];
+
+ status = cf_util_get_string_buffer(child, prefix, sizeof(prefix));
+ if (status == 0) {
+ snprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN,
+ "/var/run/.%s_config", prefix);
+ DEBUG("dpdk_common: EAL:File prefix %s", phc->eal_config.file_prefix);
+ }
+ } else if (strcasecmp("LogLevel", child->key) == 0) {
+ status = cf_util_get_string_buffer(child, phc->eal_config.log_level,
+ sizeof(phc->eal_config.log_level));
+ DEBUG("dpdk_common: EAL:LogLevel %s", phc->eal_config.log_level);
+ } else if (strcasecmp("RteDriverLibPath", child->key) == 0) {
+ status = cf_util_get_string_buffer(
+ child, phc->eal_config.rte_driver_lib_path,
+ sizeof(phc->eal_config.rte_driver_lib_path));
+ DEBUG("dpdk_common: EAL:RteDriverLibPath %s",
+ phc->eal_config.rte_driver_lib_path);
+ } 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];
+
+ /*
+ * Call shm_unlink first, as 'name' might be no longer accessible after munmap
+ */
+ if (shm_unlink(name))
+ ERROR("shm_unlink failure %s", sstrerror(errno, errbuf, sizeof(errbuf)));
+
+ if (map != NULL) {
+ if (munmap(map, size))
+ ERROR("munmap 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;
+ sstrncpy(phc->shm_name, name, sizeof(phc->shm_name));
+
+ dpdk_helper_config_default(phc);
+
+ *pphc = phc;
+
+ return 0;
+}
+
+void dpdk_helper_shutdown(dpdk_helper_ctx_t *phc) {
+ if (phc == NULL)
+ return;
+
+ 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);
+}
+
+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.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++] = "secondary";
+
+ if (strcasecmp(phc->eal_config.log_level, "") != 0) {
+ argp[argc++] = "--log-level";
+ argp[argc++] = phc->eal_config.log_level;
+ }
+ if (strcasecmp(phc->eal_config.rte_driver_lib_path, "") != 0) {
+ argp[argc++] = "-d";
+ argp[argc++] = phc->eal_config.rte_driver_lib_path;
+ }
+
+ 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);
+ DEBUG("%s:dpdk_helper_check_pipe: poll data_avail=%d", phc->shm_name,
+ data_avail);
+ 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) - 1));
+ DEBUG("%s:dpdk_helper_check_pipe: read nbytes=%d", phc->shm_name, nbytes);
+ if (nbytes <= 0)
+ break;
+ buf[nbytes] = '\0';
+ sstrncpy(out, buf, sizeof(out));
+ 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;
+}
--- /dev/null
+/*
+ * collectd - src/utils_dpdk.h
+ * MIT License
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Maryam Tahhan <maryam.tahhan@intel.com>
+ * Harry van Haaren <harry.van.haaren@intel.com>
+ * Taras Chornyi <tarasx.chornyi@intel.com>
+ * Serhiy Pshyk <serhiyx.pshyk@intel.com>
+ * Krzysztof Matczak <krzysztofx.matczak@intel.com>
+ */
+
+#ifndef UTILS_DPDK_H
+#define UTILS_DPDK_H
+
+#include <rte_version.h>
+
+#define ERR_BUF_SIZE 1024
+
+enum DPDK_CMD {
+ DPDK_CMD_NONE = 0,
+ DPDK_CMD_QUIT,
+ DPDK_CMD_INIT,
+ DPDK_CMD_GET_STATS,
+ DPDK_CMD_GET_EVENTS,
+ __DPDK_CMD_LAST,
+};
+
+struct dpdk_eal_config_s {
+ char coremask[DATA_MAX_NAME_LEN];
+ char memory_channels[DATA_MAX_NAME_LEN];
+ char socket_memory[DATA_MAX_NAME_LEN];
+ char file_prefix[DATA_MAX_NAME_LEN];
+ char log_level[DATA_MAX_NAME_LEN];
+ char rte_driver_lib_path[PATH_MAX];
+};
+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);
+void 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 */
fh = fopen(h->filename, "r");
if (fh == NULL)
- return (-1);
+ return -1;
fl.l_type = F_RDLCK;
fl.l_whence = SEEK_SET;
status = fcntl(fileno(fh), F_SETLK, &fl);
if (status != 0) {
fclose(fh);
- return (-1);
+ return -1;
}
tree = c_avl_create((int (*)(const void *, const void *))strcmp);
if (tree == NULL) {
fclose(fh);
- return (-1);
+ return -1;
}
/* Read `fh' into `tree' */
fbh_free_tree(h->tree);
h->tree = tree;
- return (0);
+ return 0;
} /* }}} int fbh_read_file */
static int fbh_check_file(fbhash_t *h) /* {{{ */
status = stat(h->filename, &statbuf);
if (status != 0)
- return (-1);
+ return -1;
if (h->mtime >= statbuf.st_mtime)
- return (0);
+ return 0;
status = fbh_read_file(h);
if (status == 0)
h->mtime = statbuf.st_mtime;
- return (status);
+ return status;
} /* }}} int fbh_check_file */
/*
int status;
if (file == NULL)
- return (NULL);
+ return NULL;
h = calloc(1, sizeof(*h));
if (h == NULL)
- return (NULL);
+ return NULL;
h->filename = strdup(file);
if (h->filename == NULL) {
free(h);
- return (NULL);
+ return NULL;
}
h->mtime = 0;
if (status != 0) {
fbh_destroy(h);
free(h);
- return (NULL);
+ return NULL;
}
- return (h);
+ return h;
} /* }}} fbhash_t *fbh_create */
void fbh_destroy(fbhash_t *h) /* {{{ */
int status;
if ((h == NULL) || (key == NULL))
- return (NULL);
+ return NULL;
value = NULL;
value_copy = NULL;
pthread_mutex_unlock(&h->lock);
- return (value_copy);
+ return value_copy;
} /* }}} char *fbh_get */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
char *fbh_get(fbhash_t *h, const char *key);
#endif /* UTILS_FBHASH_H */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
#define BUFFER_ADD(...) \
do { \
- status = ssnprintf(ret + offset, ret_len - offset, __VA_ARGS__); \
+ status = snprintf(ret + offset, ret_len - offset, __VA_ARGS__); \
if (status < 1) { \
- return (-1); \
+ return -1; \
} else if (((size_t)status) >= (ret_len - offset)) { \
- return (-1); \
+ return -1; \
} else \
offset += ((size_t)status); \
} while (0)
else {
ERROR("gr_format_values plugin: Unknown data source type: %i",
ds->ds[ds_num].type);
- return (-1);
+ return -1;
}
#undef BUFFER_ADD
- return (0);
+ return 0;
}
static void gr_copy_escape_part(char *dst, const char *src, size_t dst_len,
sizeof(n_type_instance), escape_char, preserve_separator);
if (n_plugin_instance[0] != '\0')
- ssnprintf(tmp_plugin, sizeof(tmp_plugin), "%s%c%s", n_plugin,
- (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
- n_plugin_instance);
+ snprintf(tmp_plugin, sizeof(tmp_plugin), "%s%c%s", n_plugin,
+ (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
+ n_plugin_instance);
else
sstrncpy(tmp_plugin, n_plugin, sizeof(tmp_plugin));
if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(n_plugin, n_type) == 0)
sstrncpy(tmp_type, n_type_instance, sizeof(tmp_type));
else
- ssnprintf(tmp_type, sizeof(tmp_type), "%s%c%s", n_type,
- (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
- n_type_instance);
+ snprintf(tmp_type, sizeof(tmp_type), "%s%c%s", n_type,
+ (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
+ n_type_instance);
} else
sstrncpy(tmp_type, n_type, sizeof(tmp_type));
if (ds_name != NULL) {
if ((flags & GRAPHITE_DROP_DUPE_FIELDS) &&
strcmp(tmp_plugin, tmp_type) == 0)
- ssnprintf(ret, ret_len, "%s%s%s.%s.%s", prefix, n_host, postfix,
- tmp_plugin, ds_name);
+ snprintf(ret, ret_len, "%s%s%s.%s.%s", prefix, n_host, postfix,
+ tmp_plugin, ds_name);
else
- ssnprintf(ret, ret_len, "%s%s%s.%s.%s.%s", prefix, n_host, postfix,
- tmp_plugin, tmp_type, ds_name);
+ snprintf(ret, ret_len, "%s%s%s.%s.%s.%s", prefix, n_host, postfix,
+ tmp_plugin, tmp_type, ds_name);
} else
- ssnprintf(ret, ret_len, "%s%s%s.%s.%s", prefix, n_host, postfix, tmp_plugin,
- tmp_type);
+ snprintf(ret, ret_len, "%s%s%s.%s.%s", prefix, n_host, postfix, tmp_plugin,
+ tmp_type);
- return (0);
+ return 0;
}
static void escape_graphite_string(char *buffer, char escape_char) {
if (status != 0) {
ERROR("format_graphite: error with gr_format_name");
sfree(rates);
- return (status);
+ return status;
}
escape_graphite_string(key, escape_char);
if (status != 0) {
ERROR("format_graphite: error with gr_format_values");
sfree(rates);
- return (status);
+ return status;
}
/* Compute the graphite command */
message_len =
- (size_t)ssnprintf(message, sizeof(message), "%s %s %u\r\n", key, values,
- (unsigned int)CDTIME_T_TO_TIME_T(vl->time));
+ (size_t)snprintf(message, sizeof(message), "%s %s %u\r\n", key, values,
+ (unsigned int)CDTIME_T_TO_TIME_T(vl->time));
if (message_len >= sizeof(message)) {
ERROR("format_graphite: message buffer too small: "
"Need %zu bytes.",
message_len + 1);
sfree(rates);
- return (-ENOMEM);
+ return -ENOMEM;
}
/* Append it in case we got multiple data set */
if ((buffer_pos + message_len) >= buffer_size) {
ERROR("format_graphite: target buffer too small");
sfree(rates);
- return (-ENOMEM);
+ return -ENOMEM;
}
memcpy((void *)(buffer + buffer_pos), message, message_len);
buffer_pos += message_len;
buffer[buffer_pos] = '\0';
}
sfree(rates);
- return (status);
+ return status;
} /* int format_graphite */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
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",
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;
}
size_t dst_pos;
if ((buffer == NULL) || (string == NULL))
- return (-EINVAL);
+ return -EINVAL;
if (buffer_size < 3)
- return (-ENOMEM);
+ return -ENOMEM;
dst_pos = 0;
do { \
if (dst_pos >= (buffer_size - 1)) { \
buffer[buffer_size - 1] = 0; \
- return (-ENOMEM); \
+ return -ENOMEM; \
} \
buffer[dst_pos] = (c); \
dst_pos++; \
#undef BUFFER_ADD
- return (0);
+ return 0;
} /* }}} int json_escape_string */
static int values_to_json(char *buffer, size_t buffer_size, /* {{{ */
#define BUFFER_ADD(...) \
do { \
int status; \
- status = ssnprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
+ status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
if (status < 1) { \
sfree(rates); \
- return (-1); \
+ return -1; \
} else if (((size_t)status) >= (buffer_size - offset)) { \
sfree(rates); \
- return (-ENOMEM); \
+ return -ENOMEM; \
} else \
offset += ((size_t)status); \
} while (0)
if (rates == NULL) {
WARNING("utils_format_json: uc_get_rate failed.");
sfree(rates);
- return (-1);
+ return -1;
}
if (isfinite(rates[i]))
else {
ERROR("format_json: Unknown data source type: %i", ds->ds[i].type);
sfree(rates);
- return (-1);
+ return -1;
}
} /* for ds->ds_num */
BUFFER_ADD("]");
DEBUG("format_json: values_to_json: buffer = %s;", buffer);
sfree(rates);
- return (0);
+ return 0;
} /* }}} int values_to_json */
static int dstypes_to_json(char *buffer, size_t buffer_size, /* {{{ */
#define BUFFER_ADD(...) \
do { \
int status; \
- status = ssnprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
+ status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
if (status < 1) \
- return (-1); \
+ return -1; \
else if (((size_t)status) >= (buffer_size - offset)) \
- return (-ENOMEM); \
+ return -ENOMEM; \
else \
offset += ((size_t)status); \
} while (0)
DEBUG("format_json: dstypes_to_json: buffer = %s;", buffer);
- return (0);
+ return 0;
} /* }}} int dstypes_to_json */
static int dsnames_to_json(char *buffer, size_t buffer_size, /* {{{ */
#define BUFFER_ADD(...) \
do { \
int status; \
- status = ssnprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
+ status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
if (status < 1) \
- return (-1); \
+ return -1; \
else if (((size_t)status) >= (buffer_size - offset)) \
- return (-ENOMEM); \
+ return -ENOMEM; \
else \
offset += ((size_t)status); \
} while (0)
DEBUG("format_json: dsnames_to_json: buffer = %s;", buffer);
- return (0);
+ return 0;
} /* }}} int dsnames_to_json */
static int meta_data_keys_to_json(char *buffer, size_t buffer_size, /* {{{ */
#define BUFFER_ADD(...) \
do { \
- status = ssnprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
+ status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
if (status < 1) \
- return (-1); \
+ return -1; \
else if (((size_t)status) >= (buffer_size - offset)) \
- return (-ENOMEM); \
+ return -ENOMEM; \
else \
offset += ((size_t)status); \
} while (0)
} /* for (keys) */
if (offset == 0)
- return (ENOENT);
+ return ENOENT;
buffer[0] = '{'; /* replace leading ',' */
BUFFER_ADD("}");
#undef BUFFER_ADD
- return (0);
+ return 0;
} /* }}} int meta_data_keys_to_json */
static int meta_data_to_json(char *buffer, size_t buffer_size, /* {{{ */
int status;
if ((buffer == NULL) || (buffer_size == 0) || (meta == NULL))
- return (EINVAL);
+ return EINVAL;
status = meta_data_toc(meta, &keys);
if (status <= 0)
- return (status);
+ return status;
keys_num = (size_t)status;
status = meta_data_keys_to_json(buffer, buffer_size, meta, keys, keys_num);
#define BUFFER_ADD(...) \
do { \
- status = ssnprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
+ status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
if (status < 1) \
- return (-1); \
+ return -1; \
else if (((size_t)status) >= (buffer_size - offset)) \
- return (-ENOMEM); \
+ return -ENOMEM; \
else \
offset += ((size_t)status); \
} while (0)
status = values_to_json(temp, sizeof(temp), ds, vl, store_rates);
if (status != 0)
- return (status);
+ return status;
BUFFER_ADD("\"values\":%s", temp);
status = dstypes_to_json(temp, sizeof(temp), ds);
if (status != 0)
- return (status);
+ return status;
BUFFER_ADD(",\"dstypes\":%s", temp);
status = dsnames_to_json(temp, sizeof(temp), ds);
if (status != 0)
- return (status);
+ return status;
BUFFER_ADD(",\"dsnames\":%s", temp);
BUFFER_ADD(",\"time\":%.3f", CDTIME_T_TO_DOUBLE(vl->time));
do { \
status = json_escape_string(temp, sizeof(temp), (value)); \
if (status != 0) \
- return (status); \
+ return status; \
BUFFER_ADD(",\"%s\":%s", (key), temp); \
} while (0)
memset(meta_buffer, 0, sizeof(meta_buffer));
status = meta_data_to_json(meta_buffer, sizeof(meta_buffer), vl->meta);
if (status != 0)
- return (status);
+ return status;
BUFFER_ADD(",\"meta\":%s", meta_buffer);
} /* if (vl->meta != NULL) */
DEBUG("format_json: value_list_to_json: buffer = %s;", buffer);
- return (0);
+ return 0;
} /* }}} int value_list_to_json */
static int format_json_value_list_nocheck(char *buffer, /* {{{ */
status = value_list_to_json(temp, sizeof(temp), ds, vl, store_rates);
if (status != 0)
- return (status);
+ return status;
temp_size = strlen(temp);
memcpy(buffer + (*ret_buffer_fill), temp, temp_size + 1);
(*ret_buffer_fill) += temp_size;
(*ret_buffer_free) -= temp_size;
- return (0);
+ return 0;
} /* }}} int format_json_value_list_nocheck */
int format_json_initialize(char *buffer, /* {{{ */
if ((buffer == NULL) || (ret_buffer_fill == NULL) ||
(ret_buffer_free == NULL))
- return (-EINVAL);
+ return -EINVAL;
buffer_fill = *ret_buffer_fill;
buffer_free = *ret_buffer_free;
buffer_fill = 0;
if (buffer_free < 3)
- return (-ENOMEM);
+ return -ENOMEM;
memset(buffer, 0, buffer_free);
*ret_buffer_fill = buffer_fill;
*ret_buffer_free = buffer_free;
- return (0);
+ return 0;
} /* }}} int format_json_initialize */
int format_json_finalize(char *buffer, /* {{{ */
if ((buffer == NULL) || (ret_buffer_fill == NULL) ||
(ret_buffer_free == NULL))
- return (-EINVAL);
+ return -EINVAL;
if (*ret_buffer_free < 2)
- return (-ENOMEM);
+ return -ENOMEM;
/* Replace the leading comma added in `value_list_to_json' with a square
* bracket. */
if (buffer[0] != ',')
- return (-EINVAL);
+ return -EINVAL;
buffer[0] = '[';
pos = *ret_buffer_fill;
(*ret_buffer_fill)++;
(*ret_buffer_free)--;
- return (0);
+ return 0;
} /* }}} int format_json_finalize */
int format_json_value_list(char *buffer, /* {{{ */
int store_rates) {
if ((buffer == NULL) || (ret_buffer_fill == NULL) ||
(ret_buffer_free == NULL) || (ds == NULL) || (vl == NULL))
- return (-EINVAL);
+ return -EINVAL;
if (*ret_buffer_free < 3)
- return (-ENOMEM);
+ return -ENOMEM;
- return (format_json_value_list_nocheck(buffer, ret_buffer_fill,
- ret_buffer_free, ds, vl, store_rates,
- (*ret_buffer_free) - 2));
+ return format_json_value_list_nocheck(buffer, ret_buffer_fill,
+ ret_buffer_free, ds, vl, store_rates,
+ (*ret_buffer_free) - 2);
} /* }}} int format_json_value_list */
#if HAVE_LIBYAJL
if (str == NULL)
return (int)yajl_gen_null(g);
- return (int)yajl_gen_string(g, (unsigned char const *)str,
+ return (int)yajl_gen_string(g, (const unsigned char *)str,
(unsigned int)strlen(str));
} /* }}} int json_add_string */
return ENOTSUP;
} /* }}} int format_json_notification */
#endif
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
size_t dst_pos;
if ((buffer == NULL) || (string == NULL))
- return (-EINVAL);
+ return -EINVAL;
if (buffer_size < 3)
- return (-ENOMEM);
+ return -ENOMEM;
dst_pos = 0;
do { \
if (dst_pos >= (buffer_size - 1)) { \
buffer[buffer_size - 1] = 0; \
- return (-ENOMEM); \
+ return -ENOMEM; \
} \
buffer[dst_pos] = (c); \
dst_pos++; \
#undef BUFFER_ADD
- return (0);
+ return 0;
} /* }}} int kairosdb_escape_string */
static int values_to_kairosdb(char *buffer, size_t buffer_size, /* {{{ */
#define BUFFER_ADD(...) \
do { \
int status; \
- status = ssnprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
+ status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
if (status < 1) { \
sfree(rates); \
- return (-1); \
+ return -1; \
} else if (((size_t)status) >= (buffer_size - offset)) { \
sfree(rates); \
- return (-ENOMEM); \
+ return -ENOMEM; \
} else \
offset += ((size_t)status); \
} while (0)
"%s|%s|%s|%s|%s",
vl->plugin, vl->plugin_instance, vl->type, vl->type_instance,
ds->ds[ds_idx].name);
- return (-1);
+ return -1;
}
} else if (store_rates) {
if (rates == NULL)
vl->plugin, vl->plugin_instance, vl->type, vl->type_instance,
ds->ds[ds_idx].name);
- return (-1);
+ return -1;
}
if (isfinite(rates[ds_idx])) {
vl->plugin, vl->plugin_instance, vl->type, vl->type_instance,
ds->ds[ds_idx].name);
sfree(rates);
- return (-1);
+ return -1;
}
} else if (ds->ds[ds_idx].type == DS_TYPE_COUNTER) {
BUFFER_ADD("[[");
} else {
ERROR("format_kairosdb: Unknown data source type: %i", ds->ds[ds_idx].type);
sfree(rates);
- return (-1);
+ return -1;
}
BUFFER_ADD("]]");
DEBUG("format_kairosdb: values_to_kairosdb: buffer = %s;", buffer);
sfree(rates);
- return (0);
+ return 0;
} /* }}} int values_to_kairosdb */
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, int data_ttl,
+ char const *metrics_prefix) {
char temp[512];
size_t offset = 0;
int status;
#define BUFFER_ADD(...) \
do { \
- status = ssnprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
+ status = snprintf(buffer + offset, buffer_size - offset, __VA_ARGS__); \
if (status < 1) \
- return (-1); \
+ return -1; \
else if (((size_t)status) >= (buffer_size - offset)) \
- return (-ENOMEM); \
+ return -ENOMEM; \
else \
offset += ((size_t)status); \
} while (0)
do { \
status = kairosdb_escape_string(temp, sizeof(temp), (value)); \
if (status != 0) \
- return (status); \
+ return status; \
BUFFER_ADD(",\"%s\": %s", (key), temp); \
} while (0)
for (size_t i = 0; i < ds->ds_num; i++) {
/* All value lists have a leading comma. The first one will be replaced with
* a square bracket in `format_kairosdb_finalize'. */
- BUFFER_ADD(",{");
+ BUFFER_ADD(",{\"name\":\"");
- BUFFER_ADD("\"name\":\"collectd");
+ if (metrics_prefix != NULL) {
+ BUFFER_ADD("%s.", metrics_prefix);
+ }
- BUFFER_ADD(".%s", vl->plugin);
+ BUFFER_ADD("%s", vl->plugin);
status = values_to_kairosdb(temp, sizeof(temp), ds, vl, store_rates, i);
if (status != 0)
- return (status);
+ return status;
BUFFER_ADD("\", \"datapoints\": %s", temp);
memset(temp, 0, sizeof(temp));
+ if (data_ttl != 0)
+ BUFFER_ADD(", \"ttl\": %i", data_ttl);
+
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);
DEBUG("format_kairosdb: value_list_to_kairosdb: buffer = %s;", buffer);
- return (0);
+ return 0;
} /* }}} int value_list_to_kairosdb */
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, int data_ttl,
+ char const *metrics_prefix) {
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, data_ttl,
+ metrics_prefix);
if (status != 0)
- return (status);
+ return status;
temp_size = strlen(temp);
memcpy(buffer + (*ret_buffer_fill), temp, temp_size + 1);
(*ret_buffer_fill) += temp_size;
(*ret_buffer_free) -= temp_size;
- return (0);
+ return 0;
} /* }}} int format_kairosdb_value_list_nocheck */
int format_kairosdb_initialize(char *buffer, /* {{{ */
if ((buffer == NULL) || (ret_buffer_fill == NULL) ||
(ret_buffer_free == NULL))
- return (-EINVAL);
+ return -EINVAL;
buffer_fill = *ret_buffer_fill;
buffer_free = *ret_buffer_free;
buffer_fill = 0;
if (buffer_free < 3)
- return (-ENOMEM);
+ return -ENOMEM;
memset(buffer, 0, buffer_free);
*ret_buffer_fill = buffer_fill;
*ret_buffer_free = buffer_free;
- return (0);
+ return 0;
} /* }}} int format_kairosdb_initialize */
int format_kairosdb_finalize(char *buffer, /* {{{ */
if ((buffer == NULL) || (ret_buffer_fill == NULL) ||
(ret_buffer_free == NULL))
- return (-EINVAL);
+ return -EINVAL;
if (*ret_buffer_free < 2)
- return (-ENOMEM);
+ return -ENOMEM;
/* Replace the leading comma added in `value_list_to_kairosdb' with a square
* bracket. */
if (buffer[0] != ',')
- return (-EINVAL);
+ return -EINVAL;
buffer[0] = '[';
pos = *ret_buffer_fill;
(*ret_buffer_fill)++;
(*ret_buffer_free)--;
- return (0);
+ return 0;
} /* }}} int format_kairosdb_finalize */
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, int data_ttl,
+ char const *metrics_prefix) {
if ((buffer == NULL) || (ret_buffer_fill == NULL) ||
(ret_buffer_free == NULL) || (ds == NULL) || (vl == NULL))
- return (-EINVAL);
+ return -EINVAL;
if (*ret_buffer_free < 3)
- return (-ENOMEM);
+ return -ENOMEM;
- return (format_kairosdb_value_list_nocheck(
+ 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, data_ttl,
+ metrics_prefix);
} /* }}} int format_kairosdb_value_list */
/* vim: set sw=2 sts=2 et fdm=marker : */
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 data_ttl,
+ char const *metrics_prefix);
int format_kairosdb_finalize(char *buffer, size_t *ret_buffer_fill,
size_t *ret_buffer_free);
--- /dev/null
+/**
+ * collectd - src/utils_ignorelist.c
+ * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
+ * Copyright (C) 2008 Florian Forster <octo at collectd.org>
+ *
+ * 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 <lubek at users.sourceforge.net>
+ * Florian Forster <octo at collectd.org>
+ **/
+/**
+ * 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) */
--- /dev/null
+/**
+ * collectd - src/utils_ignorelist.h
+ * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
+ *
+ * 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 <lubek at users.sourceforge.net>
+ **/
+/**
+ * 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 <regex.h>
+#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 */
lc = calloc(1, sizeof(*lc));
if (lc == NULL)
- return (NULL);
+ return NULL;
lc->bin_width = HISTOGRAM_DEFAULT_BIN_WIDTH;
latency_counter_reset(lc);
- return (lc);
+ return lc;
} /* }}} latency_counter_t *latency_counter_create */
void latency_counter_destroy(latency_counter_t *lc) /* {{{ */
cdtime_t latency_counter_get_min(latency_counter_t *lc) /* {{{ */
{
if (lc == NULL)
- return (0);
- return (lc->min);
+ return 0;
+ return lc->min;
} /* }}} cdtime_t latency_counter_get_min */
cdtime_t latency_counter_get_max(latency_counter_t *lc) /* {{{ */
{
if (lc == NULL)
- return (0);
- return (lc->max);
+ return 0;
+ return lc->max;
} /* }}} cdtime_t latency_counter_get_max */
cdtime_t latency_counter_get_sum(latency_counter_t *lc) /* {{{ */
{
if (lc == NULL)
- return (0);
- return (lc->sum);
+ return 0;
+ return lc->sum;
} /* }}} cdtime_t latency_counter_get_sum */
size_t latency_counter_get_num(latency_counter_t *lc) /* {{{ */
{
if (lc == NULL)
- return (0);
- return (lc->num);
+ return 0;
+ return lc->num;
} /* }}} size_t latency_counter_get_num */
cdtime_t latency_counter_get_average(latency_counter_t *lc) /* {{{ */
double average;
if ((lc == NULL) || (lc->num == 0))
- return (0);
+ return 0;
average = CDTIME_T_TO_DOUBLE(lc->sum) / ((double)lc->num);
- return (DOUBLE_TO_CDTIME_T(average));
+ return DOUBLE_TO_CDTIME_T(average);
} /* }}} cdtime_t latency_counter_get_average */
cdtime_t latency_counter_get_percentile(latency_counter_t *lc, /* {{{ */
size_t i;
if ((lc == NULL) || (lc->num == 0) || !((percent > 0.0) && (percent < 100.0)))
- return (0);
+ return 0;
/* Find index i so that at least "percent" events are within i+1 ms. */
percent_upper = 0.0;
}
if (i >= HISTOGRAM_NUM_BINS)
- return (0);
+ return 0;
assert(percent_upper >= percent);
assert(percent_lower < percent);
if (i == 0)
- return (lc->bin_width);
+ return lc->bin_width;
latency_lower = ((cdtime_t)i) * lc->bin_width;
p = (percent - percent_lower) / (percent_upper - percent_lower);
DEBUG("latency_counter_get_percentile: latency_interpolated = %.3f",
CDTIME_T_TO_DOUBLE(latency_interpolated));
- return (latency_interpolated);
+ return latency_interpolated;
} /* }}} cdtime_t latency_counter_get_percentile */
double latency_counter_get_rate(const latency_counter_t *lc, /* {{{ */
cdtime_t lower, cdtime_t upper,
const cdtime_t now) {
if ((lc == NULL) || (lc->num == 0))
- return (NAN);
+ return NAN;
if (upper && (upper < lower))
- return (NAN);
+ return NAN;
if (lower == upper)
- return (0);
+ return 0;
/* Buckets have an exclusive lower bound and an inclusive upper bound. That
* means that the first bucket, index 0, represents (0-bin_width]. That means
/* lower is greater than the longest latency observed => rate is zero. */
if (lower_bin >= HISTOGRAM_NUM_BINS)
- return (0);
+ return 0;
cdtime_t upper_bin = HISTOGRAM_NUM_BINS - 1;
if (upper)
return sum / (CDTIME_T_TO_DOUBLE(now - lc->start_time));
} /* }}} double latency_counter_get_rate */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
*/
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 : */
* Pavel Rochnyack <pavel2000 at ngs.ru>
*/
-#include "common.h"
#include "utils_latency_config.h"
+#include "common.h"
#include "collectd.h"
static int latency_config_add_percentile(latency_config_t *conf,
DOUBLE_TO_CDTIME_T(ci->values[1].value.number);
conf->buckets_num++;
- return (0);
+ return 0;
} /* int latency_config_add_bucket */
int latency_config(latency_config_t *conf, oconfig_item_t *ci,
status = latency_config_add_percentile(conf, child, plugin);
else if (strcasecmp("Bucket", child->key) == 0)
status = latency_config_add_bucket(conf, child, plugin);
+ else if (strcasecmp("BucketType", child->key) == 0)
+ status = cf_util_get_string(child, &conf->bucket_type);
else
WARNING("%s plugin: \"%s\" is not a valid option within a \"%s\" block.",
plugin, child->key, ci->key);
return ENOMEM;
}
+ if (src.bucket_type != NULL) {
+ dst->bucket_type = strdup(src.bucket_type);
+ if (dst->bucket_type == NULL) {
+ latency_config_free(*dst);
+ return ENOMEM;
+ }
+ }
+
memmove(dst->percentile, src.percentile,
dst->percentile_num * sizeof(*dst->percentile));
memmove(dst->buckets, src.buckets, dst->buckets_num * sizeof(*dst->buckets));
void latency_config_free(latency_config_t conf) {
sfree(conf.percentile);
sfree(conf.buckets);
+ sfree(conf.bucket_type);
} /* void latency_config_free */
latency_bucket_t *buckets;
size_t buckets_num;
+ char *bucket_type;
/*
_Bool lower;
END_TEST;
}
-
-/* vim: set sw=2 sts=2 et : */
* GCC will complain about the macro definition. */
#define DONT_POISON_SPRINTF_YET
-#include "common.h"
#include "utils_lua.h"
+#include "common.h"
static int ltoc_values(lua_State *L, /* {{{ */
const data_set_t *ds, value_t *ret_values) {
if (!lua_istable(L, -1)) {
WARNING("ltoc_values: not a table");
- return (-1);
+ return -1;
}
/* Push initial key */
WARNING("ltoc_values: invalid size for datasource \"%s\": expected %zu, "
"got %zu",
ds->type, ds->ds_num, i);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int ltoc_values */
static int ltoc_table_values(lua_State *L, int idx, /* {{{ */
"value, not a table.",
lua_typename(L, lua_type(L, -1)));
lua_pop(L, 1);
- return (-1);
+ return -1;
}
vl->values_len = ds->ds_num;
ERROR("utils_lua: calloc failed.");
vl->values_len = 0;
lua_pop(L, 1);
- return (-1);
+ return -1;
}
int status = ltoc_values(L, ds, vl->values);
sfree(vl->values);
}
- return (status);
+ return status;
} /* }}} int ltoc_table_values */
static int luaC_pushvalues(lua_State *L, const data_set_t *ds,
lua_settable(L, -3);
}
- return (0);
+ return 0;
} /* }}} int luaC_pushvalues */
static int luaC_pushdstypes(lua_State *L, const data_set_t *ds) /* {{{ */
lua_settable(L, -3);
}
- return (0);
+ return 0;
} /* }}} int luaC_pushdstypes */
static int luaC_pushdsnames(lua_State *L, const data_set_t *ds) /* {{{ */
lua_settable(L, -3);
}
- return (0);
+ return 0;
} /* }}} int luaC_pushdsnames */
/*
cdtime_t luaC_tocdtime(lua_State *L, int idx) /* {{{ */
{
if (!lua_isnumber(L, /* stack pos = */ idx))
- return (0);
+ return 0;
double d = lua_tonumber(L, idx);
- return (DOUBLE_TO_CDTIME_T(d));
+ return DOUBLE_TO_CDTIME_T(d);
} /* }}} int ltoc_table_cdtime */
int luaC_tostringbuffer(lua_State *L, int idx, /* {{{ */
char *buffer, size_t buffer_size) {
const char *str = lua_tostring(L, idx);
if (str == NULL)
- return (-1);
+ return -1;
sstrncpy(buffer, str, buffer_size);
- return (0);
+ return 0;
} /* }}} int luaC_tostringbuffer */
value_t luaC_tovalue(lua_State *L, int idx, int ds_type) /* {{{ */
value_t v = {0};
if (!lua_isnumber(L, idx))
- return (v);
+ return v;
if (ds_type == DS_TYPE_GAUGE)
v.gauge = (gauge_t)lua_tonumber(L, /* stack pos = */ -1);
else if (ds_type == DS_TYPE_ABSOLUTE)
v.absolute = (absolute_t)lua_tointeger(L, /* stack pos = */ -1);
- return (v);
+ return v;
} /* }}} value_t luaC_tovalue */
value_list_t *luaC_tovaluelist(lua_State *L, int idx) /* {{{ */
/* Check that idx is in the valid range */
if ((idx < 1) || (idx > lua_gettop(L))) {
DEBUG("luaC_tovaluelist: idx(%d), top(%d)", idx, stack_top_before);
- return (NULL);
+ return NULL;
}
value_list_t *vl = calloc(1, sizeof(*vl));
if (vl == NULL) {
DEBUG("luaC_tovaluelist: calloc failed");
- return (NULL);
+ return NULL;
}
/* Push initial key */
if (ds == NULL) {
INFO("utils_lua: Unable to lookup type \"%s\".", vl->type);
sfree(vl);
- return (NULL);
+ return NULL;
}
int status = ltoc_table_values(L, idx, ds, vl);
if (status != 0) {
WARNING("utils_lua: ltoc_table_values failed.");
sfree(vl);
- return (NULL);
+ return NULL;
}
#if COLLECT_DEBUG
assert(stack_top_before == lua_gettop(L));
#endif
- return (vl);
+ return vl;
} /* }}} value_list_t *luaC_tovaluelist */
int luaC_pushcdtime(lua_State *L, cdtime_t t) /* {{{ */
double d = CDTIME_T_TO_DOUBLE(t);
lua_pushnumber(L, (lua_Number)d);
- return (0);
+ return 0;
} /* }}} int luaC_pushcdtime */
int luaC_pushvalue(lua_State *L, value_t v, int ds_type) /* {{{ */
else if (ds_type == DS_TYPE_ABSOLUTE)
lua_pushinteger(L, (lua_Integer)v.absolute);
else
- return (-1);
- return (0);
+ return -1;
+ return 0;
} /* }}} int luaC_pushvalue */
int luaC_pushvaluelist(lua_State *L, const data_set_t *ds,
luaC_pushcdtime(L, vl->interval);
lua_setfield(L, -2, "interval");
- return (0);
+ return 0;
} /* }}} int luaC_pushvaluelist */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
const value_list_t *vl);
#endif /* UTILS_LUA_H */
-/* vim: set sw=2 sts=2 et fdm=marker : */
size_t ret_len;
if ((begin < 0) || (end < 0) || (begin >= end))
- return (NULL);
+ return NULL;
if ((size_t)end > (strlen(str) + 1)) {
ERROR("utils_match: match_substr: `end' points after end of string.");
- return (NULL);
+ return NULL;
}
ret_len = end - begin;
ret = malloc(ret_len + 1);
if (ret == NULL) {
ERROR("utils_match: match_substr: malloc failed.");
- return (NULL);
+ return NULL;
}
sstrncpy(ret, str + begin, ret_len + 1);
- return (ret);
+ return ret;
} /* char *match_substr */
static int default_callback(const char __attribute__((unused)) * str,
if (data->ds_type & UTILS_MATCH_CF_GAUGE_INC) {
data->value.gauge = isnan(data->value.gauge) ? 1 : data->value.gauge + 1;
data->values_num++;
- return (0);
+ return 0;
}
if (matches_num < 2)
- return (-1);
+ return -1;
value = (gauge_t)strtod(matches[1], &endptr);
if (matches[1] == endptr)
- return (-1);
+ return -1;
if (data->ds_type & UTILS_MATCH_CF_GAUGE_DIST) {
latency_counter_add(data->latency, DOUBLE_TO_CDTIME_T(value));
data->values_num++;
- return (0);
+ return 0;
}
if ((data->values_num == 0) ||
data->value.gauge += value;
} else {
ERROR("utils_match: default_callback: obj->ds_type is invalid!");
- return (-1);
+ return -1;
}
data->values_num++;
if (data->ds_type & UTILS_MATCH_CF_COUNTER_INC) {
data->value.counter++;
data->values_num++;
- return (0);
+ return 0;
}
if (matches_num < 2)
- return (-1);
+ return -1;
value = (counter_t)strtoull(matches[1], &endptr, 0);
if (matches[1] == endptr)
- return (-1);
+ return -1;
if (data->ds_type & UTILS_MATCH_CF_COUNTER_SET)
data->value.counter = value;
data->value.counter += value;
else {
ERROR("utils_match: default_callback: obj->ds_type is invalid!");
- return (-1);
+ return -1;
}
data->values_num++;
if (data->ds_type & UTILS_MATCH_CF_DERIVE_INC) {
data->value.derive++;
data->values_num++;
- return (0);
+ return 0;
}
if (matches_num < 2)
- return (-1);
+ return -1;
value = (derive_t)strtoll(matches[1], &endptr, 0);
if (matches[1] == endptr)
- return (-1);
+ return -1;
if (data->ds_type & UTILS_MATCH_CF_DERIVE_SET)
data->value.derive = value;
data->value.derive += value;
else {
ERROR("utils_match: default_callback: obj->ds_type is invalid!");
- return (-1);
+ return -1;
}
data->values_num++;
char *endptr = NULL;
if (matches_num < 2)
- return (-1);
+ return -1;
value = (absolute_t)strtoull(matches[1], &endptr, 0);
if (matches[1] == endptr)
- return (-1);
+ return -1;
if (data->ds_type & UTILS_MATCH_CF_ABSOLUTE_SET)
data->value.absolute = value;
else {
ERROR("utils_match: default_callback: obj->ds_type is invalid!");
- return (-1);
+ return -1;
}
data->values_num++;
} else {
ERROR("utils_match: default_callback: obj->ds_type is invalid!");
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int default_callback */
static void match_simple_free(void *data) {
obj = calloc(1, sizeof(*obj));
if (obj == NULL)
- return (NULL);
+ return NULL;
status = regcomp(&obj->regex, regex, REG_EXTENDED | REG_NEWLINE);
if (status != 0) {
ERROR("Compiling the regular expression \"%s\" failed.", regex);
sfree(obj);
- return (NULL);
+ return NULL;
}
obj->flags |= UTILS_MATCH_FLAGS_REGEX;
ERROR("Compiling the excluding regular expression \"%s\" failed.",
excluderegex);
sfree(obj);
- return (NULL);
+ return NULL;
}
obj->flags |= UTILS_MATCH_FLAGS_EXCLUDE_REGEX;
}
obj->user_data = user_data;
obj->free = free_user_data;
- return (obj);
+ return obj;
} /* cu_match_t *match_create_callback */
cu_match_t *match_create_simple(const char *regex, const char *excluderegex,
user_data = calloc(1, sizeof(*user_data));
if (user_data == NULL)
- return (NULL);
+ return NULL;
user_data->ds_type = match_ds_type;
if ((match_ds_type & UTILS_MATCH_DS_TYPE_GAUGE) &&
if (user_data->latency == NULL) {
ERROR("match_create_simple(): latency_counter_create() failed.");
free(user_data);
- return (NULL);
+ return NULL;
}
}
latency_counter_destroy(user_data->latency);
sfree(user_data);
- return (NULL);
+ return NULL;
}
- return (obj);
+ return obj;
} /* cu_match_t *match_create_simple */
void match_value_reset(cu_match_value_t *mv) {
/* Reset GAUGE metrics only and except GAUGE_PERSIST. */
if ((mv->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) &&
!(mv->ds_type & UTILS_MATCH_CF_GAUGE_PERSIST)) {
- mv->value.gauge = NAN;
+ mv->value.gauge = (mv->ds_type & UTILS_MATCH_CF_GAUGE_INC) ? 0 : NAN;
mv->values_num = 0;
}
} /* }}} void match_value_reset */
size_t matches_num;
if ((obj == NULL) || (str == NULL))
- return (-1);
+ return -1;
if (obj->flags & UTILS_MATCH_FLAGS_EXCLUDE_REGEX) {
status =
/* Regex did match, so exclude this line */
if (status == 0) {
DEBUG("ExludeRegex matched, don't count that line\n");
- return (0);
+ return 0;
}
}
/* Regex did not match */
if (status != 0)
- return (0);
+ return 0;
for (matches_num = 0; matches_num < STATIC_ARRAY_SIZE(matches);
matches_num++) {
sfree(matches[i]);
}
- return (status);
+ return status;
} /* int match_apply */
void *match_get_user_data(cu_match_t *obj) {
if (obj == NULL)
- return (NULL);
- return (obj->user_data);
+ return NULL;
+ return obj->user_data;
} /* void *match_get_user_data */
-
-/* vim: set sw=2 sts=2 ts=8 : */
void *match_get_user_data(cu_match_t *obj);
#endif /* UTILS_MATCH_H */
-
-/* vim: set sw=2 sts=2 ts=8 : */
* (This is useful, if the cdrom on /dev/hdc must not
* be accessed.)
*/
- ssnprintf(device, sizeof(device), "%s/%s", DEVLABELDIR, ptname);
+ snprintf(device, sizeof(device), "%s/%s", DEVLABELDIR, ptname);
if (!get_label_uuid(device, &label, uuid)) {
uuidcache_addentry(sstrdup(device), label, uuid);
}
static unsigned char fromhex(char c) {
if (isdigit((int)c)) {
- return (c - '0');
+ return c - '0';
} else if (islower((int)c)) {
- return (c - 'a' + 10);
+ return c - 'a' + 10;
} else {
- return (c - 'A' + 10);
+ return c - 'A' + 10;
}
}
char *rc;
if (optstr == NULL) {
- return (NULL);
+ return NULL;
} else if (strncmp(optstr, "UUID=", 5) == 0) {
DEBUG("utils_mount: TODO: check UUID= code!");
rc = get_spec_by_uuid(optstr + 5);
last->next = NULL;
} /* for(p = mntlist; p; p = p->next) */
- return (last);
+ return last;
} /* cu_mount_t *cu_mount_listmntent(void) */
/* #endif HAVE_LISTMNTENT */
DEBUG("utils_mount: getv?fsstat failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
#endif /* COLLECT_DEBUG */
- return (NULL);
+ return NULL;
}
if ((buf = calloc(bufsize, sizeof(*buf))) == NULL)
- return (NULL);
+ return NULL;
/* The bufsize needs to be passed in bytes. Really. This is not in the
* manpage.. -octo */
sstrerror(errno, errbuf, sizeof(errbuf)));
#endif /* COLLECT_DEBUG */
free(buf);
- return (NULL);
+ return NULL;
}
for (int i = 0; i < num; i++) {
free(buf);
- return (first);
+ return first;
}
/* #endif HAVE_GETVFSSTAT || HAVE_GETFSSTAT */
char errbuf[1024];
ERROR("fopen (%s): %s", COLLECTD_MNTTAB,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (NULL);
+ return NULL;
}
while (getmntent(fp, &mt) == 0) {
fclose(fp);
- return (first);
+ return first;
} /* static cu_mount_t *cu_mount_gen_getmntent (void) */
-/* #endif HAVE_TWO_GETMNTENT || HAVE_GEN_GETMNTENT || HAVE_SUN_GETMNTENT */
+ /* #endif HAVE_TWO_GETMNTENT || HAVE_GEN_GETMNTENT || HAVE_SUN_GETMNTENT */
#elif HAVE_SEQ_GETMNTENT
#warn "This version of `getmntent' hat not yet been implemented!"
char errbuf[1024];
ERROR("setmntent (%s): %s", COLLECTD_MNTTAB,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (NULL);
+ return NULL;
}
while (getmntent_r(fp, &me, mntbuf, sizeof(mntbuf))) {
endmntent(fp);
- DEBUG("utils_mount: return (0x%p)", (void *)first);
+ DEBUG("utils_mount: return 0x%p", (void *)first);
- return (first);
+ return first;
} /* HAVE_GETMNTENT_R */
#elif HAVE_ONE_GETMNTENT
char errbuf[1024];
ERROR("setmntent (%s): %s", COLLECTD_MNTTAB,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (NULL);
+ return NULL;
}
while ((me = getmntent(fp)) != NULL) {
endmntent(fp);
- DEBUG("utils_mount: return (0x%p)", (void *)first);
+ DEBUG("utils_mount: return 0x%p", (void *)first);
- return (first);
+ return first;
}
#endif /* HAVE_ONE_GETMNTENT */
cu_mount_t *last = NULL;
if (list == NULL)
- return (NULL);
+ return NULL;
if (*list != NULL) {
first = *list;
while ((last != NULL) && (last->next != NULL))
last = last->next;
- return (last);
+ return last;
} /* cu_mount_t *cu_mount_getlist(cu_mount_t **list) */
void cu_mount_freelist(cu_mount_t *list) {
OK(NULL == cu_mount_checkoption(line_bool, "tw", 1));
OK(NULL == cu_mount_checkoption(line_bool, "thr", 1));
- return (0);
+ return 0;
}
DEF_TEST(cu_mount_getoptionvalue) {
char line_opts[] = "foo=one,bar=two,qux=three";
OK(NULL == (v = cu_mount_getoptionvalue(line_bool, "four")));
sfree(v);
- return (0);
+ return 0;
}
int main(void) {
END_TEST;
}
-
-/* vim: set sw=2 sts=2 et : */
--- /dev/null
+/**
+ * collectd - src/utils_ovs.c
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ *of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to
+ *do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ *all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Volodymyr Mytnyk <volodymyrx.mytnyk@intel.com>
+ **/
+
+/* clang-format off */
+/*
+ * OVS DB API internal architecture diagram
+ * +------------------------------------------------------------------------------+
+ * |OVS plugin |OVS utils |
+ * | | +------------------------+ |
+ * | | | echo handler | JSON request/ |
+ * | | +--+ (ovs_db_table_echo_cb) +<---+---------+ update event/ |
+ * | | | | | | | result |
+ * | | | +------------------------+ | | |
+ * | | | | +----+---+--------+ |
+ * | +----------+ | | +------------------------+ | | | | |
+ * | | update | | | | update handler | | | YAJL | JSON | |
+ * | | callback +<-------+(ovs_db_table_update_cp)+<---+ | parser | reader | |
+ * | +----------+ | | | | | | | | |
+ * | | | +------------------------+ | +--------+---+----+ |
+ * | | | | ^ |
+ * | +----------+ | | +------------------------+ | | |
+ * | | result | | | | result handler | | | |
+ * | | callback +<-------+ (ovs_db_result_cb) +<---+ JSON raw | |
+ * | +----------+ | | | | data | |
+ * | | | +------------------------+ | |
+ * | | | | |
+ * | | | +------------------+ +------------+----+ |
+ * | +----------+ | | |thread| | |thread| | |
+ * | | init | | | | | reconnect | | |
+ * | | callback +<---------+ EVENT WORKER +<------------+ POLL WORKER | |
+ * | +----------+ | | +------------------+ +--------+--------+ |
+ * | | | ^ |
+ * +----------------+-------------------------------------------------------------+
+ * | |
+ * JSON|echo reply raw|data
+ * v v
+ * +-------------------+----------------------------------------------+-----------+
+ * | TCP/UNIX socket |
+ * +-------------------------------------------------------------------------------
+ */
+/* clang-format on */
+
+/* collectd headers */
+#include "collectd.h"
+
+#include "common.h"
+
+/* private headers */
+#include "utils_ovs.h"
+
+/* system libraries */
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_POLL_H
+#include <poll.h>
+#endif
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
+#include <semaphore.h>
+
+#define OVS_ERROR(fmt, ...) \
+ do { \
+ ERROR("ovs_utils: " fmt, ##__VA_ARGS__); \
+ } while (0)
+#define OVS_DEBUG(fmt, ...) \
+ do { \
+ DEBUG("%s:%d:%s(): " fmt, __FILE__, __LINE__, __FUNCTION__, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define OVS_DB_POLL_TIMEOUT 1 /* poll receive timeout (sec) */
+#define OVS_DB_POLL_READ_BLOCK_SIZE 512 /* read block size (bytes) */
+#define OVS_DB_DEFAULT_DB_NAME "Open_vSwitch"
+
+#define OVS_DB_EVENT_TIMEOUT 5 /* event thread timeout (sec) */
+#define OVS_DB_EVENT_TERMINATE 1
+#define OVS_DB_EVENT_CONN_ESTABLISHED 2
+#define OVS_DB_EVENT_CONN_TERMINATED 3
+
+#define OVS_DB_POLL_STATE_RUNNING 1
+#define OVS_DB_POLL_STATE_EXITING 2
+
+#define OVS_DB_SEND_REQ_TIMEOUT 5 /* send request timeout (sec) */
+
+#define OVS_YAJL_CALL(func, ...) \
+ do { \
+ yajl_gen_ret = yajl_gen_status_ok; \
+ if ((yajl_gen_ret = func(__VA_ARGS__)) != yajl_gen_status_ok) \
+ goto yajl_gen_failure; \
+ } while (0)
+#define OVS_YAJL_ERROR_BUFFER_SIZE 1024
+#define OVS_ERROR_BUFF_SIZE 512
+#define OVS_UID_STR_SIZE 17 /* 64-bit HEX string len + '\0' */
+
+/* JSON reader internal data */
+struct ovs_json_reader_s {
+ char *buff_ptr;
+ size_t buff_size;
+ size_t buff_offset;
+ size_t json_offset;
+};
+typedef struct ovs_json_reader_s ovs_json_reader_t;
+
+/* Result callback declaration */
+struct ovs_result_cb_s {
+ sem_t sync;
+ ovs_db_result_cb_t call;
+};
+typedef struct ovs_result_cb_s ovs_result_cb_t;
+
+/* Table callback declaration */
+struct ovs_table_cb_s {
+ ovs_db_table_cb_t call;
+};
+typedef struct ovs_table_cb_s ovs_table_cb_t;
+
+/* Callback declaration */
+struct ovs_callback_s {
+ uint64_t uid;
+ union {
+ ovs_result_cb_t result;
+ ovs_table_cb_t table;
+ };
+ struct ovs_callback_s *next;
+ struct ovs_callback_s *prev;
+};
+typedef struct ovs_callback_s ovs_callback_t;
+
+/* Event thread data declaration */
+struct ovs_event_thread_s {
+ pthread_t tid;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int value;
+};
+typedef struct ovs_event_thread_s ovs_event_thread_t;
+
+/* Poll thread data declaration */
+struct ovs_poll_thread_s {
+ pthread_t tid;
+ pthread_mutex_t mutex;
+ int state;
+};
+typedef struct ovs_poll_thread_s ovs_poll_thread_t;
+
+/* OVS DB internal data declaration */
+struct ovs_db_s {
+ ovs_poll_thread_t poll_thread;
+ ovs_event_thread_t event_thread;
+ pthread_mutex_t mutex;
+ ovs_callback_t *remote_cb;
+ ovs_db_callback_t cb;
+ char service[OVS_DB_ADDR_SERVICE_SIZE];
+ char node[OVS_DB_ADDR_NODE_SIZE];
+ char unix_path[OVS_DB_ADDR_NODE_SIZE];
+ int sock;
+};
+
+/* Global variables */
+static uint64_t ovs_uid = 0;
+static pthread_mutex_t ovs_uid_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* Post an event to event thread.
+ * Possible events are:
+ * OVS_DB_EVENT_TERMINATE
+ * OVS_DB_EVENT_CONN_ESTABLISHED
+ * OVS_DB_EVENT_CONN_TERMINATED
+ */
+static void ovs_db_event_post(ovs_db_t *pdb, int event) {
+ pthread_mutex_lock(&pdb->event_thread.mutex);
+ pdb->event_thread.value = event;
+ pthread_mutex_unlock(&pdb->event_thread.mutex);
+ pthread_cond_signal(&pdb->event_thread.cond);
+}
+
+/* Check if POLL thread is still running. Returns
+ * 1 if running otherwise 0 is returned */
+static _Bool ovs_db_poll_is_running(ovs_db_t *pdb) {
+ int state = 0;
+ pthread_mutex_lock(&pdb->poll_thread.mutex);
+ state = pdb->poll_thread.state;
+ pthread_mutex_unlock(&pdb->poll_thread.mutex);
+ return state == OVS_DB_POLL_STATE_RUNNING;
+}
+
+/* Generate unique identifier (UID). It is used by OVS DB API
+ * to set "id" field for any OVS DB JSON request. */
+static uint64_t ovs_uid_generate() {
+ uint64_t new_uid;
+ pthread_mutex_lock(&ovs_uid_mutex);
+ new_uid = ++ovs_uid;
+ pthread_mutex_unlock(&ovs_uid_mutex);
+ return new_uid;
+}
+
+/*
+ * Callback API. These function are used to store
+ * registered callbacks in OVS DB API.
+ */
+
+/* Add new callback into OVS DB object */
+static void ovs_db_callback_add(ovs_db_t *pdb, ovs_callback_t *new_cb) {
+ pthread_mutex_lock(&pdb->mutex);
+ if (pdb->remote_cb)
+ pdb->remote_cb->prev = new_cb;
+ new_cb->next = pdb->remote_cb;
+ new_cb->prev = NULL;
+ pdb->remote_cb = new_cb;
+ pthread_mutex_unlock(&pdb->mutex);
+}
+
+/* Remove callback from OVS DB object */
+static void ovs_db_callback_remove(ovs_db_t *pdb, ovs_callback_t *del_cb) {
+ pthread_mutex_lock(&pdb->mutex);
+ ovs_callback_t *pre_cb = del_cb->prev;
+ ovs_callback_t *next_cb = del_cb->next;
+
+ if (next_cb)
+ next_cb->prev = del_cb->prev;
+
+ if (pre_cb)
+ pre_cb->next = del_cb->next;
+ else
+ pdb->remote_cb = del_cb->next;
+
+ free(del_cb);
+ pthread_mutex_unlock(&pdb->mutex);
+}
+
+/* Remove all callbacks form OVS DB object */
+static void ovs_db_callback_remove_all(ovs_db_t *pdb) {
+ pthread_mutex_lock(&pdb->mutex);
+ while (pdb->remote_cb != NULL) {
+ ovs_callback_t *del_cb = pdb->remote_cb;
+ pdb->remote_cb = del_cb->next;
+ sfree(del_cb);
+ }
+ 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: [<json-value>, <table-updates>] */
+ if ((YAJL_GET_ARRAY(jparams) == NULL) ||
+ (YAJL_GET_ARRAY(jparams)->len != 2)) {
+ OVS_ERROR("invalid OVS DB request received");
+ return -1;
+ }
+
+ jvalue = YAJL_GET_ARRAY(jparams)->values[0];
+ jtable_updates = YAJL_GET_ARRAY(jparams)->values[1];
+ if ((!YAJL_IS_OBJECT(jtable_updates)) || (!YAJL_IS_STRING(jvalue))) {
+ OVS_ERROR("invalid OVS DB request id or table update received");
+ return -1;
+ }
+
+ /* find registered callback based on <json-value> */
+ pthread_mutex_lock(&pdb->mutex);
+ cb = ovs_db_table_callback_get(pdb, jvalue);
+ if (cb == NULL || cb->table.call == NULL) {
+ OVS_ERROR("No OVS DB table update callback found");
+ pthread_mutex_unlock(&pdb->mutex);
+ return -1;
+ }
+
+ /* call registered callback */
+ cb->table.call(jtable_updates);
+ pthread_mutex_unlock(&pdb->mutex);
+ return 0;
+}
+
+/* OVS DB result request handler.
+ * This callback is called by POLL thread if OVS DB
+ * result reply is received from the DB server.
+ * Once registered callback found, it's called
+ * by this handler. */
+static int ovs_db_result_cb(ovs_db_t *pdb, yajl_val jnode) {
+ ovs_callback_t *cb = NULL;
+ yajl_val jresult;
+ yajl_val jerror;
+ yajl_val jid;
+ const char *result_path[] = {"result", NULL};
+ const char *error_path[] = {"error", NULL};
+ const char *id_path[] = {"id", NULL};
+
+ jresult = yajl_tree_get(jnode, result_path, yajl_t_any);
+ jerror = yajl_tree_get(jnode, error_path, yajl_t_any);
+ jid = yajl_tree_get(jnode, id_path, yajl_t_string);
+
+ /* check & get result attributes */
+ if (!jresult || !jerror || !jid)
+ return -1;
+
+ /* try to find registered callback */
+ pthread_mutex_lock(&pdb->mutex);
+ cb = ovs_db_table_callback_get(pdb, jid);
+ if (cb != NULL && cb->result.call != NULL) {
+ /* call registered callback */
+ cb->result.call(jresult, jerror);
+ /* unlock owner of the reply */
+ sem_post(&cb->result.sync);
+ }
+
+ pthread_mutex_unlock(&pdb->mutex);
+ return 0;
+}
+
+/* Handle JSON data (one request) and call
+ * appropriate event OVS DB handler. Currently,
+ * update callback 'ovs_db_table_update_cb' and
+ * result callback 'ovs_db_result_cb' is supported.
+ */
+static int ovs_db_json_data_process(ovs_db_t *pdb, const char *data,
+ size_t len) {
+ const char *method = NULL;
+ char yajl_errbuf[OVS_YAJL_ERROR_BUFFER_SIZE];
+ const char *method_path[] = {"method", NULL};
+ const char *result_path[] = {"result", NULL};
+ char *sjson = NULL;
+ yajl_val jnode, jval;
+
+ /* duplicate the data to make null-terminated string
+ * required for yajl_tree_parse() */
+ if ((sjson = calloc(1, len + 1)) == NULL)
+ return -1;
+
+ sstrncpy(sjson, data, len + 1);
+ OVS_DEBUG("[len=%zu] %s", len, sjson);
+
+ /* parse json data */
+ jnode = yajl_tree_parse(sjson, yajl_errbuf, sizeof(yajl_errbuf));
+ if (jnode == NULL) {
+ OVS_ERROR("yajl_tree_parse() %s", yajl_errbuf);
+ sfree(sjson);
+ return -1;
+ }
+
+ /* get method name */
+ if ((jval = yajl_tree_get(jnode, method_path, yajl_t_string)) != NULL) {
+ 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){0};
+ /* 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 */
+/* XXX: Must hold pdb->mutex when calling! */
+static int ovs_db_event_thread_destroy(ovs_db_t *pdb) {
+ if (pthread_equal(pdb->event_thread.tid, (pthread_t){0})) {
+ /* already destroyed */
+ return 0;
+ }
+ ovs_db_event_post(pdb, OVS_DB_EVENT_TERMINATE);
+ if (pthread_join(pdb->event_thread.tid, NULL) != 0)
+ return -1;
+ /* Event thread always holds the thread mutex when
+ * performs some task (handles event) and releases it when
+ * while sleeping. Thus, if event thread exits, the mutex
+ * remains locked */
+ pthread_mutex_unlock(&pdb->event_thread.mutex);
+ pthread_mutex_destroy(&pdb->event_thread.mutex);
+ pthread_cond_destroy(&pdb->event_thread.cond);
+ pdb->event_thread.tid = (pthread_t){0};
+ return 0;
+}
+
+/* Initialize POLL thread */
+static int ovs_db_poll_thread_init(ovs_db_t *pdb) {
+ pdb->poll_thread.tid = (pthread_t){0};
+ /* 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 */
+/* XXX: Must hold pdb->mutex when calling! */
+static int ovs_db_poll_thread_destroy(ovs_db_t *pdb) {
+ if (pthread_equal(pdb->poll_thread.tid, (pthread_t){0})) {
+ /* already destroyed */
+ return 0;
+ }
+ /* change thread state */
+ pthread_mutex_lock(&pdb->poll_thread.mutex);
+ pdb->poll_thread.state = OVS_DB_POLL_STATE_EXITING;
+ pthread_mutex_unlock(&pdb->poll_thread.mutex);
+ /* join the thread */
+ if (pthread_join(pdb->poll_thread.tid, NULL) != 0)
+ return -1;
+ pthread_mutex_destroy(&pdb->poll_thread.mutex);
+ pdb->poll_thread.tid = (pthread_t){0};
+ 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 = calloc(1, sizeof(*pdb));
+ if (pdb == NULL)
+ return NULL;
+ pdb->sock = -1;
+
+ /* 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 */
+ 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();
+ snprintf(uid_buff, sizeof(uid_buff), "%" PRIX64, uid);
+ OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, uid_buff);
+
+ OVS_YAJL_CALL(yajl_gen_map_close, jgen);
+
+ if (cb) {
+ /* register result callback */
+ if ((new_cb = calloc(1, sizeof(ovs_callback_t))) == NULL)
+ goto yajl_gen_failure;
+
+ /* add new callback to front */
+ sem_init(&new_cb->result.sync, 0, 0);
+ new_cb->result.call = cb;
+ new_cb->uid = uid;
+ ovs_db_callback_add(pdb, new_cb);
+ }
+
+ /* send the request */
+ OVS_YAJL_CALL(yajl_gen_get_buf, jgen, (const unsigned char **)&req, &req_len);
+ OVS_DEBUG("%s", req);
+ if (!ovs_db_data_send(pdb, req, req_len)) {
+ if (cb) {
+ /* wait for result */
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += OVS_DB_SEND_REQ_TIMEOUT;
+ if (sem_timedwait(&new_cb->result.sync, &ts) < 0) {
+ OVS_ERROR("%s() no replay received within %d sec", __FUNCTION__,
+ OVS_DB_SEND_REQ_TIMEOUT);
+ ret = (-1);
+ }
+ }
+ } else {
+ OVS_ERROR("ovs_db_data_send() failed");
+ ret = (-1);
+ }
+
+yajl_gen_failure:
+ if (new_cb) {
+ /* destroy callback */
+ sem_destroy(&new_cb->result.sync);
+ ovs_db_callback_remove(pdb, new_cb);
+ }
+
+ /* release memory */
+ yajl_gen_clear(jgen);
+ return (yajl_gen_ret != yajl_gen_status_ok) ? (-1) : ret;
+}
+
+int ovs_db_table_cb_register(ovs_db_t *pdb, const char *tb_name,
+ const char **tb_column,
+ ovs_db_table_cb_t update_cb,
+ ovs_db_result_cb_t result_cb, unsigned int flags) {
+ yajl_gen jgen;
+ yajl_gen_status yajl_gen_ret;
+ ovs_callback_t *new_cb = NULL;
+ char uid_str[OVS_UID_STR_SIZE];
+ char *params;
+ size_t params_len;
+ int ovs_db_ret = 0;
+
+ /* sanity check */
+ if (pdb == NULL || tb_name == NULL || update_cb == NULL)
+ return -1;
+
+ /* allocate new update callback */
+ if ((new_cb = calloc(1, sizeof(ovs_callback_t))) == NULL)
+ return -1;
+
+ /* init YAJL generator */
+ if ((jgen = yajl_gen_alloc(NULL)) == NULL) {
+ sfree(new_cb);
+ return -1;
+ }
+
+ /* add new callback to front */
+ new_cb->table.call = update_cb;
+ new_cb->uid = ovs_uid_generate();
+ ovs_db_callback_add(pdb, new_cb);
+
+ /* make update notification request
+ * [<db-name>, <json-value>, <monitor-requests>] */
+ OVS_YAJL_CALL(yajl_gen_array_open, jgen);
+ {
+ OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, OVS_DB_DEFAULT_DB_NAME);
+
+ /* uid string <json-value> */
+ snprintf(uid_str, sizeof(uid_str), "%" PRIX64, new_cb->uid);
+ OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, uid_str);
+
+ /* <monitor-requests> */
+ OVS_YAJL_CALL(yajl_gen_map_open, jgen);
+ {
+ OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, tb_name);
+ OVS_YAJL_CALL(yajl_gen_array_open, jgen);
+ {
+ /* <monitor-request> */
+ OVS_YAJL_CALL(yajl_gen_map_open, jgen);
+ {
+ if (tb_column) {
+ /* columns within the table to be monitored */
+ OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "columns");
+ OVS_YAJL_CALL(yajl_gen_array_open, jgen);
+ for (; *tb_column; tb_column++)
+ OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, *tb_column);
+ OVS_YAJL_CALL(yajl_gen_array_close, jgen);
+ }
+ /* specify select option */
+ OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "select");
+ {
+ OVS_YAJL_CALL(yajl_gen_map_open, jgen);
+ {
+ OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "initial");
+ OVS_YAJL_CALL(yajl_gen_bool, jgen,
+ flags & OVS_DB_TABLE_CB_FLAG_INITIAL);
+ OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "insert");
+ OVS_YAJL_CALL(yajl_gen_bool, jgen,
+ flags & OVS_DB_TABLE_CB_FLAG_INSERT);
+ OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "delete");
+ OVS_YAJL_CALL(yajl_gen_bool, jgen,
+ flags & OVS_DB_TABLE_CB_FLAG_DELETE);
+ OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "modify");
+ OVS_YAJL_CALL(yajl_gen_bool, jgen,
+ flags & OVS_DB_TABLE_CB_FLAG_MODIFY);
+ }
+ OVS_YAJL_CALL(yajl_gen_map_close, jgen);
+ }
+ }
+ OVS_YAJL_CALL(yajl_gen_map_close, jgen);
+ }
+ OVS_YAJL_CALL(yajl_gen_array_close, jgen);
+ }
+ OVS_YAJL_CALL(yajl_gen_map_close, jgen);
+ }
+ OVS_YAJL_CALL(yajl_gen_array_close, jgen);
+
+ /* make a request to subscribe to given table */
+ OVS_YAJL_CALL(yajl_gen_get_buf, jgen, (const unsigned char **)¶ms,
+ ¶ms_len);
+ if (ovs_db_send_request(pdb, "monitor", params, result_cb) < 0) {
+ OVS_ERROR("Failed to subscribe to \"%s\" table", tb_name);
+ ovs_db_ret = (-1);
+ }
+
+yajl_gen_failure:
+ /* release memory */
+ yajl_gen_clear(jgen);
+ return ovs_db_ret;
+}
+
+int ovs_db_destroy(ovs_db_t *pdb) {
+ int ovs_db_ret = 0;
+ int ret = 0;
+
+ /* sanity check */
+ if (pdb == NULL)
+ return -1;
+
+ /* try to lock the structure before releasing */
+ if ((ret = pthread_mutex_lock(&pdb->mutex))) {
+ OVS_ERROR("pthread_mutex_lock() DB mutex lock failed (%d)", ret);
+ return -1;
+ }
+
+ /* stop poll thread */
+ if (ovs_db_event_thread_destroy(pdb) < 0) {
+ OVS_ERROR("destroy poll thread failed");
+ ovs_db_ret = -1;
+ }
+
+ /* stop event thread */
+ if (ovs_db_poll_thread_destroy(pdb) < 0) {
+ OVS_ERROR("stop event thread failed");
+ ovs_db_ret = -1;
+ }
+
+ pthread_mutex_unlock(&pdb->mutex);
+
+ /* unsubscribe callbacks */
+ ovs_db_callback_remove_all(pdb);
+
+ /* close connection */
+ if (pdb->sock >= 0)
+ close(pdb->sock);
+
+ /* release DB handler */
+ pthread_mutex_destroy(&pdb->mutex);
+ sfree(pdb);
+ return ovs_db_ret;
+}
+
+/*
+ * Public OVS utils API implementation
+ */
+
+/* Get YAJL value by key from YAJL dictionary
+ *
+ * EXAMPLE:
+ * {
+ * "key_a" : <YAJL return value>
+ * "key_b" : <YAJL return value>
+ * }
+ */
+yajl_val ovs_utils_get_value_by_key(yajl_val jval, const char *key) {
+ const char *obj_key = NULL;
+
+ /* check params */
+ if (!YAJL_IS_OBJECT(jval) || (key == NULL))
+ return NULL;
+
+ /* find a value by key */
+ for (size_t i = 0; i < YAJL_GET_OBJECT(jval)->len; i++) {
+ obj_key = YAJL_GET_OBJECT(jval)->keys[i];
+ if (strcmp(obj_key, key) == 0)
+ return YAJL_GET_OBJECT(jval)->values[i];
+ }
+
+ return NULL;
+}
+
+/* Get OVS DB map value by given map key
+ *
+ * FROM RFC7047:
+ *
+ * <pair>
+ * A 2-element JSON array that represents a pair within a database
+ * map. The first element is an <atom> that represents the key, and
+ * the second element is an <atom> that represents the value.
+ *
+ * <map>
+ * A 2-element JSON array that represents a database map value. The
+ * first element of the array must be the string "map", and the
+ * second element must be an array of zero or more <pair>s giving the
+ * values in the map. All of the <pair>s must have the same key and
+ * value types.
+ *
+ * EXAMPLE:
+ * [
+ * "map", [
+ * [ "key_a", <YAJL value>], [ "key_b", <YAJL value>], ...
+ * ]
+ * ]
+ */
+yajl_val ovs_utils_get_map_value(yajl_val jval, const char *key) {
+ size_t map_len = 0;
+ size_t array_len = 0;
+ yajl_val *map_values = NULL;
+ yajl_val *array_values = NULL;
+ const char *str_val = NULL;
+
+ /* check YAJL array */
+ if (!YAJL_IS_ARRAY(jval) || (key == NULL))
+ return NULL;
+
+ /* check a database map value (2-element, first one should be a string */
+ array_len = YAJL_GET_ARRAY(jval)->len;
+ array_values = YAJL_GET_ARRAY(jval)->values;
+ if ((array_len != 2) || (!YAJL_IS_STRING(array_values[0])) ||
+ (!YAJL_IS_ARRAY(array_values[1])))
+ return NULL;
+
+ /* check first element of the array */
+ str_val = YAJL_GET_STRING(array_values[0]);
+ if (strcmp("map", str_val) != 0)
+ return NULL;
+
+ /* try to find map value by map key */
+ map_len = YAJL_GET_ARRAY(array_values[1])->len;
+ map_values = YAJL_GET_ARRAY(array_values[1])->values;
+ for (size_t i = 0; i < map_len; i++) {
+ /* check YAJL array */
+ if (!YAJL_IS_ARRAY(map_values[i]))
+ break;
+
+ /* check a database pair value (2-element, first one represents a key
+ * and it should be a string in our case */
+ array_len = YAJL_GET_ARRAY(map_values[i])->len;
+ array_values = YAJL_GET_ARRAY(map_values[i])->values;
+ if ((array_len != 2) || (!YAJL_IS_STRING(array_values[0])))
+ break;
+
+ /* return map value if given key equals map key */
+ str_val = YAJL_GET_STRING(array_values[0]);
+ if (strcmp(key, str_val) == 0)
+ return array_values[1];
+ }
+ return NULL;
+}
--- /dev/null
+/**
+ * collectd - src/utils_ovs.h
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Volodymyr Mytnyk <volodymyrx.mytnyk@intel.com>
+ *
+ * Description:
+ * The OVS util module provides the following features:
+ * - Implements the OVS DB communication transport specified
+ * by RFC7047:
+ * * Connect/disconnect to OVS DB;
+ * * Recovery mechanism in case of OVS DB connection lost;
+ * * Subscription mechanism to OVS DB table update events
+ * (insert/modify/delete);
+ * * Send custom JSON request to OVS DB (poll table data, etc.)
+ * * Handling of echo request from OVS DB server to verify the
+ * liveness of the connection.
+ * - Provides YAJL helpers functions.
+ *
+ * OVS DB API User Guide:
+ * All OVS DB function/structure names begins from 'ovs_db_*' prefix. To
+ * start using OVS DB API, client (plugin) should initialize the OVS DB
+ * object (`ovs_db_t') by calling `ovs_db_init' function. It initializes
+ * internal data and creates two main workers (threads). The result of the
+ * function is a pointer to new OVS DB object which can be used by other
+ * OVS DB API later and must be released by `ovs_db_destroy' function if
+ * the object isn't needed anymore.
+ * Once OVS DB API is initialized, the `init_cb' callback is called if
+ * the connection to OVS DB has been established. This callback is called
+ * every time the OVS DB is reconnected. So, if the client registers table
+ * update event callbacks or does any other OVS DB setup that can be lost
+ * after OVS DB reconnecting, it should be done in `init_cb' callback.
+ * The `ovs_db_table_cb_register` function is used to register OVS DB
+ * table update event callback and receive the table update notification
+ * when requested event occurs (registered callback is called). See
+ * function API for more info.
+ * To send custom JSON-RPC request to OVS DB, the `ovs_db_send_request'
+ * function is used. Please note, that connection to OVS DB should be
+ * established otherwise the function will return error.
+ * To verify the liveness of established connection, the OVS DB server
+ * sends echo request to the client with a given interval. The OVS utils
+ * takes care about this request and handles it properly.
+ **/
+
+#ifndef UTILS_OVS_H
+#define UTILS_OVS_H
+
+#include <yajl/yajl_gen.h>
+#include <yajl/yajl_tree.h>
+
+/* Forward declaration */
+typedef struct ovs_db_s ovs_db_t;
+
+/* OVS DB callback type declaration */
+typedef void (*ovs_db_table_cb_t)(yajl_val jupdates);
+typedef void (*ovs_db_result_cb_t)(yajl_val jresult, yajl_val jerror);
+
+/* OVS DB structures */
+struct ovs_db_callback_s {
+ /*
+ * This callback is called when OVS DB connection
+ * has been established and ready to use. Client
+ * can use this callback to configure OVS DB, e.g.
+ * to subscribe to table update notification or poll
+ * some OVS DB data. This field can be NULL.
+ */
+ void (*post_conn_init)(ovs_db_t *pdb);
+ /*
+ * This callback is called when OVS DB connection
+ * has been lost. This field can be NULL.
+ */
+ void (*post_conn_terminate)(void);
+};
+typedef struct ovs_db_callback_s ovs_db_callback_t;
+
+/* OVS DB defines */
+#define OVS_DB_ADDR_NODE_SIZE 256
+#define OVS_DB_ADDR_SERVICE_SIZE 128
+#define OVS_DB_ADDR_UNIX_SIZE 108
+
+/* OVS DB prototypes */
+
+/*
+ * NAME
+ * ovs_db_init
+ *
+ * DESCRIPTION
+ * Initialize OVS DB internal data. The `ovs_db_destroy' function
+ * shall destroy the returned object.
+ *
+ * PARAMETERS
+ * `node' OVS DB Address.
+ * `service' OVS DB service name.
+ * `unix' OVS DB unix socket path.
+ * `cb' OVS DB callbacks.
+ *
+ * RETURN VALUE
+ * New ovs_db_t object upon success or NULL if an error occurred.
+ */
+ovs_db_t *ovs_db_init(const char *node, const char *service,
+ const char *unix_path, ovs_db_callback_t *cb);
+
+/*
+ * NAME
+ * ovs_db_destroy
+ *
+ * DESCRIPTION
+ * Destroy OVS DB object referenced by `pdb'.
+ *
+ * PARAMETERS
+ * `pdb' Pointer to OVS DB object.
+ *
+ * RETURN VALUE
+ * Zero upon success or non-zero if an error occurred.
+ */
+int ovs_db_destroy(ovs_db_t *pdb);
+
+/*
+ * NAME
+ * ovs_db_send_request
+ *
+ * DESCRIPTION
+ * Send JSON request to OVS DB server.
+ *
+ * PARAMETERS
+ * `pdb' Pointer to OVS DB object.
+ * `method' Request method name.
+ * `params' Method params to be sent (JSON value as a string).
+ * `cb' Result callback of the request. If NULL, the request
+ * is sent asynchronously.
+ *
+ * RETURN VALUE
+ * Zero upon success or non-zero if an error occurred.
+ */
+int ovs_db_send_request(ovs_db_t *pdb, const char *method, const char *params,
+ ovs_db_result_cb_t cb);
+
+/* callback types */
+#define OVS_DB_TABLE_CB_FLAG_INITIAL 0x01U
+#define OVS_DB_TABLE_CB_FLAG_INSERT 0x02U
+#define OVS_DB_TABLE_CB_FLAG_DELETE 0x04U
+#define OVS_DB_TABLE_CB_FLAG_MODIFY 0x08U
+#define OVS_DB_TABLE_CB_FLAG_ALL 0x0FU
+
+/*
+ * NAME
+ * ovs_db_table_cb_register
+ *
+ * DESCRIPTION
+ * Subscribe a callback on OVS DB table event. It allows to
+ * receive notifications (`update_cb' callback is called) of
+ * changes to requested table.
+ *
+ * PARAMETERS
+ * `pdb' Pointer to OVS DB object.
+ * `tb_name' OVS DB Table name to be monitored.
+ * `tb_column' OVS DB Table columns to be monitored. Last
+ * element in the array should be NULL.
+ * `update_cb' Callback function that is called when
+ * requested table columns are changed.
+ * `cb' Result callback of the request. If NULL, the call
+ * becomes asynchronous.
+ * Useful, if OVS_DB_TABLE_CB_FLAG_INITIAL is set.
+ * `flags' Bit mask of:
+ * OVS_DB_TABLE_CB_FLAG_INITIAL Receive initial values in
+ * result callback.
+ * OVS_DB_TABLE_CB_FLAG_INSERT Receive table insert events.
+ * OVS_DB_TABLE_CB_FLAG_DELETE Receive table remove events.
+ * OVS_DB_TABLE_CB_FLAG_MODIFY Receive table update events.
+ * OVS_DB_TABLE_CB_FLAG_ALL Receive all events.
+ *
+ * RETURN VALUE
+ * Zero upon success or non-zero if an error occurred.
+ */
+int ovs_db_table_cb_register(ovs_db_t *pdb, const char *tb_name,
+ const char **tb_column,
+ ovs_db_table_cb_t update_cb,
+ ovs_db_result_cb_t result_cb, unsigned int flags);
+
+/*
+ * OVS utils API
+ */
+
+/*
+ * NAME
+ * ovs_utils_get_value_by_key
+ *
+ * DESCRIPTION
+ * Get YAJL value by object name.
+ *
+ * PARAMETERS
+ * `jval' YAJL object value.
+ * `key' Object key name.
+ *
+ * RETURN VALUE
+ * YAJL value upon success or NULL if key not found.
+ */
+yajl_val ovs_utils_get_value_by_key(yajl_val jval, const char *key);
+
+/*
+ * NAME
+ * ovs_utils_get_map_value
+ *
+ * DESCRIPTION
+ * Get OVS DB map value by given map key (rfc7047, "Notation" section).
+ *
+ * PARAMETERS
+ * `jval' A 2-element YAJL array that represents a OVS DB map value.
+ * `key' OVS DB map key name.
+ *
+ * RETURN VALUE
+ * YAJL value upon success or NULL if key not found.
+ */
+yajl_val ovs_utils_get_map_value(yajl_val jval, const char *key);
+
+#endif
while (isspace((int)*string))
string++;
if (*string == 0)
- return (1);
+ return 1;
/* A quoted string */
if (*string == '"') {
string++;
if (*string == 0)
- return (1);
+ return 1;
dst = string;
buffer = string;
buffer++;
/* Catch a backslash at the end of buffer */
if (*buffer == 0)
- return (-1);
+ return -1;
}
*dst = *buffer;
buffer++;
}
/* No quote sign has been found */
if (*buffer == 0)
- return (-1);
+ return -1;
*dst = 0;
dst++;
/* Check for trailing spaces. */
if ((*buffer != 0) && !isspace((int)*buffer))
- return (-1);
+ return -1;
} else /* an unquoted string */
{
buffer = string;
*ret_buffer = buffer;
*ret_string = string;
- return (0);
+ return 0;
} /* int parse_string */
/*
while (isspace((int)*key))
key++;
if (*key == 0)
- return (1);
+ return 1;
/* Look for the equal sign */
buffer = key;
while (isalnum((int)*buffer) || *buffer == '_' || *buffer == ':')
buffer++;
if ((*buffer != '=') || (buffer == key))
- return (1);
+ return 1;
*buffer = 0;
buffer++;
/* Empty values must be written as "" */
if (isspace((int)*buffer) || (*buffer == 0))
- return (-1);
+ return -1;
status = parse_string(&buffer, &value);
if (status != 0)
- return (-1);
+ return -1;
/* NB: parse_string will have eaten up all trailing spaces. */
*ret_key = key;
*ret_value = value;
- return (0);
+ return 0;
} /* int parse_option */
-
-/* vim: set sw=2 ts=8 tw=78 et : */
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 : */
args = calloc(1, sizeof(*args));
if (args == NULL) {
ERROR("srrd_create_args_create: calloc failed.");
- return (NULL);
+ return NULL;
}
args->filename = NULL;
args->pdp_step = pdp_step;
if (args->filename == NULL) {
ERROR("srrd_create_args_create: strdup failed.");
srrd_create_args_destroy(args);
- return (NULL);
+ return NULL;
}
args->argv = calloc((size_t)(argc + 1), sizeof(*args->argv));
if (args->argv == NULL) {
ERROR("srrd_create_args_create: calloc failed.");
srrd_create_args_destroy(args);
- return (NULL);
+ return NULL;
}
for (args->argc = 0; args->argc < argc; args->argc++) {
if (args->argv[args->argc] == NULL) {
ERROR("srrd_create_args_create: strdup failed.");
srrd_create_args_destroy(args);
- return (NULL);
+ return NULL;
}
}
assert(args->argc == argc);
args->argv[args->argc] = NULL;
- return (args);
+ return args;
} /* srrd_create_args_t *srrd_create_args_create */
/* * * * * * * * * *
if (cfg->rrarows <= 0) {
*ret = NULL;
- return (-1);
+ return -1;
}
if ((cfg->xff < 0) || (cfg->xff >= 1.0)) {
*ret = NULL;
- return (-1);
+ return -1;
}
if (cfg->stepsize > 0)
ss = (int)CDTIME_T_TO_TIME_T(vl->interval);
if (ss <= 0) {
*ret = NULL;
- return (-1);
+ return -1;
}
/* Use the configured timespans or fall back to the built-in defaults */
assert(rra_max > 0);
if ((rra_def = calloc(rra_max + 1, sizeof(*rra_def))) == NULL)
- return (-1);
+ return -1;
rra_num = 0;
cdp_len = 0;
if (rra_num >= rra_max)
break;
- status = ssnprintf(buffer, sizeof(buffer), "RRA:%s:%.10f:%u:%u",
- rra_types[j], cfg->xff, cdp_len, cdp_num);
+ status = snprintf(buffer, sizeof(buffer), "RRA:%s:%.10f:%u:%u",
+ rra_types[j], cfg->xff, cdp_len, cdp_num);
if ((status < 0) || ((size_t)status >= sizeof(buffer))) {
ERROR("rra_get: Buffer would have been truncated.");
if (rra_num <= 0) {
sfree(rra_def);
- return (0);
+ return 0;
}
*ret = rra_def;
- return (rra_num);
+ return rra_num;
} /* }}} int rra_get */
static void ds_free(int ds_num, char **ds_def) /* {{{ */
char errbuf[1024];
ERROR("rrdtool plugin: calloc failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
for (ds_num = 0; ds_num < ds->ds_num; ds_num++) {
if (isnan(d->min)) {
sstrncpy(min, "U", sizeof(min));
} else
- ssnprintf(min, sizeof(min), "%f", d->min);
+ snprintf(min, sizeof(min), "%f", d->min);
if (isnan(d->max)) {
sstrncpy(max, "U", sizeof(max));
} else
- ssnprintf(max, sizeof(max), "%f", d->max);
+ snprintf(max, sizeof(max), "%f", d->max);
- status = ssnprintf(buffer, sizeof(buffer), "DS:%s:%s:%i:%s:%s", d->name,
- type, (cfg->heartbeat > 0)
- ? cfg->heartbeat
- : (int)CDTIME_T_TO_TIME_T(2 * vl->interval),
- min, max);
+ status = snprintf(
+ buffer, sizeof(buffer), "DS:%s:%s:%i:%s:%s", d->name, type,
+ (cfg->heartbeat > 0) ? cfg->heartbeat
+ : (int)CDTIME_T_TO_TIME_T(2 * vl->interval),
+ min, max);
if ((status < 1) || ((size_t)status >= sizeof(buffer)))
break;
if (ds_num != ds->ds_num) {
ds_free(ds_num, ds_def);
- return (-1);
+ return -1;
}
if (ds_num == 0) {
sfree(ds_def);
- return (0);
+ return 0;
}
*ret = ds_def;
- return (ds_num);
+ return ds_num;
} /* }}} int ds_get */
#if HAVE_THREADSAFE_LIBRRD
char *filename_copy;
if ((filename == NULL) || (argv == NULL))
- return (-EINVAL);
+ return -EINVAL;
/* Some versions of librrd don't have the `const' qualifier for the first
* argument, so we have to copy the pointer here to avoid warnings. It sucks,
filename_copy = strdup(filename);
if (filename_copy == NULL) {
ERROR("srrd_create: strdup failed.");
- return (-ENOMEM);
+ return -ENOMEM;
}
optind = 0; /* bug in librrd? */
sfree(filename_copy);
- return (status);
+ return status;
} /* }}} int srrd_create */
/* #endif HAVE_THREADSAFE_LIBRRD */
new_argv = malloc((new_argc + 1) * sizeof(*new_argv));
if (new_argv == NULL) {
ERROR("rrdtool plugin: malloc failed.");
- return (-1);
+ return -1;
}
if (last_up == 0)
last_up = time(NULL) - 10;
- ssnprintf(pdp_step_str, sizeof(pdp_step_str), "%lu", pdp_step);
- ssnprintf(last_up_str, sizeof(last_up_str), "%lu", (unsigned long)last_up);
+ snprintf(pdp_step_str, sizeof(pdp_step_str), "%lu", pdp_step);
+ snprintf(last_up_str, sizeof(last_up_str), "%lu", (unsigned long)last_up);
new_argv[0] = "create";
new_argv[1] = (void *)filename;
sfree(new_argv);
- return (status);
+ return status;
} /* }}} int srrd_create */
#endif /* !HAVE_THREADSAFE_LIBRRD */
if (ptr != NULL) {
pthread_mutex_unlock(&async_creation_lock);
- return (EEXIST);
+ return EEXIST;
}
status = stat(filename, &sb);
if ((status == 0) || (errno != ENOENT)) {
pthread_mutex_unlock(&async_creation_lock);
- return (EEXIST);
+ return EEXIST;
}
ptr = malloc(sizeof(*ptr));
if (ptr == NULL) {
pthread_mutex_unlock(&async_creation_lock);
- return (ENOMEM);
+ return ENOMEM;
}
ptr->filename = strdup(filename);
if (ptr->filename == NULL) {
pthread_mutex_unlock(&async_creation_lock);
sfree(ptr);
- return (ENOMEM);
+ return ENOMEM;
}
ptr->next = async_creation_list;
pthread_mutex_unlock(&async_creation_lock);
- return (0);
+ return 0;
} /* }}} int lock_file */
static int unlock_file(char const *filename) /* {{{ */
if (this == NULL) {
pthread_mutex_unlock(&async_creation_lock);
- return (ENOENT);
+ return ENOENT;
}
if (prev == NULL) {
sfree(this->filename);
sfree(this);
- return (0);
+ return 0;
} /* }}} int unlock_file */
static void *srrd_create_thread(void *targs) /* {{{ */
else
ERROR("srrd_create_thread: Unable to lock file \"%s\".", args->filename);
srrd_create_args_destroy(args);
- return (0);
+ return 0;
}
- ssnprintf(tmpfile, sizeof(tmpfile), "%s.async", args->filename);
+ snprintf(tmpfile, sizeof(tmpfile), "%s.async", args->filename);
status = srrd_create(tmpfile, args->pdp_step, args->last_up, args->argc,
(void *)args->argv);
unlink(tmpfile);
unlock_file(args->filename);
srrd_create_args_destroy(args);
- return (0);
+ return 0;
}
status = rename(tmpfile, args->filename);
unlink(tmpfile);
unlock_file(args->filename);
srrd_create_args_destroy(args);
- return (0);
+ return 0;
}
DEBUG("srrd_create_thread: Successfully created RRD file \"%s\".",
unlock_file(args->filename);
srrd_create_args_destroy(args);
- return (0);
+ return 0;
} /* }}} void *srrd_create_thread */
static int srrd_create_async(const char *filename, /* {{{ */
args = srrd_create_args_create(filename, pdp_step, last_up, argc, argv);
if (args == NULL)
- return (-1);
+ return -1;
status = pthread_attr_init(&attr);
if (status != 0) {
srrd_create_args_destroy(args);
- return (-1);
+ return -1;
}
status = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (status != 0) {
pthread_attr_destroy(&attr);
srrd_create_args_destroy(args);
- return (-1);
+ return -1;
}
status = pthread_create(&thread, &attr, srrd_create_thread, args);
sstrerror(status, errbuf, sizeof(errbuf)));
pthread_attr_destroy(&attr);
srrd_create_args_destroy(args);
- return (status);
+ return status;
}
pthread_attr_destroy(&attr);
/* args is freed in srrd_create_thread(). */
- return (0);
+ return 0;
} /* }}} int srrd_create_async */
/*
unsigned long stepsize;
if (check_create_dir(filename))
- return (-1);
+ return -1;
if ((rra_num = rra_get(&rra_def, vl, cfg)) < 1) {
ERROR("cu_rrd_create_file failed: Could not calculate RRAs");
- return (-1);
+ return -1;
}
if ((ds_num = ds_get(&ds_def, ds, vl, cfg)) < 1) {
ERROR("cu_rrd_create_file failed: Could not calculate DSes");
rra_free(rra_num, rra_def);
- return (-1);
+ return -1;
}
argc = ds_num + rra_num;
sstrerror(errno, errbuf, sizeof(errbuf)));
rra_free(rra_num, rra_def);
ds_free(ds_num, ds_def);
- return (-1);
+ return -1;
}
memcpy(argv, ds_def, ds_num * sizeof(char *));
ds_free(ds_num, ds_def);
rra_free(rra_num, rra_def);
- return (status);
+ return status;
} /* }}} int cu_rrd_create_file */
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
const value_list_t *vl, const rrdcreate_config_t *cfg);
#endif /* UTILS_RRDCREATE_H */
-
-/* vim: set sw=2 sts=2 et : */
char errbuf[1024];
ERROR("utils_tail: stat (%s) failed: %s", obj->file,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
/* The file is already open.. */
sstrerror(errno, errbuf, sizeof(errbuf)));
fclose(obj->fh);
obj->fh = NULL;
- return (-1);
+ return -1;
}
}
memcpy(&obj->stat, &stat_buf, sizeof(struct stat));
- return (1);
+ return 1;
}
/* Seek to the end if we re-open the same file again or the file opened
char errbuf[1024];
ERROR("utils_tail: fopen (%s) failed: %s", obj->file,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
if (seek_end != 0) {
ERROR("utils_tail: fseek (%s) failed: %s", obj->file,
sstrerror(errno, errbuf, sizeof(errbuf)));
fclose(fh);
- return (-1);
+ return -1;
}
}
obj->fh = fh;
memcpy(&obj->stat, &stat_buf, sizeof(struct stat));
- return (0);
+ return 0;
} /* int cu_tail_reopen */
cu_tail_t *cu_tail_create(const char *file) {
obj = calloc(1, sizeof(*obj));
if (obj == NULL)
- return (NULL);
+ return NULL;
obj->file = strdup(file);
if (obj->file == NULL) {
free(obj);
- return (NULL);
+ return NULL;
}
obj->fh = NULL;
- return (obj);
+ return obj;
} /* cu_tail_t *cu_tail_create */
int cu_tail_destroy(cu_tail_t *obj) {
free(obj->file);
free(obj);
- return (0);
+ return 0;
} /* int cu_tail_destroy */
int cu_tail_readline(cu_tail_t *obj, char *buf, int buflen) {
if (buflen < 1) {
ERROR("utils_tail: cu_tail_readline: buflen too small: %i bytes.", buflen);
- return (-1);
+ return -1;
}
if (obj->fh == NULL) {
status = cu_tail_reopen(obj);
if (status < 0)
- return (status);
+ return status;
}
assert(obj->fh != NULL);
clearerr(obj->fh);
if (fgets(buf, buflen, obj->fh) != NULL) {
buf[buflen - 1] = 0;
- return (0);
+ return 0;
}
/* Check if we encountered an error */
status = cu_tail_reopen(obj);
/* error -> return with error */
if (status < 0)
- return (status);
+ return status;
/* file end reached and file not reopened -> nothing more to read */
else if (status > 0) {
buf[0] = 0;
- return (0);
+ return 0;
}
/* If we get here: file was re-opened and there may be more to read.. Let's
* try again. */
if (fgets(buf, buflen, obj->fh) != NULL) {
buf[buflen - 1] = 0;
- return (0);
+ return 0;
}
if (ferror(obj->fh) != 0) {
sstrerror(errno, errbuf, sizeof(errbuf)));
fclose(obj->fh);
obj->fh = NULL;
- return (-1);
+ return -1;
}
/* EOf, well, apparently the new file is empty.. */
buf[0] = 0;
- return (0);
+ return 0;
} /* int cu_tail_readline */
int cu_tail_read(cu_tail_t *obj, char *buf, int buflen, tailfunc_t *callback,
match_value = (cu_match_value_t *)match_get_user_data(match);
if (match_value == NULL)
- return (-1);
+ return -1;
if ((match_value->ds_type & UTILS_MATCH_DS_TYPE_GAUGE) &&
(match_value->values_num == 0))
plugin_dispatch_values(&vl);
match_value_reset(match_value);
- return (0);
+ return 0;
} /* int simple_submit_match */
static int latency_submit_match(cu_match_t *match, void *user_data) {
match_value = (cu_match_value_t *)match_get_user_data(match);
if (match_value == NULL)
- return (-1);
+ return -1;
- sstrncpy(vl.host, hostname_g, sizeof(vl.host));
sstrncpy(vl.plugin, data->plugin, sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, data->plugin_instance,
sizeof(vl.plugin_instance));
sstrncpy(vl.type, data->type, sizeof(vl.type));
for (size_t i = 0; i < data->latency_config.percentile_num; i++) {
if (strlen(data->type_instance) != 0)
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-%.0f",
- data->type_instance, data->latency_config.percentile[i]);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%.117s-%.2f",
+ data->type_instance, data->latency_config.percentile[i]);
else
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%.0f",
- data->latency_config.percentile[i]);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%.0f",
+ data->latency_config.percentile[i]);
vl.values = &(value_t){
.gauge =
}
/* Submit buckets */
- sstrncpy(vl.type, "bucket", sizeof(vl.type));
+ if (data->latency_config.bucket_type != NULL)
+ sstrncpy(vl.type, data->latency_config.bucket_type, sizeof(vl.type));
+ else
+ sstrncpy(vl.type, "bucket", sizeof(vl.type));
+
for (size_t i = 0; i < data->latency_config.buckets_num; i++) {
latency_bucket_t bucket = data->latency_config.buckets[i];
bucket.upper_bound ? CDTIME_T_TO_DOUBLE(bucket.upper_bound) : INFINITY;
if (strlen(data->type_instance) != 0)
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-%s-%g_%g",
- data->type, data->type_instance, lower_bound, upper_bound);
+ snprintf(vl.type_instance, sizeof(vl.type_instance),
+ "%.54s-%.54s-%.2g_%.2g", data->type, data->type_instance,
+ lower_bound, upper_bound);
else
- ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-%g_%g",
- data->type, lower_bound, upper_bound);
+ snprintf(vl.type_instance, sizeof(vl.type_instance), "%.107s-%.2g_%.2g",
+ data->type, lower_bound, upper_bound);
vl.values = &(value_t){
.gauge =
match_value->values_num = 0;
latency_counter_reset(match_value->latency);
- return (0);
+ return 0;
} /* int latency_submit_match */
static int tail_callback(void *data, char *buf,
for (size_t i = 0; i < obj->matches_num; i++)
match_apply(obj->matches[i].match, buf);
- return (0);
+ return 0;
} /* int tail_callback */
static void tail_match_simple_free(void *data) {
obj = calloc(1, sizeof(*obj));
if (obj == NULL)
- return (NULL);
+ return NULL;
obj->tail = cu_tail_create(filename);
if (obj->tail == NULL) {
sfree(obj);
- return (NULL);
+ return NULL;
}
- return (obj);
+ return obj;
} /* cu_tail_match_t *tail_match_create */
void tail_match_destroy(cu_tail_match_t *obj) {
temp = realloc(obj->matches,
sizeof(cu_tail_match_match_t) * (obj->matches_num + 1));
if (temp == NULL)
- return (-1);
+ return -1;
obj->matches = temp;
obj->matches_num++;
temp->submit = submit_match;
temp->free = free_user_data;
- return (0);
+ return 0;
} /* int tail_match_add_match */
int tail_match_add_match_simple(cu_tail_match_t *obj, const char *regex,
match = match_create_simple(regex, excluderegex, ds_type);
if (match == NULL)
- return (-1);
+ return -1;
user_data = calloc(1, sizeof(*user_data));
if (user_data == NULL) {
match_destroy(match);
- return (-1);
+ return -1;
}
sstrncpy(user_data->plugin, plugin, sizeof(user_data->plugin));
match_destroy(match);
}
- return (status);
+ return status;
} /* int tail_match_add_match_simple */
int tail_match_read(cu_tail_match_t *obj) {
(void *)obj);
if (status != 0) {
ERROR("tail_match: cu_tail_read failed.");
- return (status);
+ return status;
}
for (size_t i = 0; i < obj->matches_num; i++) {
(*lt_match->submit)(lt_match->match, lt_match->user_data);
}
- return (0);
+ return 0;
} /* int tail_match_read */
-
-/* vim: set sw=2 sts=2 ts=8 : */
* Zero on success, nonzero on failure.
*/
int tail_match_read(cu_tail_match_t *obj);
-
-/* vim: set sw=2 sts=2 ts=8 : */
if (match->is_regex) {
/* Short cut popular catch-all regex. */
if (strcmp(".*", match->str) == 0)
- return (1);
+ return 1;
int status = regexec(&match->regex, str,
/* nmatch = */ 0, /* pmatch = */ NULL,
/* flags = */ 0);
if (status == 0)
- return (1);
+ return 1;
else
- return (0);
+ return 0;
} else if (strcmp(match->str, str) == 0)
- return (1);
+ return 1;
else
- return (0);
+ return 0;
} /* }}} _Bool lu_part_matches */
static int lu_copy_ident_to_match_part(part_match_t *match_part, /* {{{ */
if ((len < 3) || (ident_part[0] != '/') || (ident_part[len - 1] != '/')) {
sstrncpy(match_part->str, ident_part, sizeof(match_part->str));
match_part->is_regex = 0;
- return (0);
+ return 0;
}
/* Copy string without the leading slash. */
regerror(status, &match_part->regex, errbuf, sizeof(errbuf));
ERROR("utils_vl_lookup: Compiling regular expression \"%s\" failed: %s",
match_part->str, errbuf);
- return (EINVAL);
+ return EINVAL;
}
match_part->is_regex = 1;
- return (0);
+ return 0;
} /* }}} int lu_copy_ident_to_match_part */
static int lu_copy_ident_to_match(identifier_match_t *match, /* {{{ */
do { \
int status = lu_copy_ident_to_match_part(&match->field, ident->field); \
if (status != 0) \
- return (status); \
+ return status; \
} while (0)
COPY_FIELD(host);
#undef COPY_FIELD
- return (0);
+ return 0;
} /* }}} int lu_copy_ident_to_match */
/* user_class->lock must be held when calling this function */
user_obj = calloc(1, sizeof(*user_obj));
if (user_obj == NULL) {
ERROR("utils_vl_lookup: calloc failed.");
- return (NULL);
+ return NULL;
}
user_obj->next = NULL;
if (user_obj->user_obj == NULL) {
sfree(user_obj);
WARNING("utils_vl_lookup: User-provided constructor failed.");
- return (NULL);
+ return NULL;
}
#define COPY_FIELD(field, group_mask) \
last->next = user_obj;
}
- return (user_obj);
+ return user_obj;
} /* }}} void *lu_create_user_obj */
/* user_class->lock must be held when calling this function */
(strcmp(vl->type_instance, ptr->ident.type_instance) != 0))
continue;
- return (ptr);
+ return ptr;
}
- return (NULL);
+ return NULL;
} /* }}} user_obj_t *lu_find_user_obj */
static int lu_handle_user_class(lookup_t *obj, /* {{{ */
vl->plugin_instance) ||
!lu_part_matches(&user_class->match.plugin, vl->plugin) ||
!lu_part_matches(&user_class->match.host, vl->host))
- return (1);
+ return 1;
pthread_mutex_lock(&user_class->lock);
user_obj = lu_find_user_obj(user_class, vl);
user_obj = lu_create_user_obj(obj, ds, vl, user_class);
if (user_obj == NULL) {
pthread_mutex_unlock(&user_class->lock);
- return (-1);
+ return -1;
}
}
pthread_mutex_unlock(&user_class->lock);
status);
/* Returning a negative value means: abort! */
if (status < 0)
- return (status);
+ return status;
else
- return (1);
+ return 1;
}
- return (0);
+ return 0;
} /* }}} int lu_handle_user_class */
static int lu_handle_user_class_list(lookup_t *obj, /* {{{ */
status = lu_handle_user_class(obj, ds, vl, &ptr->entry);
if (status < 0)
- return (status);
+ return status;
else if (status == 0)
retval++;
}
- return (retval);
+ return retval;
} /* }}} int lu_handle_user_class_list */
static by_type_entry_t *lu_search_by_type(lookup_t *obj, /* {{{ */
status = c_avl_get(obj->by_type_tree, type, (void *)&by_type);
if (status == 0)
- return (by_type);
+ return by_type;
if (!allocate_if_missing)
- return (NULL);
+ return NULL;
type_copy = strdup(type);
if (type_copy == NULL) {
ERROR("utils_vl_lookup: strdup failed.");
- return (NULL);
+ return NULL;
}
by_type = calloc(1, sizeof(*by_type));
if (by_type == NULL) {
ERROR("utils_vl_lookup: calloc failed.");
sfree(type_copy);
- return (NULL);
+ return NULL;
}
by_type->wildcard_plugin_list = NULL;
ERROR("utils_vl_lookup: c_avl_create failed.");
sfree(by_type);
sfree(type_copy);
- return (NULL);
+ return NULL;
}
status = c_avl_insert(obj->by_type_tree,
c_avl_destroy(by_type->by_plugin_tree);
sfree(by_type);
sfree(type_copy);
- return (NULL);
+ return NULL;
}
- return (by_type);
+ return by_type;
} /* }}} by_type_entry_t *lu_search_by_type */
static int lu_add_by_plugin(by_type_entry_t *by_type, /* {{{ */
if (match->plugin.is_regex) {
if (by_type->wildcard_plugin_list == NULL) {
by_type->wildcard_plugin_list = user_class_list;
- return (0);
+ return 0;
}
ptr = by_type->wildcard_plugin_list;
if (plugin_copy == NULL) {
ERROR("utils_vl_lookup: strdup failed.");
sfree(user_class_list);
- return (ENOMEM);
+ return ENOMEM;
}
status =
plugin_copy, status);
sfree(plugin_copy);
sfree(user_class_list);
- return (status);
+ return status;
} else {
- return (0);
+ return 0;
}
} /* if (plugin not yet in tree) */
} /* if (plugin is not wildcard) */
ptr = ptr->next;
ptr->next = user_class_list;
- return (0);
+ return 0;
} /* }}} int lu_add_by_plugin */
static void lu_destroy_user_obj(lookup_t *obj, /* {{{ */
lookup_t *obj = calloc(1, sizeof(*obj));
if (obj == NULL) {
ERROR("utils_vl_lookup: calloc failed.");
- return (NULL);
+ return NULL;
}
obj->by_type_tree = c_avl_create((int (*)(const void *, const void *))strcmp);
if (obj->by_type_tree == NULL) {
ERROR("utils_vl_lookup: c_avl_create failed.");
sfree(obj);
- return (NULL);
+ return NULL;
}
obj->cb_user_class = cb_user_class;
obj->cb_free_class = cb_free_class;
obj->cb_free_obj = cb_free_obj;
- return (obj);
+ return obj;
} /* }}} lookup_t *lookup_create */
void lookup_destroy(lookup_t *obj) /* {{{ */
by_type = lu_search_by_type(obj, ident->type, /* allocate = */ 1);
if (by_type == NULL)
- return (-1);
+ return -1;
user_class_obj = calloc(1, sizeof(*user_class_obj));
if (user_class_obj == NULL) {
ERROR("utils_vl_lookup: calloc failed.");
- return (ENOMEM);
+ return ENOMEM;
}
pthread_mutex_init(&user_class_obj->entry.lock, /* attr = */ NULL);
user_class_obj->entry.user_class = user_class;
user_class_obj->entry.user_obj_list = NULL;
user_class_obj->next = NULL;
- return (lu_add_by_plugin(by_type, user_class_obj));
+ return lu_add_by_plugin(by_type, user_class_obj);
} /* }}} int lookup_add */
/* returns the number of successful calls to the callback function */
int status;
if ((obj == NULL) || (ds == NULL) || (vl == NULL))
- return (-EINVAL);
+ return -EINVAL;
by_type = lu_search_by_type(obj, vl->type, /* allocate = */ 0);
if (by_type == NULL)
- return (0);
+ return 0;
status =
c_avl_get(by_type->by_plugin_tree, vl->plugin, (void *)&user_class_list);
if (status == 0) {
status = lu_handle_user_class_list(obj, ds, vl, user_class_list);
if (status < 0)
- return (status);
+ return status;
retval += status;
}
status =
lu_handle_user_class_list(obj, ds, vl, by_type->wildcard_plugin_list);
if (status < 0)
- return (status);
+ return status;
retval += status;
}
- return (retval);
+ return retval;
} /* }}} lookup_search */
memcpy(&last_obj_ident, obj, sizeof(last_obj_ident));
if (strcmp(obj->plugin_instance, "failure") == 0)
- return (-1);
+ return -1;
- return (0);
+ return 0;
}
static void *lookup_class_callback(data_set_t const *ds, value_list_t const *vl,
have_new_obj = 1;
- return ((void *)obj);
+ return (void *)obj;
}
static int checked_lookup_add(lookup_t *obj, /* {{{ */
have_new_obj = 0;
status = lookup_search(obj, ds, &vl);
- return (status);
+ return status;
}
DEF_TEST(group_by_specific_host) {
/* expect new = */ 0);
lookup_destroy(obj);
- return (0);
+ return 0;
}
DEF_TEST(group_by_any_host) {
/* expect new = */ 0);
lookup_destroy(obj);
- return (0);
+ return 0;
}
DEF_TEST(multiple_lookups) {
assert(status == 2);
lookup_destroy(obj);
- return (0);
+ return 0;
}
DEF_TEST(regex) {
/* expect new = */ 1);
lookup_destroy(obj);
- return (0);
+ return 0;
}
int main(int argc, char **argv) /* {{{ */
#include <sys/sysctl.h>
#endif
-#if HAVE_LIBHAL_H
-#include <libhal.h>
-#endif
-
#define UUID_RAW_LENGTH 16
#define UUID_PRINTABLE_COMPACT_LENGTH (UUID_RAW_LENGTH * 2)
#define UUID_PRINTABLE_NORMAL_LENGTH (UUID_PRINTABLE_COMPACT_LENGTH + 4)
int len;
if (!uuid)
- return (0);
+ return 0;
len = strlen(uuid);
if (len < UUID_PRINTABLE_COMPACT_LENGTH)
- return (0);
+ return 0;
while (*uuid) {
if (!isxdigit((int)*uuid) && *uuid != '-')
- return (0);
+ return 0;
uuid++;
}
- return (1);
+ return 1;
}
static char *uuid_parse_dmidecode(FILE *file) {
if (!looks_like_a_uuid(fields[1]))
continue;
- return (strdup(fields[1]));
+ return strdup(fields[1]);
}
- return (NULL);
+ return NULL;
}
static char *uuid_get_from_dmidecode(void) {
char *uuid;
if (!dmidecode)
- return (NULL);
+ return NULL;
uuid = uuid_parse_dmidecode(dmidecode);
pclose(dmidecode);
- return (uuid);
+ return uuid;
}
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
size_t len = sizeof(uuid);
if (sysctlbyname(name, &uuid, &len, NULL, 0) == -1)
return NULL;
- return (strdup(uuid));
+ return strdup(uuid);
}
#elif defined(__OpenBSD__)
static char *uuid_get_from_sysctl(void) {
if (sysctl(mib, 2, uuid, &len, NULL, 0) == -1)
return NULL;
- return (strdup(uuid));
-}
-#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);
+ return strdup(uuid);
}
#endif
file = fopen(path, "r");
if (file == NULL)
- return (NULL);
+ return NULL;
if (!fgets(uuid, sizeof(uuid), file)) {
fclose(file);
- return (NULL);
+ return NULL;
}
fclose(file);
strstripnewline(uuid);
- return (strdup(uuid));
+ return strdup(uuid);
}
static char *uuid_get_local(void) {
/* Check /etc/uuid / UUIDFile before any other method. */
if ((uuid = uuid_get_from_file(uuidfile ? uuidfile : "/etc/uuid")) != NULL)
- return (uuid);
+ return uuid;
#if defined(__APPLE__)
if ((uuid = uuid_get_from_sysctlbyname("kern.uuid")) != NULL)
- return (uuid);
+ return uuid;
#elif defined(__FreeBSD__)
if ((uuid = uuid_get_from_sysctlbyname("kern.hostuuid")) != NULL)
- return (uuid);
+ return uuid;
#elif defined(__NetBSD__)
if ((uuid = uuid_get_from_sysctlbyname("machdep.dmi.system-uuid")) != NULL)
- return (uuid);
+ return uuid;
#elif defined(__OpenBSD__)
if ((uuid = uuid_get_from_sysctl()) != NULL)
- return (uuid);
+ return uuid;
#elif defined(__linux__)
if ((uuid = uuid_get_from_file("/sys/class/dmi/id/product_uuid")) != NULL)
- return (uuid);
-#endif
-
-#if HAVE_LIBHAL_H
- if ((uuid = uuid_get_from_hal()) != NULL)
- return (uuid);
+ return uuid;
#endif
if ((uuid = uuid_get_from_dmidecode()) != NULL)
- return (uuid);
+ return uuid;
#if defined(__linux__)
if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL)
- return (uuid);
+ return uuid;
#endif
- return (NULL);
+ return NULL;
}
static int uuid_config(const char *key, const char *value) {
if (strcasecmp(key, "UUIDFile") == 0) {
char *tmp = strdup(value);
if (tmp == NULL)
- return (-1);
+ return -1;
sfree(uuidfile);
uuidfile = tmp;
- return (0);
+ return 0;
}
- return (1);
+ return 1;
}
static int uuid_init(void) {
if (uuid) {
sstrncpy(hostname_g, uuid, DATA_MAX_NAME_LEN);
sfree(uuid);
- return (0);
+ return 0;
}
WARNING("uuid: could not read UUID using any known method");
- return (0);
+ return 0;
}
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:
- */
strlen_bogus_invalid_read_after_strdup
Memcheck:Addr4
fun:parse_value
- fun:parse_values
...
fun:main
}
* Jérôme Renard <jerome.renard at gmail.com>
* Marc Fournier <marc.fournier at camptocamp.com>
* Florian octo Forster <octo at collectd.org>
+ * Denes Matetelki <dmatetelki at varnish-software.com>
**/
#include "collectd.h"
#include "common.h"
#include "plugin.h"
-#if HAVE_VARNISH_V4
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
#include <vapi/vsc.h>
#include <vapi/vsm.h>
typedef struct VSC_C_main c_varnish_stats_t;
_Bool collect_sms;
#if HAVE_VARNISH_V2
_Bool collect_sm;
+#endif
+#if HAVE_VARNISH_V2 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
_Bool collect_sma;
#endif
_Bool collect_struct;
_Bool collect_totals;
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
_Bool collect_uptime;
#endif
_Bool collect_vcl;
_Bool collect_workers;
-#if HAVE_VARNISH_V4
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
_Bool collect_vsm;
+ _Bool collect_lck;
+ _Bool collect_mempool;
+ _Bool collect_mgt;
+ _Bool collect_smf;
+ _Bool collect_vbe;
+ _Bool collect_mse;
#endif
};
typedef struct user_config_s user_config_t; /* }}} */
if (plugin_instance == NULL)
plugin_instance = "default";
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
- plugin_instance, category);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
+ plugin_instance, category);
sstrncpy(vl.type, type, sizeof(vl.type));
if (type_instance != NULL)
sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
- return (plugin_dispatch_values(&vl));
+ return plugin_dispatch_values(&vl);
} /* }}} int varnish_submit */
static int varnish_submit_gauge(const char *plugin_instance, /* {{{ */
const char *category, const char *type,
const char *type_instance,
uint64_t gauge_value) {
- return (varnish_submit(plugin_instance, category, type, type_instance,
- (value_t){.gauge = (gauge_t)gauge_value}));
+ return varnish_submit(plugin_instance, category, type, type_instance,
+ (value_t){
+ .gauge = (gauge_t)gauge_value,
+ });
} /* }}} int varnish_submit_gauge */
static int varnish_submit_derive(const char *plugin_instance, /* {{{ */
const char *category, const char *type,
const char *type_instance,
uint64_t derive_value) {
- return (varnish_submit(plugin_instance, category, type, type_instance,
- (value_t){.derive = (derive_t)derive_value}));
+ return varnish_submit(plugin_instance, category, type, type_instance,
+ (value_t){
+ .derive = (derive_t)derive_value,
+ });
} /* }}} int varnish_submit_derive */
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
static int varnish_monitor(void *priv,
const struct VSC_point *const pt) /* {{{ */
{
uint64_t val;
const user_config_t *conf;
- const char *class;
const char *name;
if (pt == NULL)
- return (0);
+ return 0;
conf = priv;
-#if HAVE_VARNISH_V4
- class = pt->section->fantom->type;
- name = pt->desc->name;
+#if HAVE_VARNISH_V5
+ char namebuff[DATA_MAX_NAME_LEN];
- if (strcmp(class, "MAIN") != 0)
- return (0);
+ char const *c = strrchr(pt->name, '.');
+ if (c == NULL) {
+ return EINVAL;
+ }
+ sstrncpy(namebuff, c + 1, sizeof(namebuff));
+ name = namebuff;
+
+#elif HAVE_VARNISH_V4
+ if (strcmp(pt->section->fantom->type, "MAIN") != 0)
+ return 0;
+ name = pt->desc->name;
#elif HAVE_VARNISH_V3
- class = pt->class;
- name = pt->name;
+ if (strcmp(pt->class, "") != 0)
+ return 0;
- if (strcmp(class, "") != 0)
- return (0);
+ name = pt->name;
#endif
val = *(const volatile uint64_t *)pt->ptr;
else if (strcmp(name, "client_req") == 0)
return varnish_submit_derive(conf->instance, "connections", "connections",
"received", val);
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ else if (strcmp(name, "client_req_400") == 0)
+ return varnish_submit_derive(conf->instance, "connections", "connections",
+ "error_400", val);
+ else if (strcmp(name, "client_req_417") == 0)
+ return varnish_submit_derive(conf->instance, "connections", "connections",
+ "error_417", val);
+#endif
}
#ifdef HAVE_VARNISH_V3
else if (strcmp(name, "esi_warnings") == 0)
return varnish_submit_derive(conf->instance, "esi", "total_operations",
"warning", val);
+ else if (strcmp(name, "esi_maxdepth") == 0)
+ return varnish_submit_derive(conf->instance, "esi", "total_operations",
+ "max_depth", val);
}
if (conf->collect_backend) {
else if (strcmp(name, "fetch_304") == 0)
return varnish_submit_derive(conf->instance, "fetch", "http_requests",
"no_body_304", val);
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ else if (strcmp(name, "fetch_no_thread") == 0)
+ return varnish_submit_derive(conf->instance, "fetch", "http_requests",
+ "no_thread", val);
+ else if (strcmp(name, "fetch_none") == 0)
+ return varnish_submit_derive(conf->instance, "fetch", "http_requests",
+ "none", val);
+ else if (strcmp(name, "busy_sleep") == 0)
+ return varnish_submit_derive(conf->instance, "fetch", "http_requests",
+ "busy_sleep", val);
+ else if (strcmp(name, "busy_wakeup") == 0)
+ return varnish_submit_derive(conf->instance, "fetch", "http_requests",
+ "busy_wakeup", val);
+#endif
}
if (conf->collect_hcb) {
else if (strcmp(name, "n_objoverflow") == 0)
return varnish_submit_derive(conf->instance, "objects", "total_objects",
"workspace_overflow", val);
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ else if (strcmp(name, "exp_mailed") == 0)
+ return varnish_submit_gauge(conf->instance, "struct", "objects",
+ "exp_mailed", val);
+ else if (strcmp(name, "exp_received") == 0)
+ return varnish_submit_gauge(conf->instance, "struct", "objects",
+ "exp_received", val);
+#endif
}
#if HAVE_VARNISH_V3
"duplicate", val);
}
#endif
-#if HAVE_VARNISH_V4
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
if (conf->collect_ban) {
if (strcmp(name, "bans") == 0)
return varnish_submit_derive(conf->instance, "ban", "total_operations",
else if (strcmp(name, "bans_dups") == 0)
return varnish_submit_derive(conf->instance, "ban", "total_operations",
"duplicate", val);
+ else if (strcmp(name, "bans_tested") == 0)
+ return varnish_submit_derive(conf->instance, "ban", "total_operations",
+ "tested", val);
+ else if (strcmp(name, "bans_lurker_contention") == 0)
+ return varnish_submit_derive(conf->instance, "ban", "total_operations",
+ "lurker_contention", val);
+ else if (strcmp(name, "bans_lurker_obj_killed") == 0)
+ return varnish_submit_derive(conf->instance, "ban", "total_operations",
+ "lurker_obj_killed", val);
+ else if (strcmp(name, "bans_lurker_tested") == 0)
+ return varnish_submit_derive(conf->instance, "ban", "total_operations",
+ "lurker_tested", val);
+ else if (strcmp(name, "bans_lurker_tests_tested") == 0)
+ return varnish_submit_derive(conf->instance, "ban", "total_operations",
+ "lurker_tests_tested", val);
+ else if (strcmp(name, "bans_obj_killed") == 0)
+ return varnish_submit_derive(conf->instance, "ban", "total_operations",
+ "obj_killed", val);
+ else if (strcmp(name, "bans_persisted_bytes") == 0)
+ return varnish_submit_derive(conf->instance, "ban", "total_bytes",
+ "persisted_bytes", val);
+ else if (strcmp(name, "bans_persisted_fragmentation") == 0)
+ return varnish_submit_derive(conf->instance, "ban", "total_bytes",
+ "persisted_fragmentation", val);
+ else if (strcmp(name, "bans_tests_tested") == 0)
+ return varnish_submit_derive(conf->instance, "ban", "total_operations",
+ "tests_tested", val);
}
#endif
else if (strcmp(name, "sess_herd") == 0)
return varnish_submit_derive(conf->instance, "session",
"total_operations", "herd", val);
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ else if (strcmp(name, "sess_closed_err") == 0)
+ return varnish_submit_derive(conf->instance, "session",
+ "total_operations", "closed_err", val);
+ else if (strcmp(name, "sess_dropped") == 0)
+ return varnish_submit_derive(conf->instance, "session",
+ "total_operations", "dropped_for_thread",
+ val);
+#endif
}
if (conf->collect_shm) {
else if (strcmp(name, "s_req_bodybytes") == 0)
return varnish_submit_derive(conf->instance, "totals", "total_bytes",
"req_body", val);
+ else if (strcmp(name, "s_req_protobytes") == 0)
+ return varnish_submit_derive(conf->instance, "totals", "total_bytes",
+ "req_proto", val);
else if (strcmp(name, "s_resp_hdrbytes") == 0)
return varnish_submit_derive(conf->instance, "totals", "total_bytes",
"resp_header", val);
else if (strcmp(name, "s_resp_bodybytes") == 0)
return varnish_submit_derive(conf->instance, "totals", "total_bytes",
"resp_body", val);
+ else if (strcmp(name, "s_resp_protobytes") == 0)
+ return varnish_submit_derive(conf->instance, "totals", "total_bytes",
+ "resp_proto", val);
else if (strcmp(name, "s_pipe_hdrbytes") == 0)
return varnish_submit_derive(conf->instance, "totals", "total_bytes",
"pipe_header", val);
return varnish_submit_derive(conf->instance, "workers", "total_threads",
"dropped", val);
else if (strcmp(name, "thread_queue_len") == 0)
- return varnish_submit_derive(conf->instance, "workers", "queue_length",
- "threads", val);
+ return varnish_submit_gauge(conf->instance, "workers", "queue_length",
+ "threads", val);
else if (strcmp(name, "n_wrk") == 0)
return varnish_submit_gauge(conf->instance, "workers", "threads",
"worker", val);
else if (strcmp(name, "n_wrk_lqueue") == 0)
return varnish_submit_derive(conf->instance, "workers", "total_requests",
"queue_length", val);
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ else if (strcmp(name, "pools") == 0)
+ return varnish_submit_gauge(conf->instance, "workers", "pools", "pools",
+ val);
+ else if (strcmp(name, "busy_killed") == 0)
+ return varnish_submit_derive(conf->instance, "workers", "http_requests",
+ "busy_killed", val);
+#endif
}
-#if HAVE_VARNISH_V4
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
if (conf->collect_vsm) {
if (strcmp(name, "vsm_free") == 0)
return varnish_submit_gauge(conf->instance, "vsm", "bytes", "free", val);
return varnish_submit_derive(conf->instance, "vsm", "total_bytes",
"overflowed", val);
}
+
+ if (conf->collect_vbe) {
+ /* @TODO figure out the collectd type for bitmap
+ if (strcmp(name, "happy") == 0)
+ return varnish_submit_derive(conf->instance, "vbe",
+ "bitmap", "happy_hprobes", val);
+ */
+ if (strcmp(name, "bereq_hdrbytes") == 0)
+ return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+ "bereq_hdrbytes", val);
+ else if (strcmp(name, "bereq_bodybytes") == 0)
+ return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+ "bereq_bodybytes", val);
+ else if (strcmp(name, "bereq_protobytes") == 0)
+ return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+ "bereq_protobytes", val);
+ else if (strcmp(name, "beresp_hdrbytes") == 0)
+ return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+ "beresp_hdrbytes", val);
+ else if (strcmp(name, "beresp_bodybytes") == 0)
+ return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+ "beresp_bodybytes", val);
+ else if (strcmp(name, "beresp_protobytes") == 0)
+ return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+ "beresp_protobytes", val);
+ else if (strcmp(name, "pipe_hdrbytes") == 0)
+ return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+ "pipe_hdrbytes", val);
+ else if (strcmp(name, "pipe_out") == 0)
+ return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+ "pipe_out", val);
+ else if (strcmp(name, "pipe_in") == 0)
+ return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+ "pipe_in", val);
+ else if (strcmp(name, "conn") == 0)
+ return varnish_submit_derive(conf->instance, "vbe", "connections",
+ "c_conns", val);
+ else if (strcmp(name, "req") == 0)
+ return varnish_submit_derive(conf->instance, "vbe", "http_requests",
+ "b_reqs", val);
+ }
+
+ /* All Stevedores support these counters */
+ if (conf->collect_sma || conf->collect_smf || conf->collect_mse) {
+
+ char category[4];
+ if (conf->collect_sma)
+ strncpy(category, "sma", 4);
+ else if (conf->collect_smf)
+ strncpy(category, "smf", 4);
+ else
+ strncpy(category, "mse", 4);
+
+ if (strcmp(name, "c_req") == 0)
+ return varnish_submit_derive(conf->instance, category, "total_operations",
+ "alloc_req", val);
+ else if (strcmp(name, "c_fail") == 0)
+ return varnish_submit_derive(conf->instance, category, "total_operations",
+ "alloc_fail", val);
+ else if (strcmp(name, "c_bytes") == 0)
+ return varnish_submit_derive(conf->instance, category, "total_bytes",
+ "bytes_allocated", val);
+ else if (strcmp(name, "c_freed") == 0)
+ return varnish_submit_derive(conf->instance, category, "total_bytes",
+ "bytes_freed", val);
+ else if (strcmp(name, "g_alloc") == 0)
+ return varnish_submit_derive(conf->instance, category, "total_operations",
+ "alloc_outstanding", val);
+ else if (strcmp(name, "g_bytes") == 0)
+ return varnish_submit_gauge(conf->instance, category, "bytes",
+ "bytes_outstanding", val);
+ else if (strcmp(name, "g_space") == 0)
+ return varnish_submit_gauge(conf->instance, category, "bytes",
+ "bytes_available", val);
+ }
+
+ /* No SMA specific counters */
+
+ if (conf->collect_smf) {
+ if (strcmp(name, "g_smf") == 0)
+ return varnish_submit_gauge(conf->instance, "smf", "objects",
+ "n_struct_smf", val);
+ else if (strcmp(name, "g_smf_frag") == 0)
+ return varnish_submit_gauge(conf->instance, "smf", "objects",
+ "n_small_free_smf", val);
+ else if (strcmp(name, "g_smf_large") == 0)
+ return varnish_submit_gauge(conf->instance, "smf", "objects",
+ "n_large_free_smf", val);
+ }
+
+ if (conf->collect_mgt) {
+ if (strcmp(name, "uptime") == 0)
+ return varnish_submit_gauge(conf->instance, "mgt", "uptime",
+ "mgt_proc_uptime", val);
+ else if (strcmp(name, "child_start") == 0)
+ return varnish_submit_derive(conf->instance, "mgt", "total_operations",
+ "child_start", val);
+ else if (strcmp(name, "child_exit") == 0)
+ return varnish_submit_derive(conf->instance, "mgt", "total_operations",
+ "child_exit", val);
+ else if (strcmp(name, "child_stop") == 0)
+ return varnish_submit_derive(conf->instance, "mgt", "total_operations",
+ "child_stop", val);
+ else if (strcmp(name, "child_died") == 0)
+ return varnish_submit_derive(conf->instance, "mgt", "total_operations",
+ "child_died", val);
+ else if (strcmp(name, "child_dump") == 0)
+ return varnish_submit_derive(conf->instance, "mgt", "total_operations",
+ "child_dump", val);
+ else if (strcmp(name, "child_panic") == 0)
+ return varnish_submit_derive(conf->instance, "mgt", "total_operations",
+ "child_panic", val);
+ }
+
+ if (conf->collect_lck) {
+ if (strcmp(name, "creat") == 0)
+ return varnish_submit_gauge(conf->instance, "lck", "objects", "created",
+ val);
+ else if (strcmp(name, "destroy") == 0)
+ return varnish_submit_gauge(conf->instance, "lck", "objects", "destroyed",
+ val);
+ else if (strcmp(name, "locks") == 0)
+ return varnish_submit_derive(conf->instance, "lck", "total_operations",
+ "lock_ops", val);
+ }
+
+ if (conf->collect_mempool) {
+ if (strcmp(name, "live") == 0)
+ return varnish_submit_gauge(conf->instance, "mempool", "objects",
+ "in_use", val);
+ else if (strcmp(name, "pool") == 0)
+ return varnish_submit_gauge(conf->instance, "mempool", "objects",
+ "in_pool", val);
+ else if (strcmp(name, "sz_wanted") == 0)
+ return varnish_submit_gauge(conf->instance, "mempool", "bytes",
+ "size_requested", val);
+ else if (strcmp(name, "sz_actual") == 0)
+ return varnish_submit_gauge(conf->instance, "mempool", "bytes",
+ "size_allocated", val);
+ else if (strcmp(name, "allocs") == 0)
+ return varnish_submit_derive(conf->instance, "mempool",
+ "total_operations", "allocations", val);
+ else if (strcmp(name, "frees") == 0)
+ return varnish_submit_derive(conf->instance, "mempool",
+ "total_operations", "frees", val);
+ else if (strcmp(name, "recycle") == 0)
+ return varnish_submit_gauge(conf->instance, "mempool", "objects",
+ "recycled", val);
+ else if (strcmp(name, "timeout") == 0)
+ return varnish_submit_gauge(conf->instance, "mempool", "objects",
+ "timed_out", val);
+ else if (strcmp(name, "toosmall") == 0)
+ return varnish_submit_gauge(conf->instance, "mempool", "objects",
+ "too_small", val);
+ else if (strcmp(name, "surplus") == 0)
+ return varnish_submit_gauge(conf->instance, "mempool", "objects",
+ "surplus", val);
+ else if (strcmp(name, "randry") == 0)
+ return varnish_submit_gauge(conf->instance, "mempool", "objects",
+ "ran_dry", val);
+ }
+
+ if (conf->collect_mse) {
+ if (strcmp(name, "c_full") == 0)
+ return varnish_submit_derive(conf->instance, "mse", "total_operations",
+ "full_allocs", val);
+ else if (strcmp(name, "c_truncated") == 0)
+ return varnish_submit_derive(conf->instance, "mse", "total_operations",
+ "truncated_allocs", val);
+ else if (strcmp(name, "c_expanded") == 0)
+ return varnish_submit_derive(conf->instance, "mse", "total_operations",
+ "expanded_allocs", val);
+ else if (strcmp(name, "c_failed") == 0)
+ return varnish_submit_derive(conf->instance, "mse", "total_operations",
+ "failed_allocs", val);
+ else if (strcmp(name, "c_bytes") == 0)
+ return varnish_submit_derive(conf->instance, "mse", "total_bytes",
+ "bytes_allocated", val);
+ else if (strcmp(name, "c_freed") == 0)
+ return varnish_submit_derive(conf->instance, "mse", "total_bytes",
+ "bytes_freed", val);
+ else if (strcmp(name, "g_fo_alloc") == 0)
+ return varnish_submit_derive(conf->instance, "mse", "total_operations",
+ "fo_allocs_outstanding", val);
+ else if (strcmp(name, "g_fo_bytes") == 0)
+ return varnish_submit_gauge(conf->instance, "mse", "bytes",
+ "fo_bytes_outstanding", val);
+ else if (strcmp(name, "g_membuf_alloc") == 0)
+ return varnish_submit_gauge(conf->instance, "mse", "objects",
+ "membufs_allocated", val);
+ else if (strcmp(name, "g_membuf_inuse") == 0)
+ return varnish_submit_gauge(conf->instance, "mse", "objects",
+ "membufs_inuse", val);
+ else if (strcmp(name, "g_bans_bytes") == 0)
+ return varnish_submit_gauge(conf->instance, "mse", "bytes",
+ "persisted_banspace_used", val);
+ else if (strcmp(name, "g_bans_space") == 0)
+ return varnish_submit_gauge(conf->instance, "mse", "bytes",
+ "persisted_banspace_available", val);
+ else if (strcmp(name, "g_bans_persisted") == 0)
+ return varnish_submit_derive(conf->instance, "mse", "total_operations",
+ "bans_persisted", val);
+ else if (strcmp(name, "g_bans_lost") == 0)
+ return varnish_submit_derive(conf->instance, "mse", "total_operations",
+ "bans_lost", val);
+
+ /* mse seg */
+ else if (strcmp(name, "g_journal_bytes") == 0)
+ return varnish_submit_gauge(conf->instance, "mse_reg", "bytes",
+ "journal_bytes_used", val);
+ else if (strcmp(name, "g_journal_space") == 0)
+ return varnish_submit_gauge(conf->instance, "mse_reg", "bytes",
+ "journal_bytes_free", val);
+
+ /* mse segagg */
+ else if (strcmp(name, "g_bigspace") == 0)
+ return varnish_submit_gauge(conf->instance, "mse_segagg", "bytes",
+ "big_extents_bytes_available", val);
+ else if (strcmp(name, "g_extfree") == 0)
+ return varnish_submit_gauge(conf->instance, "mse_segagg", "objects",
+ "free_extents", val);
+ else if (strcmp(name, "g_sparenode") == 0)
+ return varnish_submit_gauge(conf->instance, "mse_segagg", "objects",
+ "spare_nodes_available", val);
+ else if (strcmp(name, "g_objnode") == 0)
+ return varnish_submit_gauge(conf->instance, "mse_segagg", "objects",
+ "object_nodes_in_use", val);
+ else if (strcmp(name, "g_extnode") == 0)
+ return varnish_submit_gauge(conf->instance, "mse_segagg", "objects",
+ "extent_nodes_in_use", val);
+ else if (strcmp(name, "g_bigextfree") == 0)
+ return varnish_submit_gauge(conf->instance, "mse_segagg", "objects",
+ "free_big_extents", val);
+ else if (strcmp(name, "c_pruneloop") == 0)
+ return varnish_submit_derive(conf->instance, "mse_segagg",
+ "total_operations", "prune_loops", val);
+ else if (strcmp(name, "c_pruned") == 0)
+ return varnish_submit_derive(conf->instance, "mse_segagg",
+ "total_objects", "pruned_objects", val);
+ else if (strcmp(name, "c_spared") == 0)
+ return varnish_submit_derive(conf->instance, "mse_segagg",
+ "total_operations", "spared_objects", val);
+ else if (strcmp(name, "c_skipped") == 0)
+ return varnish_submit_derive(conf->instance, "mse_segagg",
+ "total_operations", "missed_objects", val);
+ else if (strcmp(name, "c_nuked") == 0)
+ return varnish_submit_derive(conf->instance, "mse_segagg",
+ "total_operations", "nuked_objects", val);
+ else if (strcmp(name, "c_sniped") == 0)
+ return varnish_submit_derive(conf->instance, "mse_segagg",
+ "total_operations", "sniped_objects", val);
+ }
+
#endif
- return (0);
+ return 0;
} /* }}} static int varnish_monitor */
#else /* if HAVE_VARNISH_V2 */
} /* }}} void varnish_monitor */
#endif
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
static int varnish_read(user_data_t *ud) /* {{{ */
{
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
struct VSM_data *vd;
- const c_varnish_stats_t *stats;
_Bool ok;
+ const c_varnish_stats_t *stats;
+#elif HAVE_VARNISH_V5
+ struct vsm *vd;
+ struct vsc *vsc;
+ int vsm_status;
+#endif
user_config_t *conf;
if ((ud == NULL) || (ud->data == NULL))
- return (EINVAL);
+ return EINVAL;
conf = ud->data;
vd = VSM_New();
+
+#if HAVE_VARNISH_V5
+ vsc = VSC_New();
+#endif
+
#if HAVE_VARNISH_V3
VSC_Setup(vd);
#endif
if (conf->instance != NULL) {
int status;
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
status = VSM_n_Arg(vd, conf->instance);
+#elif HAVE_VARNISH_V5
+ status = VSM_Arg(vd, 'n', conf->instance);
+#endif
+
if (status < 0) {
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
VSM_Delete(vd);
- ERROR("varnish plugin: VSM_n_Arg (\"%s\") failed "
+#elif HAVE_VARNISH_V5
+ VSC_Destroy(&vsc, vd);
+ VSM_Destroy(&vd);
+#endif
+ ERROR("varnish plugin: VSM_Arg (\"%s\") failed "
"with status %i.",
conf->instance, status);
- return (-1);
+ return -1;
}
}
#if HAVE_VARNISH_V3
ok = (VSC_Open(vd, /* diag = */ 1) == 0);
-#else /* if HAVE_VARNISH_V4 */
+#elif HAVE_VARNISH_V4
ok = (VSM_Open(vd) == 0);
#endif
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
if (!ok) {
VSM_Delete(vd);
ERROR("varnish plugin: Unable to open connection.");
-
- return (-1);
+ return -1;
}
+#endif
#if HAVE_VARNISH_V3
stats = VSC_Main(vd);
-#else /* if HAVE_VARNISH_V4 */
+#elif HAVE_VARNISH_V4
stats = VSC_Main(vd, NULL);
#endif
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
if (!stats) {
VSM_Delete(vd);
ERROR("varnish plugin: Unable to get statistics.");
+ return -1;
+ }
+#endif
+
+#if HAVE_VARNISH_V5
+ if (VSM_Attach(vd, STDERR_FILENO)) {
+ ERROR("varnish plugin: Cannot attach to varnish. %s", VSM_Error(vd));
+ VSC_Destroy(&vsc, vd);
+ VSM_Destroy(&vd);
+ return -1;
+ }
- return (-1);
+ vsm_status = VSM_Status(vd);
+ if (vsm_status & ~(VSM_MGT_RUNNING | VSM_WRK_RUNNING)) {
+ ERROR("varnish plugin: Unable to get statistics.");
+ VSC_Destroy(&vsc, vd);
+ VSM_Destroy(&vd);
+ return -1;
}
+#endif
#if HAVE_VARNISH_V3
VSC_Iter(vd, varnish_monitor, conf);
-#else /* if HAVE_VARNISH_V4 */
+#elif HAVE_VARNISH_V4
VSC_Iter(vd, NULL, varnish_monitor, conf);
+#elif HAVE_VARNISH_V5
+ VSC_Iter(vsc, vd, varnish_monitor, conf);
#endif
+
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
VSM_Delete(vd);
+#elif HAVE_VARNISH_V5
+ VSC_Destroy(&vsc, vd);
+ VSM_Destroy(&vd);
+#endif
- return (0);
+ return 0;
} /* }}} */
#else /* if HAVE_VARNISH_V2 */
static int varnish_read(user_data_t *ud) /* {{{ */
user_config_t *conf;
if ((ud == NULL) || (ud->data == NULL))
- return (EINVAL);
+ return EINVAL;
conf = ud->data;
if (stats == NULL) {
ERROR("Varnish plugin : unable to load statistics");
- return (-1);
+ return -1;
}
varnish_monitor(conf, stats);
- return (0);
+ return 0;
} /* }}} */
#endif
static int varnish_config_apply_default(user_config_t *conf) /* {{{ */
{
if (conf == NULL)
- return (EINVAL);
+ return EINVAL;
conf->collect_backend = 1;
conf->collect_cache = 1;
conf->collect_shm = 1;
#if HAVE_VARNISH_V2
conf->collect_sm = 0;
+#endif
+#if HAVE_VARNISH_V2 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
conf->collect_sma = 0;
#endif
conf->collect_sms = 0;
conf->collect_struct = 0;
conf->collect_totals = 0;
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
conf->collect_uptime = 0;
#endif
conf->collect_vcl = 0;
conf->collect_workers = 0;
-#if HAVE_VARNISH_V4
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
conf->collect_vsm = 0;
+ conf->collect_lck = 0;
+ conf->collect_mempool = 0;
+ conf->collect_mgt = 0;
+ conf->collect_smf = 0;
+ conf->collect_vbe = 0;
+ conf->collect_mse = 0;
#endif
- return (0);
+ return 0;
} /* }}} int varnish_config_apply_default */
static int varnish_init(void) /* {{{ */
user_config_t *conf;
if (have_instance)
- return (0);
+ return 0;
conf = calloc(1, sizeof(*conf));
if (conf == NULL)
- return (ENOMEM);
+ return ENOMEM;
/* Default settings: */
conf->instance = NULL;
/* group = */ "varnish",
/* name = */ "varnish/localhost",
/* callback = */ varnish_read,
- /* interval = */ 0, &(user_data_t){
- .data = conf, .free_func = varnish_config_free,
- });
+ /* interval = */ 0,
+ &(user_data_t){
+ .data = conf, .free_func = varnish_config_free,
+ });
- return (0);
+ return 0;
} /* }}} int varnish_init */
static int varnish_config_instance(const oconfig_item_t *ci) /* {{{ */
conf = calloc(1, sizeof(*conf));
if (conf == NULL)
- return (ENOMEM);
+ return ENOMEM;
conf->instance = NULL;
varnish_config_apply_default(conf);
status = cf_util_get_string(ci, &conf->instance);
if (status != 0) {
sfree(conf);
- return (status);
+ return status;
}
assert(conf->instance != NULL);
WARNING("Varnish plugin: \"Instance\" blocks accept only "
"one argument.");
sfree(conf);
- return (EINVAL);
+ return EINVAL;
}
for (int i = 0; i < ci->children_num; i++) {
else if (strcasecmp("CollectSMS", child->key) == 0)
cf_util_get_boolean(child, &conf->collect_sms);
else if (strcasecmp("CollectSMA", child->key) == 0)
-#if HAVE_VARNISH_V2
+#if HAVE_VARNISH_V2 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
cf_util_get_boolean(child, &conf->collect_sma);
#else
WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
- child->key, "v2");
+ child->key, "v2 and v4");
#endif
else if (strcasecmp("CollectSM", child->key) == 0)
#if HAVE_VARNISH_V2
else if (strcasecmp("CollectTotals", child->key) == 0)
cf_util_get_boolean(child, &conf->collect_totals);
else if (strcasecmp("CollectUptime", child->key) == 0)
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
cf_util_get_boolean(child, &conf->collect_uptime);
#else
WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
else if (strcasecmp("CollectWorkers", child->key) == 0)
cf_util_get_boolean(child, &conf->collect_workers);
else if (strcasecmp("CollectVSM", child->key) == 0)
-#if HAVE_VARNISH_V4
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
cf_util_get_boolean(child, &conf->collect_vsm);
#else
WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
child->key, "v4");
#endif
+ else if (strcasecmp("CollectLock", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ cf_util_get_boolean(child, &conf->collect_lck);
+#else
+ WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+ child->key, "v4");
+#endif
+ else if (strcasecmp("CollectMempool", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ cf_util_get_boolean(child, &conf->collect_mempool);
+#else
+ WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+ child->key, "v4");
+#endif
+ else if (strcasecmp("CollectManagement", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ cf_util_get_boolean(child, &conf->collect_mgt);
+#else
+ WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+ child->key, "v4");
+#endif
+ else if (strcasecmp("CollectSMF", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ cf_util_get_boolean(child, &conf->collect_smf);
+#else
+ WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+ child->key, "v4");
+#endif
+ else if (strcasecmp("CollectSMF", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ cf_util_get_boolean(child, &conf->collect_smf);
+#else
+ WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+ child->key, "v4");
+#endif
+ else if (strcasecmp("CollectVBE", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ cf_util_get_boolean(child, &conf->collect_vbe);
+#else
+ WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+ child->key, "v4");
+#endif
+ else if (strcasecmp("CollectMSE", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ cf_util_get_boolean(child, &conf->collect_mse);
+#else
+ WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+ child->key, "Plus v4");
+#endif
else {
WARNING("Varnish plugin: Ignoring unknown "
"configuration option: \"%s\". Did "
#endif
&& !conf->collect_session && !conf->collect_shm && !conf->collect_sms
#if HAVE_VARNISH_V2
- && !conf->collect_sma && !conf->collect_sm
+ && !conf->collect_sm
+#endif
+#if HAVE_VARNISH_V2 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ && !conf->collect_sma
#endif
&& !conf->collect_struct && !conf->collect_totals
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
&& !conf->collect_uptime
#endif
&& !conf->collect_vcl && !conf->collect_workers
-#if HAVE_VARNISH_V4
- && !conf->collect_vsm
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+ && !conf->collect_vsm && !conf->collect_vbe && !conf->collect_smf &&
+ !conf->collect_mgt && !conf->collect_lck && !conf->collect_mempool &&
+ !conf->collect_mse
#endif
) {
WARNING("Varnish plugin: No metric has been configured for "
"instance \"%s\". Disabling this instance.",
(conf->instance == NULL) ? "localhost" : conf->instance);
sfree(conf);
- return (EINVAL);
+ return EINVAL;
}
- ssnprintf(callback_name, sizeof(callback_name), "varnish/%s",
- (conf->instance == NULL) ? "localhost" : conf->instance);
+ snprintf(callback_name, sizeof(callback_name), "varnish/%s",
+ (conf->instance == NULL) ? "localhost" : conf->instance);
plugin_register_complex_read(
/* group = */ "varnish",
/* name = */ callback_name,
/* callback = */ varnish_read,
- /* interval = */ 0, &(user_data_t){
- .data = conf, .free_func = varnish_config_free,
- });
+ /* interval = */ 0,
+ &(user_data_t){
+ .data = conf, .free_func = varnish_config_free,
+ });
have_instance = 1;
- return (0);
+ return 0;
} /* }}} int varnish_config_instance */
static int varnish_config(oconfig_item_t *ci) /* {{{ */
}
}
- return (0);
+ return 0;
} /* }}} int varnish_config */
void module_register(void) /* {{{ */
plugin_register_complex_config("varnish", varnish_config);
plugin_register_init("varnish", varnish_init);
} /* }}} */
-
-/* vim: set sw=8 noet fdm=marker : */
*
* Authors:
* Richard W.M. Jones <rjones@redhat.com>
+ * Przemyslaw Szczerbik <przemyslawx.szczerbik@intel.com>
**/
#include "collectd.h"
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
/* Plugin name */
#define PLUGIN_NAME "virt"
+#ifdef LIBVIR_CHECK_VERSION
+
+#if LIBVIR_CHECK_VERSION(0, 9, 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",
"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;
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 */
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_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;
+};
-static void free_interface_devices(void);
-static int add_interface_device(virDomainPtr dom, const char *path,
- const char *address, unsigned int number);
+#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
/* 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;
/* 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) \
+ if (!strcmp(param[i].field, NAME)) { \
+ binfo->FIELD = param[i].value.l; \
+ continue; \
+ }
+
+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) \
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) {
+ virTypedParamsClear(param, nparams);
+ sfree(param);
+ 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;
+ }
+
+ virTypedParamsClear(param, nparams);
+ sfree(param);
+#endif /* HAVE_CPU_STATS */
+
+ return 0;
+}
+
static void init_value_list(value_list_t *vl, virDomainPtr dom) {
int n;
const char *name;
} /* 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) {
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);
}
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;
}
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,
const char *type) {
char type_instance[DATA_MAX_NAME_LEN];
- ssnprintf(type_instance, sizeof(type_instance), "%d", vcpu_nr);
-
+ snprintf(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];
+ snprintf(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
+
+ snprintf(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) {
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
+ int nparams = 0;
+ if (virDomainBlockStatsFlags(dom, path, NULL, &nparams, 0) < 0 ||
+ nparams <= 0) {
+ VIRT_ERROR(conn, "getting the disk params count");
+ return -1;
+ }
+
+ virTypedParameterPtr params = calloc((size_t)nparams, sizeof(*params));
+ if (params == NULL) {
+ ERROR("virt plugin: alloc(%i) for block=%s parameters failed.", nparams,
+ path);
+ return -1;
+ }
+
+ int rc = -1;
+ if (virDomainBlockStatsFlags(dom, path, params, &nparams, 0) < 0) {
+ VIRT_ERROR(conn, "getting the disk params values");
+ } else {
+ rc = get_block_info(binfo, params, nparams);
+ }
+
+ virTypedParamsClear(params, nparams);
+ sfree(params);
+ 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;
+
+ snprintf(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;
#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),
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");
+ snprintf(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) */
+ snprintf(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);
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. */
}
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) {
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) {
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)
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);
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);
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);
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))
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);
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,
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.");
return 0;
}
- ssnprintf(name, n, "%s:%s", domname, devpath);
+ snprintf(name, n, "%s:%s", domname, devpath);
r = ignorelist_match(il, name);
sfree(name);
return r;
}
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;
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
- */
--- /dev/null
+/**
+ * collectd - src/virt_test.c
+ * Copyright (C) 2016 Francesco Romani <fromani at redhat.com>
+ * Based on
+ * collectd - src/ceph_test.c
+ * Copyright (C) 2015 Florian octo Forster
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Florian octo Forster <octo at collectd.org>
+ **/
+
+#include "testing.h"
+#include "virt.c" /* sic */
+
+#include <unistd.h>
+
+static const char minimal_xml[] =
+ ""
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<domain type=\"kvm\" xmlns:ovirt=\"http://ovirt.org/vm/tune/1.0\">"
+ " <metadata/>"
+ "</domain>";
+
+static const char minimal_metadata_xml[] =
+ ""
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<domain type=\"kvm\" xmlns:ovirt=\"http://ovirt.org/vm/tune/1.0\">"
+ " <metadata>"
+ " <ovirtmap:tag "
+ "xmlns:ovirtmap=\"http://ovirt.org/ovirtmap/tag/1.0\">virt-0</ovirtmap:tag>"
+ " </metadata>"
+ "</domain>";
+
+struct xml_state {
+ xmlDocPtr xml_doc;
+ xmlXPathContextPtr xpath_ctx;
+ xmlXPathObjectPtr xpath_obj;
+ char tag[PARTITION_TAG_MAX_LEN];
+};
+
+static int init_state(struct xml_state *st, const char *xml) {
+ memset(st, 0, sizeof(*st));
+
+ st->xml_doc = xmlReadDoc((const xmlChar *)xml, NULL, NULL, XML_PARSE_NONET);
+ if (st->xml_doc == NULL) {
+ return -1;
+ }
+ st->xpath_ctx = xmlXPathNewContext(st->xml_doc);
+ if (st->xpath_ctx == NULL) {
+ return -1;
+ }
+ return 0;
+}
+
+static void fini_state(struct xml_state *st) {
+ if (st->xpath_ctx) {
+ xmlXPathFreeContext(st->xpath_ctx);
+ st->xpath_ctx = NULL;
+ }
+ if (st->xml_doc) {
+ xmlFreeDoc(st->xml_doc);
+ st->xml_doc = NULL;
+ }
+}
+
+#define TAG "virt-0"
+
+DEF_TEST(lv_domain_get_tag_no_metadata_xml) {
+ int err;
+ struct xml_state st;
+ err = init_state(&st, minimal_xml);
+ EXPECT_EQ_INT(0, err);
+
+ err = lv_domain_get_tag(st.xpath_ctx, "test", st.tag);
+
+ EXPECT_EQ_INT(0, err);
+ EXPECT_EQ_STR("", st.tag);
+
+ fini_state(&st);
+ return 0;
+}
+
+DEF_TEST(lv_domain_get_tag_valid_xml) {
+ int err;
+ struct xml_state st;
+ err = init_state(&st, minimal_metadata_xml);
+ EXPECT_EQ_INT(0, err);
+
+ err = lv_domain_get_tag(st.xpath_ctx, "test", st.tag);
+
+ EXPECT_EQ_INT(0, err);
+ EXPECT_EQ_STR(TAG, st.tag);
+
+ return 0;
+}
+
+DEF_TEST(lv_default_instance_include_domain_without_tag) {
+ struct lv_read_instance *inst = NULL;
+ int ret;
+
+ ret = lv_init_instance(0, lv_read);
+ inst = &(lv_read_user_data[0].inst);
+ EXPECT_EQ_STR("virt-0", inst->tag);
+
+ ret = lv_instance_include_domain(inst, "testing", "");
+ EXPECT_EQ_INT(1, ret);
+
+ lv_fini_instance(0);
+ return 0;
+}
+
+DEF_TEST(lv_regular_instance_skip_domain_without_tag) {
+ struct lv_read_instance *inst = NULL;
+ int ret;
+
+ ret = lv_init_instance(1, lv_read);
+ inst = &(lv_read_user_data[1].inst);
+ EXPECT_EQ_STR("virt-1", inst->tag);
+
+ ret = lv_instance_include_domain(inst, "testing", "");
+ EXPECT_EQ_INT(0, ret);
+
+ lv_fini_instance(0);
+ return 0;
+}
+
+DEF_TEST(lv_include_domain_matching_tags) {
+ struct lv_read_instance *inst = NULL;
+ int ret;
+
+ ret = lv_init_instance(0, lv_read);
+ inst = &(lv_read_user_data[0].inst);
+ EXPECT_EQ_STR("virt-0", inst->tag);
+
+ ret = lv_instance_include_domain(inst, "testing", "virt-0");
+ EXPECT_EQ_INT(1, ret);
+
+ ret = lv_init_instance(1, lv_read);
+ inst = &(lv_read_user_data[1].inst);
+ EXPECT_EQ_STR("virt-1", inst->tag);
+
+ ret = lv_instance_include_domain(inst, "testing", "virt-1");
+ EXPECT_EQ_INT(1, ret);
+
+ lv_fini_instance(0);
+ lv_fini_instance(1);
+ return 0;
+}
+
+DEF_TEST(lv_default_instance_include_domain_with_unknown_tag) {
+ struct lv_read_instance *inst = NULL;
+ int ret;
+
+ ret = lv_init_instance(0, lv_read);
+ inst = &(lv_read_user_data[0].inst);
+ EXPECT_EQ_STR("virt-0", inst->tag);
+
+ ret = lv_instance_include_domain(inst, "testing", "unknownFormat-tag");
+ EXPECT_EQ_INT(1, ret);
+
+ lv_fini_instance(0);
+ return 0;
+}
+
+DEF_TEST(lv_regular_instance_skip_domain_with_unknown_tag) {
+ struct lv_read_instance *inst = NULL;
+ int ret;
+
+ ret = lv_init_instance(1, lv_read);
+ inst = &(lv_read_user_data[1].inst);
+ EXPECT_EQ_STR("virt-1", inst->tag);
+
+ ret = lv_instance_include_domain(inst, "testing", "unknownFormat-tag");
+ EXPECT_EQ_INT(0, ret);
+
+ lv_fini_instance(0);
+ return 0;
+}
+#undef TAG
+
+int main(void) {
+ RUN_TEST(lv_domain_get_tag_no_metadata_xml);
+ RUN_TEST(lv_domain_get_tag_valid_xml);
+
+ RUN_TEST(lv_default_instance_include_domain_without_tag);
+ RUN_TEST(lv_regular_instance_skip_domain_without_tag);
+ RUN_TEST(lv_include_domain_matching_tags);
+ RUN_TEST(lv_default_instance_include_domain_with_unknown_tag);
+ RUN_TEST(lv_regular_instance_skip_domain_with_unknown_tag);
+
+ END_TEST;
+}
+
+/* vim: set sw=2 sts=2 et : */
else
verbose_output = 0;
} else {
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* int vmem_config */
static int vmem_read(void) {
char errbuf[1024];
ERROR("vmem plugin: fopen (/proc/vmstat) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
submit_two(NULL, "vmpage_io", "swap", pswpin, pswpout);
#endif /* KERNEL_LINUX */
- return (0);
+ return 0;
} /* int vmem_read */
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 : */
* What's the right thing to do, if there is no getpagesize ()? */
pagesize = getpagesize();
- return (0);
+ return 0;
} /* static void vserver_init(void) */
static void traffic_submit(const char *plugin_instance,
status = parse_value(s, &v, DS_TYPE_DERIVE);
if (status != 0)
- return (-1);
- return (v.derive);
+ return -1;
+ return v.derive;
}
static int vserver_read(void) {
char errbuf[1024];
ERROR("vserver plugin: fopen (%s): %s", PROCDIR,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
while (42) {
ERROR("vserver plugin: failed to read directory %s: %s", PROCDIR,
sstrerror(errno, errbuf, sizeof(errbuf)));
closedir(proc);
- return (-1);
+ return -1;
}
if (dent->d_name[0] == '.')
continue;
- len = ssnprintf(file, sizeof(file), PROCDIR "/%s", dent->d_name);
+ len = snprintf(file, sizeof(file), PROCDIR "/%s", dent->d_name);
if ((len < 0) || (len >= BUFSIZE))
continue;
continue;
/* socket message accounting */
- len = ssnprintf(file, sizeof(file), PROCDIR "/%s/cacct", dent->d_name);
+ len = snprintf(file, sizeof(file), PROCDIR "/%s/cacct", dent->d_name);
if ((len < 0) || ((size_t)len >= sizeof(file)))
continue;
}
/* thread information and load */
- len = ssnprintf(file, sizeof(file), PROCDIR "/%s/cvirt", dent->d_name);
+ len = snprintf(file, sizeof(file), PROCDIR "/%s/cvirt", dent->d_name);
if ((len < 0) || ((size_t)len >= sizeof(file)))
continue;
}
/* processes and memory usage */
- len = ssnprintf(file, sizeof(file), PROCDIR "/%s/limit", dent->d_name);
+ len = snprintf(file, sizeof(file), PROCDIR "/%s/limit", dent->d_name);
if ((len < 0) || ((size_t)len >= sizeof(file)))
continue;
closedir(proc);
- return (0);
+ return 0;
} /* int vserver_read */
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 : */
watt = pow (10.0, (dbm / 10.0)) / 1000.0;
- return (watt);
+ return watt;
}
#endif
static double wireless_percent_to_power(double quality) {
assert((quality >= 0.0) && (quality <= 100.0));
- return ((quality * (POWER_MAX - POWER_MIN)) + POWER_MIN);
+ return (quality * (POWER_MAX - POWER_MIN)) + POWER_MIN;
} /* double wireless_percent_to_power */
static int wireless_read(void) {
if ((fh = fopen(WIRELESS_PROC_FILE, "r")) == NULL) {
char errbuf[1024];
WARNING("wireless: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ return -1;
}
devices_found = 0;
/* If no wireless devices are present return an error, so the plugin
* code delays our read function. */
if (devices_found == 0)
- return (-1);
+ return -1;
#endif /* KERNEL_LINUX */
- return (0);
+ return 0;
} /* int wireless_read */
void module_register(void) {
ssize_t status;
if (cb->sock_fd < 0)
- return (-1);
+ return -1;
status = swrite(cb->sock_fd, cb->send_buf, strlen(cb->send_buf));
if (status != 0) {
close(cb->sock_fd);
cb->sock_fd = -1;
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
/* NOTE: You must hold cb->send_lock when calling this function! */
now = cdtime();
if ((cb->send_buf_init_time + timeout) > now)
- return (0);
+ return 0;
}
if (cb->send_buf_fill == 0) {
cb->send_buf_init_time = cdtime();
- return (0);
+ return 0;
}
status = wg_send_buffer(cb);
wg_reset_buffer(cb);
- return (status);
+ return status;
}
static int wg_callback_init(struct wg_callback *cb) {
char connerr[1024] = "";
if (cb->sock_fd > 0)
- return (0);
+ return 0;
/* Don't try to reconnect too often. By default, one reconnection attempt
* is made per second. */
now = cdtime();
if ((now - cb->last_connect_time) < WG_MIN_RECONNECT_INTERVAL)
- return (EAGAIN);
+ return EAGAIN;
cb->last_connect_time = now;
struct addrinfo ai_hints = {.ai_family = AF_UNSPEC,
if (status != 0) {
ERROR("write_graphite plugin: getaddrinfo (%s, %s, %s) failed: %s",
cb->node, cb->service, cb->protocol, gai_strerror(status));
- return (-1);
+ return -1;
}
assert(ai_list != NULL);
"write_graphite plugin: Connecting to %s:%s via %s failed. "
"The last error was: %s",
cb->node, cb->service, cb->protocol, connerr);
- return (-1);
+ return -1;
} else {
c_release(LOG_INFO, &cb->init_complaint,
"write_graphite plugin: Successfully connected to %s:%s via %s.",
else
cb->reconnect_interval_reached = 0;
- return (0);
+ return 0;
}
static void wg_callback_free(void *data) {
int status;
if (user_data == NULL)
- return (-EINVAL);
+ return -EINVAL;
cb = user_data->data;
if (status != 0) {
/* An error message has already been printed. */
pthread_mutex_unlock(&cb->send_lock);
- return (-1);
+ return -1;
}
}
status = wg_flush_nolock(timeout, cb);
pthread_mutex_unlock(&cb->send_lock);
- return (status);
+ return status;
}
static int wg_send_message(char const *message, struct wg_callback *cb) {
if (status != 0) {
/* An error message has already been printed. */
pthread_mutex_unlock(&cb->send_lock);
- return (-1);
+ return -1;
}
}
status = wg_flush_nolock(/* timeout = */ 0, cb);
if (status != 0) {
pthread_mutex_unlock(&cb->send_lock);
- return (status);
+ return status;
}
}
pthread_mutex_unlock(&cb->send_lock);
- return (0);
+ return 0;
}
static int wg_write_messages(const data_set_t *ds, const value_list_t *vl,
status = format_graphite(buffer, sizeof(buffer), ds, vl, cb->prefix,
cb->postfix, cb->escape_char, cb->format_flags);
if (status != 0) /* error message has been printed already. */
- return (status);
+ return status;
/* Send the message to graphite */
status = wg_send_message(buffer, cb);
if (status != 0) /* error message has been printed already. */
- return (status);
+ return status;
- return (0);
+ return 0;
} /* int wg_write_messages */
static int wg_write(const data_set_t *ds, const value_list_t *vl,
int status;
if (user_data == NULL)
- return (EINVAL);
+ return EINVAL;
cb = user_data->data;
status = wg_write_messages(ds, vl, cb);
- return (status);
+ return status;
}
static int config_set_char(char *dest, oconfig_item_t *ci) {
status = cf_util_get_string_buffer(ci, buffer, sizeof(buffer));
if (status != 0)
- return (status);
+ return status;
if (buffer[0] == 0) {
ERROR("write_graphite plugin: Cannot use an empty string for the "
"\"EscapeCharacter\" option.");
- return (-1);
+ return -1;
}
if (buffer[1] != 0) {
*dest = buffer[0];
- return (0);
+ return 0;
}
static int wg_config_node(oconfig_item_t *ci) {
cb = calloc(1, sizeof(*cb));
if (cb == NULL) {
ERROR("write_graphite plugin: calloc failed.");
- return (-1);
+ return -1;
}
cb->sock_fd = -1;
cb->name = NULL;
status = cf_util_get_string(ci, &cb->name);
if (status != 0) {
wg_callback_free(cb);
- return (status);
+ return status;
}
}
if (status != 0) {
wg_callback_free(cb);
- return (status);
+ return status;
}
/* FIXME: Legacy configuration syntax. */
if (cb->name == NULL)
- ssnprintf(callback_name, sizeof(callback_name), "write_graphite/%s/%s/%s",
- cb->node, cb->service, cb->protocol);
+ snprintf(callback_name, sizeof(callback_name), "write_graphite/%s/%s/%s",
+ cb->node, cb->service, cb->protocol);
else
- ssnprintf(callback_name, sizeof(callback_name), "write_graphite/%s",
- cb->name);
+ snprintf(callback_name, sizeof(callback_name), "write_graphite/%s",
+ cb->name);
plugin_register_write(callback_name, wg_write,
&(user_data_t){
plugin_register_flush(callback_name, wg_flush, &(user_data_t){.data = cb});
- return (0);
+ return 0;
}
static int wg_config(oconfig_item_t *ci) {
}
}
- return (0);
+ return 0;
}
void module_register(void) {
plugin_register_complex_config("write_graphite", wg_config);
}
-
-/* vim: set sw=4 ts=4 sts=4 tw=78 et : */
#define WRITE_HTTP_DEFAULT_BUFFER_SIZE 4096
#endif
+#ifndef WRITE_HTTP_DEFAULT_PREFIX
+#define WRITE_HTTP_DEFAULT_PREFIX "collectd"
+#endif
+
/*
* Private variables
*/
cdtime_t send_buffer_init_time;
pthread_mutex_t send_lock;
+
+ int data_ttl;
+ char *metrics_prefix;
};
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;
"status %i: %s",
status, cb->curl_errbuf);
}
- return (status);
+ return status;
} /* }}} wh_post_nolock */
static int wh_callback_init(wh_callback_t *cb) /* {{{ */
{
if (cb->curl != NULL)
- return (0);
+ return 0;
cb->curl = curl_easy_init();
if (cb->curl == NULL) {
ERROR("curl plugin: curl_easy_init failed.");
- return (-1);
+ return -1;
}
if (cb->low_speed_limit > 0 && cb->low_speed_time > 0) {
cb->credentials = malloc(credentials_size);
if (cb->credentials == NULL) {
ERROR("curl plugin: malloc failed.");
- return (-1);
+ return -1;
}
- ssnprintf(cb->credentials, credentials_size, "%s:%s", cb->user,
- (cb->pass == NULL) ? "" : cb->pass);
+ snprintf(cb->credentials, credentials_size, "%s:%s", cb->user,
+ (cb->pass == NULL) ? "" : cb->pass);
curl_easy_setopt(cb->curl, CURLOPT_USERPWD, cb->credentials);
#endif
curl_easy_setopt(cb->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
wh_reset_buffer(cb);
- return (0);
+ return 0;
} /* }}} int wh_callback_init */
static int wh_flush_nolock(cdtime_t timeout, wh_callback_t *cb) /* {{{ */
now = cdtime();
if ((cb->send_buffer_init_time + timeout) > now)
- return (0);
+ return 0;
}
if (cb->format == WH_FORMAT_COMMAND) {
if (cb->send_buffer_fill == 0) {
cb->send_buffer_init_time = cdtime();
- return (0);
+ return 0;
}
status = wh_post_nolock(cb, cb->send_buffer);
} else if (cb->format == WH_FORMAT_JSON || cb->format == WH_FORMAT_KAIROSDB) {
if (cb->send_buffer_fill <= 2) {
cb->send_buffer_init_time = cdtime();
- return (0);
+ return 0;
}
status = format_json_finalize(cb->send_buffer, &cb->send_buffer_fill,
ERROR("write_http: wh_flush_nolock: "
"format_json_finalize failed.");
wh_reset_buffer(cb);
- return (status);
+ return status;
}
status = wh_post_nolock(cb, cb->send_buffer);
ERROR("write_http: wh_flush_nolock: "
"Unknown format: %i",
cb->format);
- return (-1);
+ return -1;
}
- return (status);
+ return status;
} /* }}} wh_flush_nolock */
static int wh_flush(cdtime_t timeout, /* {{{ */
int status;
if (user_data == NULL)
- return (-EINVAL);
+ return -EINVAL;
cb = user_data->data;
if (wh_callback_init(cb) != 0) {
ERROR("write_http plugin: wh_callback_init failed.");
pthread_mutex_unlock(&cb->send_lock);
- return (-1);
+ return -1;
}
status = wh_flush_nolock(timeout, cb);
pthread_mutex_unlock(&cb->send_lock);
- return (status);
+ return status;
} /* }}} int wh_flush */
static void wh_callback_free(void *data) /* {{{ */
sfree(cb->clientcert);
sfree(cb->clientkeypass);
sfree(cb->send_buffer);
+ sfree(cb->metrics_prefix);
sfree(cb);
} /* }}} void wh_callback_free */
status = FORMAT_VL(key, sizeof(key), vl);
if (status != 0) {
ERROR("write_http plugin: error with format_name");
- return (status);
+ return status;
}
escape_string(key, sizeof(key));
if (status != 0) {
ERROR("write_http plugin: error with "
"wh_value_list_to_string");
- return (status);
+ return status;
}
- command_len = (size_t)ssnprintf(command, sizeof(command),
- "PUTVAL %s interval=%.3f %s\r\n", key,
- CDTIME_T_TO_DOUBLE(vl->interval), values);
+ command_len = (size_t)snprintf(command, sizeof(command),
+ "PUTVAL %s interval=%.3f %s\r\n", key,
+ CDTIME_T_TO_DOUBLE(vl->interval), values);
if (command_len >= sizeof(command)) {
ERROR("write_http plugin: Command buffer too small: "
"Need %zu bytes.",
command_len + 1);
- return (-1);
+ return -1;
}
pthread_mutex_lock(&cb->send_lock);
if (wh_callback_init(cb) != 0) {
ERROR("write_http plugin: wh_callback_init failed.");
pthread_mutex_unlock(&cb->send_lock);
- return (-1);
+ return -1;
}
if (command_len >= cb->send_buffer_free) {
status = wh_flush_nolock(/* timeout = */ 0, cb);
if (status != 0) {
pthread_mutex_unlock(&cb->send_lock);
- return (status);
+ return status;
}
}
assert(command_len < cb->send_buffer_free);
/* Check if we have enough space for this command. */
pthread_mutex_unlock(&cb->send_lock);
- return (0);
+ return 0;
} /* }}} int wh_write_command */
static int wh_write_json(const data_set_t *ds, const value_list_t *vl, /* {{{ */
if (wh_callback_init(cb) != 0) {
ERROR("write_http plugin: wh_callback_init failed.");
pthread_mutex_unlock(&cb->send_lock);
- return (-1);
+ return -1;
}
status =
if (status != 0) {
wh_reset_buffer(cb);
pthread_mutex_unlock(&cb->send_lock);
- return (status);
+ return status;
}
status =
}
if (status != 0) {
pthread_mutex_unlock(&cb->send_lock);
- return (status);
+ return status;
}
DEBUG("write_http plugin: <%s> buffer %zu/%zu (%g%%)", cb->location,
/* Check if we have enough space for this command. */
pthread_mutex_unlock(&cb->send_lock);
- return (0);
+ return 0;
} /* }}} int wh_write_json */
static int wh_write_kairosdb(const data_set_t *ds,
if (status != 0) {
ERROR("write_http plugin: wh_callback_init failed.");
pthread_mutex_unlock(&cb->send_lock);
- return (-1);
+ return -1;
}
}
- 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,
+ cb->data_ttl, cb->metrics_prefix);
if (status == -ENOMEM) {
status = wh_flush_nolock(/* timeout = */ 0, cb);
if (status != 0) {
wh_reset_buffer(cb);
pthread_mutex_unlock(&cb->send_lock);
- return (status);
+ 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,
+ cb->data_ttl, cb->metrics_prefix);
}
if (status != 0) {
pthread_mutex_unlock(&cb->send_lock);
- return (status);
+ return status;
}
DEBUG("write_http plugin: <%s> buffer %zu/%zu (%g%%)", cb->location,
/* Check if we have enough space for this command. */
pthread_mutex_unlock(&cb->send_lock);
- return (0);
+ return 0;
} /* }}} int wh_write_kairosdb */
static int wh_write(const data_set_t *ds, const value_list_t *vl, /* {{{ */
int status;
if (user_data == NULL)
- return (-EINVAL);
+ return -EINVAL;
cb = user_data->data;
assert(cb->send_metrics);
status = wh_write_command(ds, vl, cb);
break;
}
- return (status);
+ return status;
} /* }}} int wh_write */
static int wh_notify(notification_t const *n, user_data_t *ud) /* {{{ */
int status;
if ((ud == NULL) || (ud->data == NULL))
- return (EINVAL);
+ return EINVAL;
cb = ud->data;
assert(cb->send_notifications);
if (wh_callback_init(cb) != 0) {
ERROR("write_http plugin: wh_callback_init failed.");
pthread_mutex_unlock(&cb->send_lock);
- return (-1);
+ return -1;
}
status = wh_post_nolock(cb, alert);
pthread_mutex_unlock(&cb->send_lock);
- return (status);
+ return status;
} /* }}} int wh_notify */
static int config_set_format(wh_callback_t *cb, /* {{{ */
WARNING("write_http plugin: The `%s' config option "
"needs exactly one string argument.",
ci->key);
- return (-1);
+ return -1;
}
string = ci->values[0].value.string;
cb->format = WH_FORMAT_KAIROSDB;
else {
ERROR("write_http plugin: Invalid format string: %s", string);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
} /* }}} int config_set_format */
static int wh_config_append_string(const char *name,
struct curl_slist *temp = NULL;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("write_http plugin: `%s' needs exactly one string argument.", name);
- return (-1);
+ return -1;
}
temp = curl_slist_append(*dest, ci->values[0].value.string);
if (temp == NULL)
- return (-1);
+ return -1;
*dest = temp;
- return (0);
+ return 0;
} /* }}} int wh_config_append_string */
static int wh_config_node(oconfig_item_t *ci) /* {{{ */
cb = calloc(1, sizeof(*cb));
if (cb == NULL) {
ERROR("write_http plugin: calloc failed.");
- return (-1);
+ return -1;
}
cb->verify_peer = 1;
cb->verify_host = 1;
cb->headers = NULL;
cb->send_metrics = 1;
cb->send_notifications = 0;
+ cb->data_ttl = 0;
+ cb->metrics_prefix = strdup(WRITE_HTTP_DEFAULT_PREFIX);
+
+ if (cb->metrics_prefix == NULL) {
+ ERROR("write_http plugin: strdup failed.");
+ sfree(cb);
+ return -1;
+ }
pthread_mutex_init(&cb->send_lock, /* attr = */ NULL);
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 if (strcasecmp("TTL", child->key) == 0) {
+ status = cf_util_get_int(child, &cb->data_ttl);
+ } else if (strcasecmp("Prefix", child->key) == 0) {
+ status = cf_util_get_string(child, &cb->metrics_prefix);
+ } else {
ERROR("write_http plugin: Invalid configuration "
"option: %s.",
child->key);
if (status != 0) {
wh_callback_free(cb);
- return (status);
+ return status;
}
if (cb->location == NULL) {
ERROR("write_http plugin: no URL defined for instance '%s'", cb->name);
wh_callback_free(cb);
- return (-1);
+ return -1;
}
if (!cb->send_metrics && !cb->send_notifications) {
"are enabled for \"%s\".",
cb->name);
wh_callback_free(cb);
- return (-1);
+ return -1;
}
+ if (strlen(cb->metrics_prefix) == 0)
+ sfree(cb->metrics_prefix);
+
if (cb->low_speed_limit > 0)
cb->low_speed_time = CDTIME_T_TO_TIME_T(plugin_get_interval());
if (cb->send_buffer == NULL) {
ERROR("write_http plugin: malloc(%zu) failed.", cb->send_buffer_size);
wh_callback_free(cb);
- return (-1);
+ return -1;
}
/* Nulls the buffer and sets ..._free and ..._fill. */
wh_reset_buffer(cb);
- ssnprintf(callback_name, sizeof(callback_name), "write_http/%s", cb->name);
+ snprintf(callback_name, sizeof(callback_name), "write_http/%s", cb->name);
DEBUG("write_http: Registering write callback '%s' with URL '%s'",
callback_name, cb->location);
user_data.free_func = NULL;
}
- return (0);
+ return 0;
} /* }}} int wh_config_node */
static int wh_config(oconfig_item_t *ci) /* {{{ */
}
}
- return (0);
+ return 0;
} /* }}} int wh_config */
static int wh_init(void) /* {{{ */
/* Call this while collectd is still single-threaded to avoid
* initialization issues in libgcrypt. */
curl_global_init(CURL_GLOBAL_SSL);
- return (0);
+ return 0;
} /* }}} int wh_init */
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 : */
#define KAFKA_RANDOM_KEY_BUFFER \
(char[KAFKA_RANDOM_KEY_SIZE]) { "" }
static char *kafka_random_key(char buffer[static KAFKA_RANDOM_KEY_SIZE]) {
- ssnprintf(buffer, KAFKA_RANDOM_KEY_SIZE, "%08" PRIX32, cdrand_u());
+ snprintf(buffer, KAFKA_RANDOM_KEY_SIZE, "%08" PRIX32, cdrand_u());
return buffer;
}
rd_kafka_topic_conf_t *topic_conf;
if (ctx->kafka != NULL && ctx->topic != NULL)
- return (0);
+ return 0;
if (ctx->kafka == NULL) {
if ((conf = rd_kafka_conf_dup(ctx->kafka_conf)) == NULL) {
ERROR("write_kafka plugin: cannot duplicate kafka config");
- return (1);
+ return 1;
}
if ((ctx->kafka = rd_kafka_new(RD_KAFKA_PRODUCER, conf, errbuf,
rd_kafka_topic_name(ctx->topic));
}
- return (0);
+ return 0;
} /* }}} int kafka_handle */
rd_kafka_topic_conf_set_partitioner_cb(tctx->conf, kafka_partition);
rd_kafka_topic_conf_set_opaque(tctx->conf, tctx);
- ssnprintf(callback_name, sizeof(callback_name), "write_kafka/%s",
- tctx->topic_name);
+ snprintf(callback_name, sizeof(callback_name), "write_kafka/%s",
+ tctx->topic_name);
status = plugin_register_write(
callback_name, kafka_write,
}
if (conf != NULL)
rd_kafka_conf_destroy(conf);
- return (0);
+ return 0;
errout:
if (conf != NULL)
rd_kafka_conf_destroy(conf);
status = format_graphite(buffer, sizeof(buffer), ds, vl, NULL, NULL, '_', 0);
if (status != 0) /* error message has been printed already. */
- return (status);
+ return status;
INFO("write_log values:\n%s", buffer);
- return (0);
+ return 0;
} /* int wl_write_graphite */
static int wl_write_json(const data_set_t *ds, const value_list_t *vl) {
INFO("write_log values:\n%s", buffer);
- return (0);
+ return 0;
} /* int wl_write_json */
static int wl_write(const data_set_t *ds, const value_list_t *vl,
status = wl_write_json(ds, vl);
}
- return (status);
+ return status;
}
static int wl_config(oconfig_item_t *ci) /* {{{ */
else {
ERROR("write_log plugin: Unknown format `%s' for option `%s'.", str,
child->key);
- return (-EINVAL);
+ return -EINVAL;
}
} else {
ERROR("write_log plugin: Invalid configuration option: `%s'.",
child->key);
- return (-EINVAL);
+ return -EINVAL;
}
}
- return (0);
+ return 0;
} /* }}} int wl_config */
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 : */
* 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"),
* Florian Forster <octo at collectd.org>
* Akkarit Sangpetch <asangpet at andrew.cmu.edu>
* Chris Lundquist <clundquist at bluebox.net>
+ * Saikrishna Arcot <saiarcot895 at gmail.com>
**/
#include "collectd.h"
#include "plugin.h"
#include "utils_cache.h"
-#if HAVE_STDINT_H
-#define MONGO_HAVE_STDINT 1
-#else
-#define MONGO_USE_LONG_LONG_INT 1
-#endif
-#include <mongo.h>
-
-#if (MONGO_MAJOR == 0) && (MONGO_MINOR < 8)
-#define bson_alloc() bson_create()
-#define bson_dealloc(b) bson_dispose(b)
-#endif
+#include <mongoc.h>
struct wm_node_s {
char name[DATA_MAX_NAME_LEN];
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;
/*
* 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_destroy(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"); /* {{{ */
- for (int i = 0; i < ds->ds_num; i++) {
+ BSON_APPEND_ARRAY_BEGIN(ret, "values", &subarray); /* {{{ */
+ for (size_t i = 0; i < ds->ds_num; i++) {
char key[16];
- ssnprintf(key, sizeof(key), "%i", i);
+ snprintf(key, sizeof(key), "%zu", 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 %zu",
+ ds->ds[i].type, i);
+ bson_destroy(ret);
+ return NULL;
+ }
}
- bson_append_finish_array(ret); /* }}} values */
+ bson_append_array_end(ret, &subarray); /* }}} values */
- bson_append_start_array(ret, "dstypes"); /* {{{ */
- for (int i = 0; i < ds->ds_num; i++) {
+ BSON_APPEND_ARRAY_BEGIN(ret, "dstypes", &subarray); /* {{{ */
+ for (size_t i = 0; i < ds->ds_num; i++) {
char key[16];
- ssnprintf(key, sizeof(key), "%i", i);
+ snprintf(key, sizeof(key), "%zu", 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"); /* {{{ */
- for (int i = 0; i < ds->ds_num; i++) {
+ BSON_APPEND_ARRAY_BEGIN(ret, "dsnames", &subarray); /* {{{ */
+ for (size_t 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);
+ snprintf(key, sizeof(key), "%zu", i);
+ 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_destroy(ret);
+ return NULL;
+ }
+
+ return ret;
} /* }}} bson *wm_create_bson */
+static int wm_initialize(wm_node_t *node) /* {{{ */
+{
+ char *uri;
+
+ if (node->connected)
+ return 0;
+
+ INFO("write_mongodb plugin: Connecting to [%s]:%d", node->host, node->port);
+
+ if ((node->db != NULL) && (node->user != NULL) && (node->passwd != NULL)) {
+ uri = ssnprintf_alloc("mongodb://%s:%s@%s:%d/?authSource=%s", node->user,
+ node->passwd, node->host, node->port, node->db);
+ if (uri == 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;
+ }
+
+ node->client = mongoc_client_new(uri);
+ if (!node->client) {
+ ERROR("write_mongodb plugin: Authenticating to [%s]:%d for database "
+ "\"%s\" as user \"%s\" failed.",
+ node->host, node->port, node->db, node->user);
+ node->connected = 0;
+ sfree(uri);
+ return -1;
+ }
+ } else {
+ uri = ssnprintf_alloc("mongodb://%s:%d", node->host, node->port);
+ if (uri == 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;
+ }
+
+ node->client = mongoc_client_new(uri);
+ if (!node->client) {
+ ERROR("write_mongodb plugin: Connecting to [%s]:%d failed.", node->host,
+ node->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;
+ }
+
+ node->connected = 1;
+ return 0;
+} /* }}} int wm_initialize */
+
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;
+ mongoc_collection_t *collection = NULL;
+ bson_t *bson_record;
+ bson_error_t error;
int status;
- ssnprintf(collection_name, sizeof(collection_name), "collectd.%s",
- vl->plugin);
-
bson_record = wm_create_bson(ds, vl, node->store_rates);
- if (bson_record == NULL)
- return (ENOMEM);
+ if (!bson_record) {
+ ERROR("write_mongodb plugin: error making insert bson");
+ return -1;
+ }
pthread_mutex_lock(&node->lock);
-
- 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) {
- 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);
- }
-
- 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);
- }
- }
-
- 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);
- }
- }
+ if (wm_initialize(node) < 0) {
+ ERROR("write_mongodb plugin: error making connection to server");
+ pthread_mutex_unlock(&node->lock);
+ bson_destroy(bson_record);
+ 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);
+ 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_destroy(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);
+ 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_destroy(bson_record);
+ mongoc_collection_destroy(collection);
+ return -1;
}
+ /* free our resource as not to leak memory */
+ mongoc_collection_destroy(collection);
+
pthread_mutex_unlock(&node->lock);
- /* free our resource as not to leak memory */
- bson_destroy(bson_record); /* matches bson_init() */
- bson_dealloc(bson_record); /* matches bson_alloc() */
+ bson_destroy(bson_record);
- return (0);
+ return 0;
} /* }}} int wm_write */
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);
node = calloc(1, sizeof(*node));
if (node == NULL)
- return (ENOMEM);
- mongo_init(node->conn);
- node->host = NULL;
+ return ENOMEM;
+ mongoc_init();
+ node->host = strdup("localhost");
+ if (node->host == NULL) {
+ sfree(node);
+ return ENOMEM;
+ }
+ node->port = MONGOC_DEFAULT_PORT;
node->store_rates = 1;
pthread_mutex_init(&node->lock, /* attr = */ NULL);
status = cf_util_get_string_buffer(ci, node->name, sizeof(node->name));
if (status != 0) {
+ sfree(node->host);
sfree(node);
- return (status);
+ return status;
}
for (int i = 0; i < ci->children_num; i++) {
}
if (status == 0) {
- char cb_name[DATA_MAX_NAME_LEN];
+ char cb_name[sizeof("write_mongodb/") + DATA_MAX_NAME_LEN];
- ssnprintf(cb_name, sizeof(cb_name), "write_mongodb/%s", node->name);
+ snprintf(cb_name, sizeof(cb_name), "write_mongodb/%s", node->name);
- status = plugin_register_write(
- cb_name, wm_write, &(user_data_t){
- .data = node, .free_func = wm_config_free,
- });
+ status =
+ plugin_register_write(cb_name, wm_write,
+ &(user_data_t){
+ .data = node, .free_func = wm_config_free,
+ });
INFO("write_mongodb plugin: registered write plugin %s %d", cb_name,
status);
}
if (status != 0)
wm_config_free(node);
- return (status);
+ return status;
} /* }}} int wm_config_node */
static int wm_config(oconfig_item_t *ci) /* {{{ */
child->key);
}
- return (0);
+ return 0;
} /* }}} int wm_config */
void module_register(void) {
plugin_register_complex_config("write_mongodb", wm_config);
}
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
* know that they are sane. */
for (size_t i = 0; i < m->n_label; i++) {
char value[LABEL_VALUE_SIZE];
- ssnprintf(labels[i], LABEL_BUFFER_SIZE, "%s=\"%s\"", m->label[i]->name,
- escape_label_value(value, sizeof(value), m->label[i]->value));
+ snprintf(labels[i], LABEL_BUFFER_SIZE, "%s=\"%s\"", m->label[i]->name,
+ escape_label_value(value, sizeof(value), m->label[i]->value));
}
strjoin(buffer, buffer_size, labels, m->n_label, ",");
while (c_avl_iterator_next(iter, (void *)&unused_name, (void *)&fam) == 0) {
char line[1024]; /* 4x DATA_MAX_NAME_LEN? */
- ssnprintf(line, sizeof(line), "# HELP %s %s\n", fam->name, fam->help);
+ snprintf(line, sizeof(line), "# HELP %s %s\n", fam->name, fam->help);
buffer->append(buffer, strlen(line), (uint8_t *)line);
- ssnprintf(line, sizeof(line), "# TYPE %s %s\n", fam->name,
- (fam->type == IO__PROMETHEUS__CLIENT__METRIC_TYPE__GAUGE)
- ? "gauge"
- : "counter");
+ snprintf(line, sizeof(line), "# TYPE %s %s\n", fam->name,
+ (fam->type == IO__PROMETHEUS__CLIENT__METRIC_TYPE__GAUGE)
+ ? "gauge"
+ : "counter");
buffer->append(buffer, strlen(line), (uint8_t *)line);
for (size_t i = 0; i < fam->n_metric; i++) {
char timestamp_ms[24] = "";
if (m->has_timestamp_ms)
- ssnprintf(timestamp_ms, sizeof(timestamp_ms), " %" PRIi64,
- m->timestamp_ms);
+ snprintf(timestamp_ms, sizeof(timestamp_ms), " %" PRIi64,
+ m->timestamp_ms);
if (fam->type == IO__PROMETHEUS__CLIENT__METRIC_TYPE__GAUGE)
- ssnprintf(line, sizeof(line), "%s{%s} " GAUGE_FORMAT "%s\n", fam->name,
- format_labels(labels, sizeof(labels), m), m->gauge->value,
- timestamp_ms);
+ snprintf(line, sizeof(line), "%s{%s} " GAUGE_FORMAT "%s\n", fam->name,
+ format_labels(labels, sizeof(labels), m), m->gauge->value,
+ timestamp_ms);
else /* if (fam->type == IO__PROMETHEUS__CLIENT__METRIC_TYPE__COUNTER) */
- ssnprintf(line, sizeof(line), "%s{%s} %.0f%s\n", fam->name,
- format_labels(labels, sizeof(labels), m), m->counter->value,
- timestamp_ms);
+ snprintf(line, sizeof(line), "%s{%s} %.0f%s\n", fam->name,
+ format_labels(labels, sizeof(labels), m), m->counter->value,
+ timestamp_ms);
buffer->append(buffer, strlen(line), (uint8_t *)line);
}
c_avl_iterator_destroy(iter);
char server[1024];
- ssnprintf(server, sizeof(server), "\n# collectd/write_prometheus %s at %s\n",
- PACKAGE_VERSION, hostname_g);
+ snprintf(server, sizeof(server), "\n# collectd/write_prometheus %s at %s\n",
+ PACKAGE_VERSION, hostname_g);
buffer->append(buffer, strlen(server), (uint8_t *)server);
pthread_mutex_unlock(&metrics_lock);
msg->name = name;
char help[1024];
- ssnprintf(
+ snprintf(
help, sizeof(help),
"write_prometheus plugin: '%s' Type: '%s', Dstype: '%s', Dsname: '%s'",
vl->plugin, vl->type, DS_TYPE_TO_STRING(ds->ds[ds_index].type),
/* user data = */ NULL);
plugin_register_shutdown("write_prometheus", prom_shutdown);
}
-
-/* vim: set sw=2 sts=2 et fdm=marker : */
char *prefix;
int database;
int max_set_size;
+ int max_set_duration;
_Bool store_rates;
redisContext *conn;
status = FORMAT_VL(ident, sizeof(ident), vl);
if (status != 0)
- return (status);
- ssnprintf(key, sizeof(key), "%s%s",
- (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX,
- ident);
- ssnprintf(time, sizeof(time), "%.9f", CDTIME_T_TO_DOUBLE(vl->time));
+ return status;
+ snprintf(key, sizeof(key), "%s%s",
+ (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX, ident);
+ snprintf(time, sizeof(time), "%.9f", CDTIME_T_TO_DOUBLE(vl->time));
value_size = sizeof(value);
value_ptr = &value[0];
status = format_values(value_ptr, value_size, ds, vl, node->store_rates);
if (status != 0)
- return (status);
+ return status;
pthread_mutex_lock(&node->lock);
(node->host != NULL) ? node->host : "localhost",
(node->port != 0) ? node->port : 6379);
pthread_mutex_unlock(&node->lock);
- return (-1);
+ return -1;
} else if (node->conn->err) {
ERROR(
"write_redis plugin: Connecting to host \"%s\" (port %i) failed: %s",
(node->host != NULL) ? node->host : "localhost",
(node->port != 0) ? node->port : 6379, node->conn->errstr);
pthread_mutex_unlock(&node->lock);
- return (-1);
+ return -1;
}
rr = redisCommand(node->conn, "SELECT %d", node->database);
freeReplyObject(rr);
}
+ if (node->max_set_duration > 0) {
+ /*
+ * remove element, scored less than 'current-max_set_duration'
+ * '(%d' indicates 'less than' in redis CLI.
+ */
+ rr = redisCommand(node->conn, "ZREMRANGEBYSCORE %s -1 (%d", key,
+ (time - node->max_set_duration) + 1);
+ if (rr == NULL)
+ WARNING("ZREMRANGEBYSCORE command error. key:%s message:%s", key,
+ node->conn->errstr);
+ else
+ freeReplyObject(rr);
+ }
+
/* TODO(octo): This is more overhead than necessary. Use the cache and
* metadata to determine if it is a new metric and call SADD only once for
* each metric. */
pthread_mutex_unlock(&node->lock);
- return (0);
+ return 0;
} /* }}} int wr_write */
static void wr_config_free(void *ptr) /* {{{ */
node = calloc(1, sizeof(*node));
if (node == NULL)
- return (ENOMEM);
+ return ENOMEM;
node->host = NULL;
node->port = 0;
node->timeout.tv_sec = 0;
node->prefix = NULL;
node->database = 0;
node->max_set_size = -1;
+ node->max_set_duration = -1;
node->store_rates = 1;
pthread_mutex_init(&node->lock, /* attr = */ NULL);
status = cf_util_get_string_buffer(ci, node->name, sizeof(node->name));
if (status != 0) {
sfree(node);
- return (status);
+ return status;
}
for (int i = 0; i < ci->children_num; i++) {
status = cf_util_get_int(child, &node->database);
} else if (strcasecmp("MaxSetSize", child->key) == 0) {
status = cf_util_get_int(child, &node->max_set_size);
+ } else if (strcasecmp("MaxSetDuration", child->key) == 0) {
+ status = cf_util_get_int(child, &node->max_set_duration);
} else if (strcasecmp("StoreRates", child->key) == 0) {
status = cf_util_get_boolean(child, &node->store_rates);
} else
} /* for (i = 0; i < ci->children_num; i++) */
if (status == 0) {
- char cb_name[DATA_MAX_NAME_LEN];
+ char cb_name[sizeof("write_redis/") + DATA_MAX_NAME_LEN];
- ssnprintf(cb_name, sizeof(cb_name), "write_redis/%s", node->name);
+ snprintf(cb_name, sizeof(cb_name), "write_redis/%s", node->name);
- status = plugin_register_write(
- cb_name, wr_write, &(user_data_t){
- .data = node, .free_func = wr_config_free,
- });
+ status =
+ plugin_register_write(cb_name, wr_write,
+ &(user_data_t){
+ .data = node, .free_func = wr_config_free,
+ });
}
if (status != 0)
wr_config_free(node);
- return (status);
+ return status;
} /* }}} int wr_config_node */
static int wr_config(oconfig_item_t *ci) /* {{{ */
child->key);
}
- return (0);
+ return 0;
} /* }}} int wr_config */
void module_register(void) {
plugin_register_complex_config("write_redis", wr_config);
}
-
-/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */
static int wrr_disconnect(struct riemann_host *host) /* {{{ */
{
if (!host->client)
- return (0);
+ return 0;
riemann_client_free(host->client);
host->client = NULL;
- return (0);
+ return 0;
} /* }}} int wrr_disconnect */
/**
RIEMANN_EVENT_FIELD_SERVICE, &service_buffer[1],
RIEMANN_EVENT_FIELD_NONE);
+#if RCC_VERSION_NUMBER >= 0x010A00
+ riemann_event_set(event, RIEMANN_EVENT_FIELD_TIME_MICROS,
+ (int64_t)CDTIME_T_TO_US(n->time));
+#endif
+
if (n->host[0] != 0)
riemann_event_string_attribute_add(event, "host", n->host);
if (n->plugin[0] != 0)
if (msg == NULL) {
ERROR("write_riemann plugin: riemann_message_create_with_events() failed.");
riemann_event_free(event);
- return (NULL);
+ return NULL;
}
DEBUG("write_riemann plugin: Successfully created message for notification: "
"host = \"%s\", service = \"%s\", state = \"%s\"",
event->host, event->service, event->state);
- return (msg);
+ return msg;
} /* }}} riemann_message_t *wrr_notification_to_message */
static riemann_event_t *
event = riemann_event_new();
if (event == NULL) {
ERROR("write_riemann plugin: riemann_event_new() failed.");
- return (NULL);
+ return NULL;
}
format_name(name_buffer, sizeof(name_buffer),
vl->type_instance);
if (host->always_append_ds || (ds->ds_num > 1)) {
if (host->event_service_prefix == NULL)
- ssnprintf(service_buffer, sizeof(service_buffer), "%s/%s",
- &name_buffer[1], ds->ds[index].name);
+ snprintf(service_buffer, sizeof(service_buffer), "%s/%s", &name_buffer[1],
+ ds->ds[index].name);
else
- ssnprintf(service_buffer, sizeof(service_buffer), "%s%s/%s",
- host->event_service_prefix, &name_buffer[1],
- ds->ds[index].name);
+ snprintf(service_buffer, sizeof(service_buffer), "%s%s/%s",
+ host->event_service_prefix, &name_buffer[1], ds->ds[index].name);
} else {
if (host->event_service_prefix == NULL)
sstrncpy(service_buffer, &name_buffer[1], sizeof(service_buffer));
else
- ssnprintf(service_buffer, sizeof(service_buffer), "%s%s",
- host->event_service_prefix, &name_buffer[1]);
+ snprintf(service_buffer, sizeof(service_buffer), "%s%s",
+ host->event_service_prefix, &name_buffer[1]);
}
riemann_event_set(
vl->type, "ds_name", ds->ds[index].name, NULL,
RIEMANN_EVENT_FIELD_SERVICE, service_buffer, RIEMANN_EVENT_FIELD_NONE);
+#if RCC_VERSION_NUMBER >= 0x010A00
+ riemann_event_set(event, RIEMANN_EVENT_FIELD_TIME_MICROS,
+ (int64_t)CDTIME_T_TO_US(vl->time));
+#endif
+
if (host->check_thresholds) {
const char *state = NULL;
if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) {
char ds_type[DATA_MAX_NAME_LEN];
- ssnprintf(ds_type, sizeof(ds_type), "%s:rate",
- DS_TYPE_TO_STRING(ds->ds[index].type));
+ snprintf(ds_type, sizeof(ds_type), "%s:rate",
+ DS_TYPE_TO_STRING(ds->ds[index].type));
riemann_event_string_attribute_add(event, "ds_type", ds_type);
} else {
riemann_event_string_attribute_add(event, "ds_type",
{
char ds_index[DATA_MAX_NAME_LEN];
- ssnprintf(ds_index, sizeof(ds_index), "%zu", index);
+ snprintf(ds_index, sizeof(ds_index), "%zu", index);
riemann_event_string_attribute_add(event, "ds_index", ds_index);
}
DEBUG("write_riemann plugin: Successfully created message for metric: "
"host = \"%s\", service = \"%s\"",
event->host, event->service);
- return (event);
+ return event;
} /* }}} riemann_event_t *wrr_value_to_event */
static riemann_message_t *
msg = riemann_message_new();
if (msg == NULL) {
ERROR("write_riemann plugin: riemann_message_new failed.");
- return (NULL);
+ return NULL;
}
if (host->store_rates) {
if (rates == NULL) {
ERROR("write_riemann plugin: uc_get_rate failed.");
riemann_message_free(msg);
- return (NULL);
+ return NULL;
}
}
if (event == NULL) {
riemann_message_free(msg);
sfree(rates);
- return (NULL);
+ return NULL;
}
riemann_message_append_events(msg, event, NULL);
}
sfree(rates);
- return (msg);
+ return msg;
} /* }}} riemann_message_t *wrr_value_list_to_message */
/*
int status;
if (user_data == NULL)
- return (-EINVAL);
+ return -EINVAL;
host = user_data->data;
pthread_mutex_lock(&host->lock);
*/
msg = wrr_notification_to_message(host, n);
if (msg == NULL)
- return (-1);
+ return -1;
status = wrr_send(host, msg);
if (status != 0)
"write_riemann plugin: riemann_client_send succeeded");
riemann_message_free(msg);
- return (status);
+ return status;
} /* }}} int wrr_notification */
static int wrr_write(const data_set_t *ds, /* {{{ */
} else {
msg = wrr_value_list_to_message(host, ds, vl, statuses);
if (msg == NULL)
- return (-1);
+ return -1;
status = wrr_send(host, msg);
return status;
}
- ssnprintf(callback_name, sizeof(callback_name), "write_riemann/%s",
- host->name);
+ snprintf(callback_name, sizeof(callback_name), "write_riemann/%s",
+ host->name);
user_data_t ud = {.data = host, .free_func = wrr_free};
* holding a reference. */
pthread_mutex_unlock(&host->lock);
wrr_free(host);
- return (-1);
+ return -1;
}
host->reference_count--;
if (child->values_num != 2) {
WARNING("riemann attributes need both a key and a value.");
- return (-1);
+ return -1;
}
if (child->values[0].type != OCONFIG_TYPE_STRING ||
child->values[1].type != OCONFIG_TYPE_STRING) {
WARNING("riemann attribute needs string arguments.");
- return (-1);
+ return -1;
}
if ((key = strdup(child->values[0].value.string)) == NULL) {
WARNING("cannot allocate memory for attribute key.");
- return (-1);
+ return -1;
}
if ((val = strdup(child->values[1].value.string)) == NULL) {
WARNING("cannot allocate memory for attribute value.");
sfree(key);
- return (-1);
+ return -1;
}
strarray_add(&riemann_attrs, &riemann_attrs_num, key);
strarray_add(&riemann_attrs, &riemann_attrs_num, val);
child->key);
}
}
- return (0);
+ return 0;
} /* }}} int wrr_config */
void module_register(void) {
plugin_register_complex_config("write_riemann", wrr_config);
}
-
-/* vim: set sw=8 sts=8 ts=8 noet : */
#include "utils_threshold.h"
#include "write_riemann_threshold.h"
-#include <ltdl.h>
-
/*
* Threshold management
* ====================
if (ds != NULL) {
ds_name = ds->ds[ds_index].name;
if ((th->data_source[0] != 0) && (strcmp(ds_name, th->data_source) != 0))
- return (STATE_OKAY);
+ return STATE_OKAY;
}
if ((th->flags & UT_FLAG_INVERT) != 0) {
((th->failure_min + th->hysteresis) < values[ds_index])) ||
(!isnan(th->failure_max) &&
((th->failure_max - th->hysteresis) > values[ds_index])))
- return (STATE_OKAY);
+ return STATE_OKAY;
else
is_failure++;
case STATE_WARNING:
((th->warning_min + th->hysteresis) < values[ds_index])) ||
(!isnan(th->warning_max) &&
((th->warning_max - th->hysteresis) > values[ds_index])))
- return (STATE_OKAY);
+ return STATE_OKAY;
else
is_warning++;
}
}
if (is_failure != 0)
- return (STATE_ERROR);
+ return STATE_ERROR;
if (is_warning != 0)
- return (STATE_WARNING);
+ return STATE_WARNING;
- return (STATE_OKAY);
+ return STATE_OKAY;
} /* }}} int ut_check_one_data_source */
/*
}
} /* for (ds->ds_num) */
- return (ret);
+ return ret;
} /* }}} int ut_check_one_threshold */
/*
th = threshold_search(vl);
pthread_mutex_unlock(&threshold_lock);
if (th == NULL)
- return (0);
+ return 0;
DEBUG("ut_check_threshold: Found matching threshold(s)");
values = uc_get_rate(ds, vl);
if (values == NULL)
- return (0);
+ return 0;
while (th != NULL) {
status = ut_check_one_threshold(ds, vl, th, values, statuses);
if (status < 0) {
ERROR("ut_check_threshold: ut_check_one_threshold failed.");
sfree(values);
- return (-1);
+ return -1;
}
th = th->next;
sfree(values);
- return (0);
+ return 0;
} /* }}} int ut_check_threshold */
-
-/* vim: set sw=2 ts=8 sts=2 tw=78 et fdm=marker : */
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);
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;
do { \
size_t l = strlen(str); \
if (l >= buffer_size) \
- return (ENOBUFS); \
+ return ENOBUFS; \
memcpy(buffer, (str), l); \
buffer += l; \
buffer_size -= l; \
buffer[0] = 0;
#undef APPEND
- return (0);
+ return 0;
} /* int sensu_format_name2 */
static void in_place_replace_sensu_name_reserved(char *orig_name) /* {{{ */
// incorporate the data source type
if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) {
char ds_type[DATA_MAX_NAME_LEN];
- ssnprintf(ds_type, sizeof(ds_type), "%s:rate",
- DS_TYPE_TO_STRING(ds->ds[index].type));
+ snprintf(ds_type, sizeof(ds_type), "%s:rate",
+ DS_TYPE_TO_STRING(ds->ds[index].type));
res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"",
ret_str, ds_type);
free(ret_str);
// incorporate the data source index
{
char ds_index[DATA_MAX_NAME_LEN];
- ssnprintf(ds_index, sizeof(ds_index), "%zu", index);
+ snprintf(ds_index, sizeof(ds_index), "%zu", index);
res = my_asprintf(&temp_str, "%s, \"collectd_data_source_index\": %s",
ret_str, ds_index);
free(ret_str);
host->separator);
if (host->always_append_ds || (ds->ds_num > 1)) {
if (host->event_service_prefix == NULL)
- ssnprintf(service_buffer, sizeof(service_buffer), "%s.%s", name_buffer,
- ds->ds[index].name);
+ snprintf(service_buffer, sizeof(service_buffer), "%s.%s", name_buffer,
+ ds->ds[index].name);
else
- ssnprintf(service_buffer, sizeof(service_buffer), "%s%s.%s",
- host->event_service_prefix, name_buffer, ds->ds[index].name);
+ snprintf(service_buffer, sizeof(service_buffer), "%s%s.%s",
+ host->event_service_prefix, name_buffer, ds->ds[index].name);
} else {
if (host->event_service_prefix == NULL)
sstrncpy(service_buffer, name_buffer, sizeof(service_buffer));
else
- ssnprintf(service_buffer, sizeof(service_buffer), "%s%s",
- host->event_service_prefix, name_buffer);
+ snprintf(service_buffer, sizeof(service_buffer), "%s%s",
+ host->event_service_prefix, name_buffer);
}
// Replace collectd sensor name reserved characters so that time series DB is
return -1;
}
- ssnprintf(callback_name, sizeof(callback_name), "write_sensu/%s", host->name);
+ snprintf(callback_name, sizeof(callback_name), "write_sensu/%s", host->name);
user_data_t ud = {.data = host, .free_func = sensu_free};
void module_register(void) {
plugin_register_complex_config("write_sensu", sensu_config);
}
-
-/* vim: set sw=8 sts=8 ts=8 noet : */
#include "common.h"
#include "plugin.h"
-
#include "utils_cache.h"
+#include "utils_random.h"
#include <netdb.h>
* Private variables
*/
struct wt_callback {
+ struct addrinfo *ai;
+ cdtime_t ai_last_update;
int sock_fd;
char *node;
cdtime_t send_buf_init_time;
pthread_mutex_t send_lock;
+
+ _Bool connect_failed_log_enabled;
+ int connect_dns_failed_attempts_remaining;
+ cdtime_t next_random_ttl;
};
+static cdtime_t resolve_interval = 0;
+static cdtime_t resolve_jitter = 0;
+
/*
* Functions
*/
ssize_t status = 0;
status = swrite(cb->sock_fd, cb->send_buf, strlen(cb->send_buf));
- if (status < 0) {
+ if (status != 0) {
char errbuf[1024];
ERROR("write_tsdb plugin: send failed with status %zi (%s)", status,
sstrerror(errno, errbuf, sizeof(errbuf)));
return status;
}
+static cdtime_t new_random_ttl() {
+ if (resolve_jitter == 0)
+ return 0;
+
+ return (cdtime_t)cdrand_range(0, (long)resolve_jitter);
+}
+
static int wt_callback_init(struct wt_callback *cb) {
- struct addrinfo *ai_list;
int status;
+ cdtime_t now;
const char *node = cb->node ? cb->node : WT_DEFAULT_NODE;
const char *service = cb->service ? cb->service : WT_DEFAULT_SERVICE;
if (cb->sock_fd > 0)
return 0;
- struct addrinfo ai_hints = {.ai_family = AF_UNSPEC,
- .ai_flags = AI_ADDRCONFIG,
- .ai_socktype = SOCK_STREAM};
+ now = cdtime();
+ if (cb->ai) {
+ /* When we are here, we still have the IP in cache.
+ * If we have remaining attempts without calling the DNS, we update the
+ * last_update date so we keep the info until next time.
+ * If there is no more attempts, we need to flush the cache.
+ */
+
+ if ((cb->ai_last_update + resolve_interval + cb->next_random_ttl) < now) {
+ cb->next_random_ttl = new_random_ttl();
+ if (cb->connect_dns_failed_attempts_remaining > 0) {
+ /* Warning : this is run under send_lock mutex.
+ * This is why we do not use another mutex here.
+ * */
+ cb->ai_last_update = now;
+ cb->connect_dns_failed_attempts_remaining--;
+ } else {
+ freeaddrinfo(cb->ai);
+ cb->ai = NULL;
+ }
+ }
+ }
- status = getaddrinfo(node, service, &ai_hints, &ai_list);
- if (status != 0) {
- ERROR("write_tsdb plugin: getaddrinfo (%s, %s) failed: %s", node, service,
- gai_strerror(status));
- return -1;
+ if (cb->ai == NULL) {
+ if ((cb->ai_last_update + resolve_interval + cb->next_random_ttl) >= now) {
+ DEBUG("write_tsdb plugin: too many getaddrinfo(%s, %s) failures", node,
+ service);
+ return -1;
+ }
+ cb->ai_last_update = now;
+ cb->next_random_ttl = new_random_ttl();
+
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_socktype = SOCK_STREAM,
+ };
+
+ status = getaddrinfo(node, service, &ai_hints, &cb->ai);
+ if (status != 0) {
+ if (cb->ai) {
+ freeaddrinfo(cb->ai);
+ cb->ai = NULL;
+ }
+ if (cb->connect_failed_log_enabled) {
+ ERROR("write_tsdb plugin: getaddrinfo(%s, %s) failed: %s", node,
+ service, gai_strerror(status));
+ cb->connect_failed_log_enabled = 0;
+ }
+ return -1;
+ }
}
- assert(ai_list != NULL);
- for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL;
- ai_ptr = ai_ptr->ai_next) {
- cb->sock_fd =
- socket(ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
+ assert(cb->ai != NULL);
+ for (struct addrinfo *ai = cb->ai; ai != NULL; ai = ai->ai_next) {
+ cb->sock_fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (cb->sock_fd < 0)
continue;
set_sock_opts(cb->sock_fd);
- status = connect(cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
+ status = connect(cb->sock_fd, ai->ai_addr, ai->ai_addrlen);
if (status != 0) {
close(cb->sock_fd);
cb->sock_fd = -1;
break;
}
- freeaddrinfo(ai_list);
-
if (cb->sock_fd < 0) {
char errbuf[1024];
ERROR("write_tsdb plugin: Connecting to %s:%s failed. "
return -1;
}
+ if (0 == cb->connect_failed_log_enabled) {
+ WARNING("write_tsdb plugin: Connecting to %s:%s succeeded.", node, service);
+ cb->connect_failed_log_enabled = 1;
+ }
+ cb->connect_dns_failed_attempts_remaining = 1;
+
wt_reset_buffer(cb);
return 0;
#define BUFFER_ADD(...) \
do { \
- status = ssnprintf(ret + offset, ret_len - offset, __VA_ARGS__); \
+ status = snprintf(ret + offset, ret_len - offset, __VA_ARGS__); \
if (status < 1) { \
sfree(rates); \
return -1; \
if (ds_name != NULL) {
if (vl->plugin_instance[0] == '\0') {
if (vl->type_instance[0] == '\0') {
- ssnprintf(ret, ret_len, "%s%s.%s.%s", prefix, vl->plugin, vl->type,
- ds_name);
+ snprintf(ret, ret_len, "%s%s.%s.%s", prefix, vl->plugin, vl->type,
+ ds_name);
} else {
- ssnprintf(ret, ret_len, "%s%s.%s.%s.%s", prefix, vl->plugin, vl->type,
- vl->type_instance, ds_name);
+ snprintf(ret, ret_len, "%s%s.%s.%s.%s", prefix, vl->plugin, vl->type,
+ vl->type_instance, ds_name);
}
} else { /* vl->plugin_instance != "" */
if (vl->type_instance[0] == '\0') {
- ssnprintf(ret, ret_len, "%s%s.%s.%s.%s", prefix, vl->plugin,
- vl->plugin_instance, vl->type, ds_name);
+ snprintf(ret, ret_len, "%s%s.%s.%s.%s", prefix, vl->plugin,
+ vl->plugin_instance, vl->type, ds_name);
} else {
- ssnprintf(ret, ret_len, "%s%s.%s.%s.%s.%s", prefix, vl->plugin,
- vl->plugin_instance, vl->type, vl->type_instance, ds_name);
+ snprintf(ret, ret_len, "%s%s.%s.%s.%s.%s", prefix, vl->plugin,
+ vl->plugin_instance, vl->type, vl->type_instance, ds_name);
}
}
} else { /* ds_name == NULL */
if (vl->plugin_instance[0] == '\0') {
if (vl->type_instance[0] == '\0') {
- ssnprintf(ret, ret_len, "%s%s.%s", prefix, vl->plugin, vl->type);
+ snprintf(ret, ret_len, "%s%s.%s", prefix, vl->plugin, vl->type);
} else {
- ssnprintf(ret, ret_len, "%s%s.%s.%s", prefix, vl->plugin,
- vl->type_instance, vl->type);
+ snprintf(ret, ret_len, "%s%s.%s.%s", prefix, vl->plugin,
+ vl->type_instance, vl->type);
}
} else { /* vl->plugin_instance != "" */
if (vl->type_instance[0] == '\0') {
- ssnprintf(ret, ret_len, "%s%s.%s.%s", prefix, vl->plugin,
- vl->plugin_instance, vl->type);
+ snprintf(ret, ret_len, "%s%s.%s.%s", prefix, vl->plugin,
+ vl->plugin_instance, vl->type);
} else {
- ssnprintf(ret, ret_len, "%s%s.%s.%s.%s", prefix, vl->plugin,
- vl->plugin_instance, vl->type, vl->type_instance);
+ snprintf(ret, ret_len, "%s%s.%s.%s.%s", prefix, vl->plugin,
+ vl->plugin_instance, vl->type, vl->type_instance);
}
}
}
}
status =
- ssnprintf(message, sizeof(message), "put %s %.0f %s fqdn=%s %s %s\r\n",
- key, CDTIME_T_TO_DOUBLE(time), value, host, tags, host_tags);
+ snprintf(message, sizeof(message), "put %s %.0f %s fqdn=%s %s %s\r\n",
+ key, CDTIME_T_TO_DOUBLE(time), value, host, tags, host_tags);
sfree(temp);
if (status < 0)
return -1;
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);
}
}
- ssnprintf(callback_name, sizeof(callback_name), "write_tsdb/%s/%s",
- cb->node != NULL ? cb->node : WT_DEFAULT_NODE,
- cb->service != NULL ? cb->service : WT_DEFAULT_SERVICE);
+ snprintf(callback_name, sizeof(callback_name), "write_tsdb/%s/%s",
+ cb->node != NULL ? cb->node : WT_DEFAULT_NODE,
+ cb->service != NULL ? cb->service : WT_DEFAULT_SERVICE);
user_data_t user_data = {.data = cb, .free_func = wt_callback_free};
}
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.",
void module_register(void) {
plugin_register_complex_config("write_tsdb", wt_config);
}
-
-/* vim: set sw=4 ts=4 sts=4 tw=78 et : */
xc_handle = xc_interface_open(XC_INTERFACE_INIT_ARGS);
if (!xc_handle) {
ERROR("xencpu: xc_interface_open() failed");
- return (-1);
+ return -1;
}
xc_physinfo_t *physinfo;
if (physinfo == NULL) {
ERROR("xencpu plugin: calloc() for physinfo failed.");
xc_interface_close(xc_handle);
- return (ENOMEM);
+ return ENOMEM;
}
if (xc_physinfo(xc_handle, physinfo) < 0) {
ERROR("xencpu plugin: xc_physinfo() failed");
xc_interface_close(xc_handle);
free(physinfo);
- return (-1);
+ return -1;
}
num_cpus = physinfo->nr_cpus;
if (cpu_info == NULL) {
ERROR("xencpu plugin: calloc() for num_cpus failed.");
xc_interface_close(xc_handle);
- return (ENOMEM);
+ return ENOMEM;
}
cpu_states = calloc(num_cpus, sizeof(value_to_rate_state_t));
ERROR("xencpu plugin: calloc() for cpu_states failed.");
xc_interface_close(xc_handle);
free(cpu_info);
- return (ENOMEM);
+ return ENOMEM;
}
- return (0);
+ return 0;
} /* static int xencpu_init */
static int xencpu_shutdown(void) {
sstrncpy(vl.type_instance, "load", sizeof(vl.type_instance));
if (cpu_num >= 0) {
- ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", cpu_num);
+ snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", cpu_num);
}
plugin_dispatch_values(&vl);
} /* static void submit_value */
if (rc < 0) {
ERROR("xencpu: xc_getcpuinfo() Failed: %d %s\n", rc,
xc_strerror(xc_handle, errno));
- return (-1);
+ return -1;
}
int status;
}
}
- return (0);
+ return 0;
} /* static int xencpu_read */
void module_register(void) {
gint nch;
if (!xmms_remote_is_running(xmms_session))
- return (0);
+ return 0;
xmms_remote_get_info(xmms_session, &rate, &freq, &nch);
if ((freq == 0) || (nch == 0))
- return (-1);
+ return -1;
cxmms_submit("bitrate", rate);
cxmms_submit("frequency", freq);
- return (0);
+ return 0;
} /* int read */
void module_register(void) {
plugin_register_read("xmms", cxmms_read);
} /* void module_register */
-
-/*
- * vim: shiftwidth=2:softtabstop=2:textwidth=78
- */
/*
* Global variables
*/
+static value_to_rate_state_t arc_hits_state;
+static value_to_rate_state_t arc_misses_state;
+static value_to_rate_state_t l2_hits_state;
+static value_to_rate_state_t l2_misses_state;
#if defined(KERNEL_LINUX)
#include "utils_llist.h"
e = llist_search(ksp, key);
if (e == NULL) {
- ERROR("zfs_arc plugin: `llist_search` failed for key: '%s'.", key);
- return (-1);
+ return -1;
}
v = e->value;
- return ((long long)v->derive);
+ return (long long)v->derive;
}
static void free_zfs_values(kstat_t *ksp) {
static long long get_zfs_value(kstat_t *ksp, char *name) {
- return (get_kstat_value(ksp, name));
+ return get_kstat_value(ksp, name);
}
#elif defined(KERNEL_FREEBSD)
#include <sys/sysctl.h>
size_t valuelen = sizeof(value);
int rv;
- ssnprintf(buffer, sizeof(buffer), "%s%s", zfs_arcstat, name);
+ snprintf(buffer, sizeof(buffer), "%s%s", zfs_arcstat, name);
rv = sysctlbyname(buffer, (void *)&value, &valuelen,
/* new value = */ NULL, /* new length = */ (size_t)0);
if (rv == 0)
- return (value);
+ return value;
- return (-1);
+ return -1;
}
#endif
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);
- return (-1);
+ DEBUG("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value);
+ return -1;
}
za_submit(type, type_instance, &(value_t){.derive = (derive_t)tmp},
/* values_num = */ 1);
- return (0);
+ return 0;
}
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);
- return (-1);
+ DEBUG("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value);
+ return -1;
}
za_submit(type, type_instance, &(value_t){.gauge = (gauge_t)tmp},
/* values_num = */ 1);
- return (0);
+ return 0;
}
static void za_submit_ratio(const char *type_instance, gauge_t hits,
char errbuf[1024];
ERROR("zfs_arc plugin: Opening \"%s\" failed: %s", ZOL_ARCSTATS_FILE,
sstrerror(errno, errbuf, sizeof(errbuf)));
- return (-1);
+ 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) ||
+ (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;
}
ksp = llist_create();
if (ksp == NULL) {
ERROR("zfs_arc plugin: `llist_create' failed.");
fclose(fh);
- return (-1);
+ return -1;
}
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
get_kstat(&ksp, "zfs", 0, "arcstats");
if (ksp == NULL) {
ERROR("zfs_arc plugin: Cannot find zfs:0:arcstats kstat.");
- return (-1);
+ return -1;
}
#endif
za_read_derive(ksp, "mru_hits", "cache_result", "mru-hit");
za_read_derive(ksp, "mru_ghost_hits", "cache_result", "mru_ghost-hit");
+ cdtime_t now = cdtime();
+
/* Ratios */
- arc_hits = (gauge_t)get_zfs_value(ksp, "hits");
- arc_misses = (gauge_t)get_zfs_value(ksp, "misses");
- l2_hits = (gauge_t)get_zfs_value(ksp, "l2_hits");
- l2_misses = (gauge_t)get_zfs_value(ksp, "l2_misses");
+ if ((value_to_rate(&arc_hits, (value_t){.derive = get_zfs_value(ksp, "hits")},
+ DS_TYPE_DERIVE, now, &arc_hits_state) == 0) &&
+ (value_to_rate(&arc_misses,
+ (value_t){.derive = get_zfs_value(ksp, "misses")},
+ DS_TYPE_DERIVE, now, &arc_misses_state) == 0)) {
+ za_submit_ratio("arc", arc_hits, arc_misses);
+ }
- za_submit_ratio("arc", arc_hits, arc_misses);
- za_submit_ratio("L2", l2_hits, l2_misses);
+ if ((value_to_rate(&l2_hits,
+ (value_t){.derive = get_zfs_value(ksp, "l2_hits")},
+ DS_TYPE_DERIVE, now, &l2_hits_state) == 0) &&
+ (value_to_rate(&l2_misses,
+ (value_t){.derive = get_zfs_value(ksp, "l2_misses")},
+ DS_TYPE_DERIVE, now, &l2_misses_state) == 0)) {
+ za_submit_ratio("L2", l2_hits, l2_misses);
+ }
/* I/O */
value_t l2_io[] = {
free_zfs_values(ksp);
#endif
- return (0);
+ return 0;
} /* int za_read */
static int za_init(void) /* {{{ */
* went fine. */
if (kc == NULL) {
ERROR("zfs_arc plugin: kstat chain control structure not available.");
- return (-1);
+ return -1;
}
#endif
- return (0);
+ return 0;
} /* }}} int za_init */
void module_register(void) {
static int zone_compare(const void *a, const void *b) {
if (*(const zoneid_t *)a == *(const zoneid_t *)b)
- return (0);
+ return 0;
if (*(const zoneid_t *)a < *(const zoneid_t *)b)
- return (-1);
- return (1);
+ return -1;
+ return 1;
}
static int zone_read_procfile(char const *pidstr, char const *name, void *buf,
char procfile[MAX_PROCFS_PATH];
(void)snprintf(procfile, sizeof(procfile), "/proc/%s/%s", pidstr, name);
if ((fd = open(procfile, O_RDONLY)) == -1) {
- return (1);
+ return 1;
}
if (sread(fd, buf, bufsize) != 0) {
ERROR("zone plugin: Reading \"%s\" failed: %s", procfile,
sstrerror(errno, errbuf, sizeof(errbuf)));
close(fd);
- return (1);
+ return 1;
}
close(fd);
- return (0);
+ return 0;
}
static int zone_submit_value(char *zone, gauge_t value) {
sstrncpy(vl.type, "percent", sizeof(vl.type));
sstrncpy(vl.type_instance, zone, sizeof(vl.type_instance));
- return (plugin_dispatch_values(&vl));
+ return plugin_dispatch_values(&vl);
}
static zone_stats_t *zone_find_stats(c_avl_tree_t *tree, zoneid_t zoneid) {
if (c_avl_get(tree, (void **)&zoneid, (void **)&ret)) {
if (!(ret = malloc(sizeof(*ret)))) {
WARNING("zone plugin: no memory");
- return (NULL);
+ return NULL;
}
if (!(key = malloc(sizeof(*key)))) {
WARNING("zone plugin: no memory");
free(ret);
- return (NULL);
+ return NULL;
}
*key = zoneid;
if (c_avl_insert(tree, key, ret)) {
WARNING("zone plugin: error inserting into tree");
- return (NULL);
+ return NULL;
}
}
- return (ret);
+ return ret;
}
static void zone_submit_values(c_avl_tree_t *tree) {
if (!(tree = c_avl_create(zone_compare))) {
WARNING("zone plugin: Failed to create tree");
- return (NULL);
+ return NULL;
}
rewinddir(procdir);
stats->pctmem += psinfo.pr_pctmem;
}
}
- return (tree);
+ return tree;
}
static int zone_read(void) {
if ((procdir = opendir("/proc")) == NULL) {
ERROR("zone plugin: cannot open /proc directory\n");
- return (-1);
+ return -1;
}
tree = zone_scandir(procdir);
closedir(procdir);
if (tree == NULL) {
- return (-1);
+ return -1;
}
zone_submit_values(tree); /* this also frees tree */
- return (0);
+ return 0;
}
void module_register(void) {
INFO("getaddrinfo failed: %s",
(status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
: gai_strerror(status));
- return (-1);
+ return -1;
}
for (struct addrinfo *ai = ai_list; ai != NULL; ai = ai->ai_next) {
}
freeaddrinfo(ai_list);
- return (sk);
+ return sk;
} /* int zookeeper_connect */
static int zookeeper_query(char *buffer, size_t buffer_size) {
sk = zookeeper_connect();
if (sk < 0) {
ERROR("zookeeper: Could not connect to daemon");
- return (-1);
+ return -1;
}
status = (int)swrite(sk, "mntr\r\n", strlen("mntr\r\n"));
ERROR("zookeeper: write(2) failed: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
close(sk);
- return (-1);
+ return -1;
}
memset(buffer, 0, buffer_size);
ERROR("zookeeper: Error reading from socket: %s",
sstrerror(errno, errbuf, sizeof(errbuf)));
close(sk);
- return (-1);
+ return -1;
}
buffer_fill += (size_t)status;
}
close(sk);
- return (status);
+ return status;
} /* int zookeeper_query */
static int zookeeper_read(void) {
char *fields[2];
if (zookeeper_query(buf, sizeof(buf)) < 0) {
- return (-1);
+ return -1;
}
ptr = buf;
}
}
- return (0);
+ return 0;
} /* zookeeper_read */
void module_register(void) {
#!/bin/sh
-DEFAULT_VERSION="5.7.2.git"
+DEFAULT_VERSION="5.8.0.git"
if [ -d .git ]; then
VERSION="`git describe --dirty=+ --abbrev=7 2> /dev/null | grep collectd | sed -e 's/^collectd-//' -e 's/-/./g'`"