author | Marc Fournier <marc.fournier@camptocamp.com> | |
Fri, 7 Aug 2015 08:14:59 +0000 (10:14 +0200) | ||
committer | Marc Fournier <marc.fournier@camptocamp.com> | |
Fri, 7 Aug 2015 08:14:59 +0000 (10:14 +0200) |
118 files changed:
diff --git a/.gitignore b/.gitignore
index 54eaa9748ef6240a0e8cd12650275d6536892f53..cf4ad158cdf3287937d7ce6f0a5becf6f4d8d3d5 100644 (file)
--- a/.gitignore
+++ b/.gitignore
src/tests/mock/.deps/
src/tests/.dirstamp
src/tests/mock/.dirstamp
+src/test_utils_latency
+src/test_utils_mount
+src/test_utils_vl_lookup
test*.log
+*.trs
# new daemon repo
src/daemon/.deps/
src/daemon/.dirstamp
src/daemon/collectd
+src/daemon/test_common
+src/daemon/test_meta_data
+src/daemon/test_utils_avltree
+src/daemon/test_utils_heap
+src/daemon/test_utils_subst
diff --git a/.travis.yml b/.travis.yml
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,25 @@
+sudo: false
+compiler:
+ - gcc
+ - clang
+addons:
+ apt:
+ packages:
+ - iptables-dev
+ - libcap-dev
+ - libdbi-dev
+ - libhiredis-dev
+ - libnfnetlink-dev
+ - libnotify-dev
+ - libpcap-dev
+ - libperl-dev
+ - libprotobuf-c0-dev
+ - librrd-dev
+ - libsnmp-dev
+ - libudev-dev
+ - libvarnishapi-dev
+ - libyajl-dev
+ - linux-libc-dev
+ - protobuf-c-compiler
+language: c
+script: sh build.sh && ./configure && make distcheck
index 3f63c3dcd5591c72131b4bfa3dc579d9bc5e36cc..02b125688ee778587d14992e449d28bb2142515f 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
Cyril Feraudet <cyril at feraudet.com>
- ethstat plugin.
+Dagobert Michelsen <dam at opencsw.org>
+ - zone plugin.
+
Dan Berrange <berrange at redhat.com>
- uuid plugin.
- ip6tables support in the iptables plugin.
- openvpn plugin (support for more status file formats)
+Mathijs Möhlmann <collectd at mmrc.nl>
+ - zone plugin.
+
Michael Hanselmann <public at hansmi.ch>
- md plugin.
index 3e2c0233adc3ea9ccfbcbbf072c107a0f6dcbd5b..ad5b66783473bc531d9c20451c306db47b22a3e7 100644 (file)
--- a/README
+++ b/README
Reads values from Modbus/TCP enabled devices. Supports reading values
from multiple "slaves" so gateway devices can be used.
+ - mqtt
+ Publishes and subscribes to MQTT topics.
+
- multimeter
Information provided by serial multimeters, such as the `Metex
M-4650CR'.
- zfs_arc
Statistics for ZFS' “Adaptive Replacement Cache” (ARC).
+ - zone
+ Measures the percentage of cpu load per container (zone) under Solaris 10
+ and higher
+
- zookeeper
Read data from Zookeeper's MNTR command.
index 5c6a5f9d24c74179b8c2e3a878619198398bdc73..69c755b6a92996cd192b9845ea87c866dd51b741 100644 (file)
sub _escape_argument
{
- local $_ = shift;
+ my $arg = shift;
- return $_ if /^\w+$/;
+ return $arg if $arg =~ /^\w+$/;
- s#\\#\\\\#g;
- s#"#\\"#g;
- return "\"$_\"";
+ $arg =~ s#\\#\\\\#g;
+ $arg =~ s#"#\\"#g;
+ return "\"$arg\"";
}
# Send a command on a socket, including any required argument escaping.
index 2f7818b15799cb650e6d2288072286f4426ac583..4e94f8e8d235f53fa742bd716a1b738b6aade28f 100644 (file)
my ($nresults, $resultdata) = @$results;
my $r = $s->getval(%{Collectd::Unixsock::_parse_identifier($attr)});
is(ref $r, 'HASH', "Got a result for $attr");
- is(scalar keys $r, $nresults, "$nresults result result for $attr");
+ is(scalar keys %$r, $nresults, "$nresults result result for $attr");
is_deeply($r, $resultdata, "Data or $attr matches");
}
diff --git a/configure.ac b/configure.ac
index a7cddb5e7c139f433c23c4e49b0b0d269d7704e2..8129468a1f7dc538d020c3063a13a42a24350a9d 100644 (file)
--- a/configure.ac
+++ b/configure.ac
AM_CONDITIONAL(BUILD_WITH_LIBMONGOC, test "x$with_libmongoc" = "xyes")
# }}}
+# --with-libmosquitto {{{
+with_libmosquitto_cppflags=""
+with_libmosquitto_libs="-lmosquitto"
+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_libs="-L$withval/lib -lmosquitto"
+ with_libmosquitto="yes"
+ else
+ with_libmosquitto="$withval"
+ fi
+],
+[
+ with_libmosquitto="yes"
+])
+if test "x$with_libmosquitto" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$with_libmosquitto_cppflags"
+
+ AC_CHECK_HEADERS(mosquitto.h, [with_libmosquitto="yes"], [with_libmosquitto="no (mosquitto.h not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libmosquitto" = "xyes"
+then
+ SAVE_LDFLAGS="$LDFLAGS"
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ LDFLAGS="$with_libmosquitto_libs"
+ CPPFLAGS="$with_libmosquitto_cppflags"
+
+ AC_CHECK_LIB(mosquitto, mosquitto_connect, [with_libmosquitto="yes"], [with_libmosquitto="no (libmosquitto not found)"])
+
+ LDFLAGS="$SAVE_LDFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libmosquitto" = "xyes"
+then
+ BUILD_WITH_LIBMOSQUITTO_CPPFLAGS="$with_libmosquitto_cppflags"
+ BUILD_WITH_LIBMOSQUITTO_LIBS="$with_libmosquitto_libs"
+ AC_SUBST(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS)
+ AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LIBS)
+fi
+# }}}
+
# --with-libmysql {{{
with_mysql_config="mysql_config"
with_mysql_cflags=""
plugin_vserver="no"
plugin_wireless="no"
plugin_zfs_arc="no"
+plugin_zone="no"
plugin_zookeeper="no"
# Linux
plugin_processes="yes"
plugin_uptime="yes"
plugin_zfs_arc="yes"
+ plugin_zone="yes"
fi
if test "x$with_devinfo$with_kstat" = "xyesyes"
AC_PLUGIN([memory], [$plugin_memory], [Memory usage])
AC_PLUGIN([mic], [$with_mic], [Intel Many Integrated Core stats])
AC_PLUGIN([modbus], [$with_libmodbus], [Modbus plugin])
+AC_PLUGIN([mqtt], [$with_libmosquitto], [MQTT output plugin])
AC_PLUGIN([multimeter], [$plugin_multimeter], [Read multimeter values])
AC_PLUGIN([mysql], [$with_libmysql], [MySQL statistics])
AC_PLUGIN([netapp], [$with_libnetapp], [NetApp plugin])
AC_PLUGIN([write_tsdb], [yes], [TSDB output plugin])
AC_PLUGIN([xmms], [$with_libxmms], [XMMS statistics])
AC_PLUGIN([zfs_arc], [$plugin_zfs_arc], [ZFS ARC statistics])
+AC_PLUGIN([zone], [$plugin_zone], [Solaris container statistics])
AC_PLUGIN([zookeeper], [yes], [Zookeeper statistics])
dnl Default configuration file
libmnl . . . . . . . $with_libmnl
libmodbus . . . . . . $with_libmodbus
libmongoc . . . . . . $with_libmongoc
+ libmosquitto . . . . $with_libmosquitto
libmysql . . . . . . $with_libmysql
libnetapp . . . . . . $with_libnetapp
libnetsnmp . . . . . $with_libnetsnmp
memory . . . . . . . $enable_memory
mic . . . . . . . . . $enable_mic
modbus . . . . . . . $enable_modbus
+ mqtt . . . . . . . . $enable_mqtt
multimeter . . . . . $enable_multimeter
mysql . . . . . . . . $enable_mysql
netapp . . . . . . . $enable_netapp
write_tsdb . . . . . $enable_write_tsdb
xmms . . . . . . . . $enable_xmms
zfs_arc . . . . . . . $enable_zfs_arc
+ zone . . . . . . . . $enable_zone
zookeeper . . . . . . $enable_zookeeper
EOF
diff --git a/contrib/README b/contrib/README
index 1ebf1f146e6332ce88f90b894ec233bbbc196946..897d61978c32532c535d635cf96c1bdac781007e 100644 (file)
--- a/contrib/README
+++ b/contrib/README
RRD-file that should have been in multiple RRD-files instead. Is is used by
`migrate-3-4.px' to split up the cpu-, nfs-, swap-files and possibly others.
-fedora/
--------
- Init-script and Spec-file that can be used when creating RPM-packages for
-Fedora.
-
GenericJMX.conf
---------------
Example configuration file for the ‘GenericJMX’ Java plugin. Please read the
diff --git a/contrib/collectd.service b/contrib/collectd.service
--- a/contrib/collectd.service
+++ /dev/null
@@ -1,15 +0,0 @@
-[Unit]
-Description=statistics collection daemon
-Documentation=man:collectd(1)
-After=local-fs.target network.target
-Requires=local-fs.target network.target
-
-[Service]
-ExecStart=/usr/sbin/collectd -C /etc/collectd/collectd.conf -f
-Restart=always
-RestartSec=10
-StandardOutput=syslog
-StandardError=syslog
-
-[Install]
-WantedBy=multi-user.target
diff --git a/contrib/fedora/collectd.spec b/contrib/fedora/collectd.spec
+++ /dev/null
@@ -1,376 +0,0 @@
-Summary: Statistics collection daemon for filling RRD files.
-Name: collectd
-Version: 4.2.0
-Release: 1.fc6
-Source: http://collectd.org/files/%{name}-%{version}.tar.gz
-License: GPL
-Group: System Environment/Daemons
-BuildRoot: %{_tmppath}/%{name}-%{version}-root
-BuildPrereq: lm_sensors-devel
-BuildPrereq: mysql-devel
-BuildPrereq: rrdtool-devel
-BuildPrereq: net-snmp-devel
-Requires: rrdtool
-Requires: perl-Regexp-Common
-Packager: Florian octo Forster <octo@verplant.org>
-Vendor: Florian octo Forster <octo@verplant.org>
-
-%description
-collectd is a small daemon written in C for performance. It reads various
-system statistics and updates RRD files, creating them if neccessary.
-Since the daemon doesn't need to startup every time it wants to update the
-files it's very fast and easy on the system. Also, the statistics are very
-fine grained since the files are updated every 10 seconds.
-
-%package apache
-Summary: apache-plugin for collectd.
-Group: System Environment/Daemons
-Requires: collectd = %{version}, curl
-%description apache
-This plugin collectd data provided by Apache's `mod_status'.
-
-%package email
-Summary: email-plugin for collectd.
-Group: System Environment/Daemons
-Requires: collectd = %{version}, spamassassin
-%description email
-This plugin collectd data provided by spamassassin.
-
-%package mysql
-Summary: mysql-module for collectd.
-Group: System Environment/Daemons
-Requires: collectd = %{version}, mysql
-%description mysql
-MySQL querying plugin. This plugins provides data of issued commands,
-called handlers and database traffic.
-
-%package sensors
-Summary: libsensors-module for collectd.
-Group: System Environment/Daemons
-Requires: collectd = %{version}, lm_sensors
-%description sensors
-This plugin for collectd provides querying of sensors supported by
-lm_sensors.
-
-%prep
-rm -rf $RPM_BUILD_ROOT
-%setup
-
-%build
-./configure --prefix=%{_prefix} --sbindir=%{_sbindir} --mandir=%{_mandir} --libdir=%{_libdir} --sysconfdir=%{_sysconfdir}
-make
-
-%install
-make install DESTDIR=$RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d
-mkdir -p $RPM_BUILD_ROOT/var/www/cgi-bin
-cp src/collectd.conf $RPM_BUILD_ROOT/etc/collectd.conf
-cp contrib/fedora/init.d-collectd $RPM_BUILD_ROOT/etc/rc.d/init.d/collectd
-cp contrib/collection.cgi $RPM_BUILD_ROOT/var/www/cgi-bin
-cp contrib/collection.conf $RPM_BUILD_ROOT/etc/collection.conf
-mkdir -p $RPM_BUILD_ROOT/var/lib/collectd
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%post
-/sbin/chkconfig --add collectd
-/sbin/chkconfig collectd on
-
-%preun
-if [ "$1" = 0 ]; then
- /sbin/chkconfig collectd off
- /etc/init.d/collectd stop
- /sbin/chkconfig --del collectd
-fi
-exit 0
-
-%postun
-if [ "$1" -ge 1 ]; then
- /etc/init.d/collectd restart
-fi
-exit 0
-
-%files
-%defattr(-,root,root)
-%doc AUTHORS COPYING ChangeLog INSTALL NEWS README
-%attr(0644,root,root) %config(noreplace) /etc/collectd.conf
-%attr(0644,root,root) %config(noreplace) /etc/collection.conf
-%attr(0755,root,root) /etc/rc.d/init.d/collectd
-%attr(0755,root,root) /var/www/cgi-bin/collection.cgi
-%attr(0755,root,root) %{_sbindir}/collectd
-%attr(0755,root,root) %{_bindir}/collectd-nagios
-%attr(0644,root,root) %{_mandir}/man1/*
-%attr(0644,root,root) %{_mandir}/man5/*
-
-%attr(0644,root,root) /usr/lib/perl5/5.8.8/i386-linux-thread-multi/perllocal.pod
-%attr(0644,root,root) /usr/lib/perl5/site_perl/5.8.8/Collectd.pm
-%attr(0644,root,root) /usr/lib/perl5/site_perl/5.8.8/Collectd/Unixsock.pm
-%attr(0644,root,root) /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/Collectd/.packlist
-%attr(0644,root,root) %{_mandir}/man3/Collectd::Unixsock.3pm.gz
-
-%attr(0644,root,root) %{_libdir}/%{name}/apcups.so*
-%attr(0644,root,root) %{_libdir}/%{name}/apcups.la
-
-# FIXME!!!
-#%attr(0644,root,root) %{_libdir}/%{name}/apple_sensors.so*
-#%attr(0644,root,root) %{_libdir}/%{name}/apple_sensors.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/battery.so*
-%attr(0644,root,root) %{_libdir}/%{name}/battery.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/conntrack.so*
-%attr(0644,root,root) %{_libdir}/%{name}/conntrack.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/cpufreq.so*
-%attr(0644,root,root) %{_libdir}/%{name}/cpufreq.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/cpu.so*
-%attr(0644,root,root) %{_libdir}/%{name}/cpu.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/csv.so*
-%attr(0644,root,root) %{_libdir}/%{name}/csv.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/df.so*
-%attr(0644,root,root) %{_libdir}/%{name}/df.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/disk.so*
-%attr(0644,root,root) %{_libdir}/%{name}/disk.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/dns.so*
-%attr(0644,root,root) %{_libdir}/%{name}/dns.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/entropy.so*
-%attr(0644,root,root) %{_libdir}/%{name}/entropy.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/exec.so*
-%attr(0644,root,root) %{_libdir}/%{name}/exec.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/hddtemp.so*
-%attr(0644,root,root) %{_libdir}/%{name}/hddtemp.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/interface.so*
-%attr(0644,root,root) %{_libdir}/%{name}/interface.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/iptables.so*
-%attr(0644,root,root) %{_libdir}/%{name}/iptables.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/irq.so*
-%attr(0644,root,root) %{_libdir}/%{name}/irq.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/load.so*
-%attr(0644,root,root) %{_libdir}/%{name}/load.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/logfile.so*
-%attr(0644,root,root) %{_libdir}/%{name}/logfile.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/mbmon.so*
-%attr(0644,root,root) %{_libdir}/%{name}/mbmon.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/memcached.so*
-%attr(0644,root,root) %{_libdir}/%{name}/memcached.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/memory.so*
-%attr(0644,root,root) %{_libdir}/%{name}/memory.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/multimeter.so*
-%attr(0644,root,root) %{_libdir}/%{name}/multimeter.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/network.so*
-%attr(0644,root,root) %{_libdir}/%{name}/network.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/nfs.so*
-%attr(0644,root,root) %{_libdir}/%{name}/nfs.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/nginx.so*
-%attr(0644,root,root) %{_libdir}/%{name}/nginx.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/ntpd.so*
-%attr(0644,root,root) %{_libdir}/%{name}/ntpd.la
-
-# FIXME!!!
-#%attr(0644,root,root) %{_libdir}/%{name}/nut.so*
-#%attr(0644,root,root) %{_libdir}/%{name}/nut.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/perl.so*
-%attr(0644,root,root) %{_libdir}/%{name}/perl.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/ping.so*
-%attr(0644,root,root) %{_libdir}/%{name}/ping.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/processes.so*
-%attr(0644,root,root) %{_libdir}/%{name}/processes.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/rrdtool.so*
-%attr(0644,root,root) %{_libdir}/%{name}/rrdtool.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/serial.so*
-%attr(0644,root,root) %{_libdir}/%{name}/serial.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/swap.so*
-%attr(0644,root,root) %{_libdir}/%{name}/swap.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/snmp.so*
-%attr(0644,root,root) %{_libdir}/%{name}/snmp.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/syslog.so*
-%attr(0644,root,root) %{_libdir}/%{name}/syslog.la
-
-# FIXME!!!
-#%attr(0644,root,root) %{_libdir}/%{name}/tape.so*
-#%attr(0644,root,root) %{_libdir}/%{name}/tape.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/tcpconns.so*
-%attr(0644,root,root) %{_libdir}/%{name}/tcpconns.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/unixsock.so*
-%attr(0644,root,root) %{_libdir}/%{name}/unixsock.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/users.so*
-%attr(0644,root,root) %{_libdir}/%{name}/users.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/vserver.so*
-%attr(0644,root,root) %{_libdir}/%{name}/vserver.la
-
-%attr(0644,root,root) %{_libdir}/%{name}/wireless.so*
-%attr(0644,root,root) %{_libdir}/%{name}/wireless.la
-
-%attr(0644,root,root) %{_datadir}/%{name}/types.db
-
-%dir /var/lib/collectd
-
-%files apache
-%attr(0644,root,root) %{_libdir}/%{name}/apache.so*
-%attr(0644,root,root) %{_libdir}/%{name}/apache.la
-
-%files email
-%attr(0644,root,root) %{_libdir}/%{name}/email.so*
-%attr(0644,root,root) %{_libdir}/%{name}/email.la
-
-%files mysql
-%attr(0644,root,root) %{_libdir}/%{name}/mysql.so*
-%attr(0644,root,root) %{_libdir}/%{name}/mysql.la
-
-%files sensors
-%attr(0644,root,root) %{_libdir}/%{name}/sensors.so*
-%attr(0644,root,root) %{_libdir}/%{name}/sensors.la
-
-%changelog
-* Wed Oct 31 2007 Iain Lea <iain@bricbrac.de> 4.2.0
-- New major release
-- Changes to support 4.2.0 (ie. contrib/collection.conf)
-
-* Mon Aug 06 2007 Kjell Randa <Kjell.Randa@broadpark.no> 4.0.6
-- New upstream version
-
-* Wed Jul 25 2007 Kjell Randa <Kjell.Randa@broadpark.no> 4.0.5
-- New major release
-- Changes to support 4.0.5
-
-* Wed Jan 11 2007 Iain Lea <iain@bricbrac.de> 3.11.0-0
-- fixed spec file to build correctly on fedora core
-- added improved init.d script to work with chkconfig
-- added %post and %postun to call chkconfig automatically
-
-* Sun Jul 09 2006 Florian octo Forster <octo@verplant.org> 3.10.0-1
-- New upstream version
-
-* Tue Jun 25 2006 Florian octo Forster <octo@verplant.org> 3.9.4-1
-- New upstream version
-
-* Tue Jun 01 2006 Florian octo Forster <octo@verplant.org> 3.9.3-1
-- New upstream version
-
-* Tue May 09 2006 Florian octo Forster <octo@verplant.org> 3.9.2-1
-- New upstream version
-
-* Tue May 09 2006 Florian octo Forster <octo@verplant.org> 3.8.5-1
-- New upstream version
-
-* Fri Apr 21 2006 Florian octo Forster <octo@verplant.org> 3.9.1-1
-- New upstream version
-
-* Fri Apr 14 2006 Florian octo Forster <octo@verplant.org> 3.9.0-1
-- New upstream version
-- Added the `apache' package.
-
-* Thu Mar 14 2006 Florian octo Forster <octo@verplant.org> 3.8.2-1
-- New upstream version
-
-* Thu Mar 13 2006 Florian octo Forster <octo@verplant.org> 3.8.1-1
-- New upstream version
-
-* Thu Mar 09 2006 Florian octo Forster <octo@verplant.org> 3.8.0-1
-- New upstream version
-
-* Sat Feb 18 2006 Florian octo Forster <octo@verplant.org> 3.7.2-1
-- Include `tape.so' so the build doesn't terminate because of missing files..
-- New upstream version
-
-* Sat Feb 04 2006 Florian octo Forster <octo@verplant.org> 3.7.1-1
-- New upstream version
-
-* Mon Jan 30 2006 Florian octo Forster <octo@verplant.org> 3.7.0-1
-- New upstream version
-- Removed the extra `hddtemp' package
-
-* Tue Jan 24 2006 Florian octo Forster <octo@verplant.org> 3.6.2-1
-- New upstream version
-
-* Fri Jan 20 2006 Florian octo Forster <octo@verplant.org> 3.6.1-1
-- New upstream version
-
-* Fri Jan 20 2006 Florian octo Forster <octo@verplant.org> 3.6.0-1
-- New upstream version
-- Added config file, `collectd.conf(5)', `df.so'
-- Added package `collectd-mysql', dependency on `mysqlclient10 | mysql'
-
-* Wed Dec 07 2005 Florian octo Forster <octo@verplant.org> 3.5.0-1
-- New upstream version
-
-* Sat Nov 26 2005 Florian octo Forster <octo@verplant.org> 3.4.0-1
-- New upstream version
-
-* Sat Nov 05 2005 Florian octo Forster <octo@verplant.org> 3.3.0-1
-- New upstream version
-
-* Tue Oct 26 2005 Florian octo Forster <octo@verplant.org> 3.2.0-1
-- New upstream version
-- Added statement to remove the `*.la' files. This fixes a problem when
- `Unpackaged files terminate build' is in effect.
-- Added `processes.so*' to the main package
-
-* Fri Oct 14 2005 Florian octo Forster <octo@verplant.org> 3.1.0-1
-- New upstream version
-- Added package `collectd-hddtemp'
-
-* Fri Sep 30 2005 Florian octo Forster <octo@verplant.org> 3.0.0-1
-- New upstream version
-- Split the package into `collectd' and `collectd-sensors'
-
-* Fri Sep 16 2005 Florian octo Forster <octo@verplant.org> 2.1.0-1
-- New upstream version
-
-* Mon Sep 10 2005 Florian octo Forster <octo@verplant.org> 2.0.0-1
-- New upstream version
-
-* Mon Aug 29 2005 Florian octo Forster <octo@verplant.org> 1.8.0-1
-- New upstream version
-
-* Sun Aug 25 2005 Florian octo Forster <octo@verplant.org> 1.7.0-1
-- New upstream version
-
-* Sun Aug 21 2005 Florian octo Forster <octo@verplant.org> 1.6.0-1
-- New upstream version
-
-* Sun Jul 17 2005 Florian octo Forster <octo@verplant.org> 1.5.1-1
-- New upstream version
-
-* Sun Jul 17 2005 Florian octo Forster <octo@verplant.org> 1.5-1
-- New upstream version
-
-* Mon Jul 11 2005 Florian octo Forster <octo@verplant.org> 1.4.2-1
-- New upstream version
-
-* Sat Jul 09 2005 Florian octo Forster <octo@verplant.org> 1.4-1
-- Built on RedHat 7.3
diff --git a/contrib/fedora/init.d-collectd b/contrib/fedora/init.d-collectd
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/bash
-#
-# collectd Startup script for the Collectd statistics gathering daemon
-# chkconfig: - 86 15
-# description: Collectd is a statistics gathering daemon used to collect \
-# system information ie. cpu, memory, disk, network
-# processname: collectd
-# config: /etc/collectd.conf
-# config: /etc/sysconfig/collectd
-# pidfile: /var/run/collectd.pid
-
-# Source function library.
-. /etc/init.d/functions
-
-RETVAL=0
-ARGS=""
-prog="collectd"
-CONFIG=/etc/collectd.conf
-
-if [ -r /etc/default/$prog ]; then
- . /etc/default/$prog
-fi
-
-start () {
- echo -n $"Starting $prog: "
- if [ -r "$CONFIG" ]
- then
- daemon /usr/sbin/collectd -C "$CONFIG"
- RETVAL=$?
- echo
- [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
- fi
-}
-stop () {
- echo -n $"Stopping $prog: "
- killproc $prog
- RETVAL=$?
- echo
- [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
-}
-# See how we were called.
-case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- status)
- status $prog
- ;;
- restart|reload)
- stop
- start
- ;;
- condrestart)
- [ -f /var/lock/subsys/$prog ] && stop && start || :
- ;;
- *)
- echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}"
- exit 1
-esac
-
-exit $?
-
-# vim:syntax=sh
index 9d491ff818e88986ca67046607636839019d22d1..2252181335cff9c2e116cc962b0836c6b61d1e22 100644 (file)
%{?el7:%global _has_atasmart 1}
%{?el7:%global _has_hiredis 1}
%{?el7:%global _has_asm_msr_index 1}
+%{?el7:%global _has_libmosquitto 1}
# plugins enabled by default
%define with_aggregation 0%{!?_without_aggregation:1}
%define with_memory 0%{!?_without_memory:1}
%define with_multimeter 0%{!?_without_multimeter:1}
%define with_modbus 0%{!?_without_modbus:0%{?_has_libmodbus}}
+%define with_mqtt 0%{!?_without_mqtt:0%{?_has_libmosquitto}}
%define with_mysql 0%{!?_without_mysql:1}
%define with_netlink 0%{!?_without_netlink:0%{?_has_iproute}}
%define with_network 0%{!?_without_network:1}
%define with_write_mongodb 0%{!?_without_write_mongodb:0}
# plugin xmms disabled, requires xmms
%define with_xmms 0%{!?_without_xmms:0}
+# plugin zone disabled, requires Solaris
+%define with_zone 0%{!?_without_zone:0}
Summary: statistics collection and monitoring daemon
Name: collectd
handlers and database traffic.
%endif
+%if %{with_mqtt}
+%package mqtt
+Summary: mqtt plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: mosquitto-devel
+%description mqtt
+The MQTT plugin publishes and subscribes to MQTT topics.
+%endif
+
%if %{with_netlink}
%package netlink
Summary: netlink plugin for collectd
%define _with_multimeter --disable-multimeter
%endif
+%if %{with_mqtt}
+%define _with_mqtt --enable-mqtt
+%else
+%define _with_mqtt --disable-mqtt
+%endif
+
%if %{with_mysql}
%define _with_mysql --enable-mysql
%else
%define _with_zfs_arc --disable-zfs_arc
%endif
+%if %{with_zone}
+%define _with_zone --enable-zone
+%else
+%define _with_zone --disable-zone
+%endif
+
%if %{with_zookeeper}
%define _with_zookeeper --enable-zookeeper
%else
%{?_with_mic} \
%{?_with_modbus} \
%{?_with_multimeter} \
+ %{?_with_mqtt} \
%{?_with_mysql} \
%{?_with_netapp} \
%{?_with_netlink} \
%{?_with_write_redis} \
%{?_with_xmms} \
%{?_with_zfs_arc} \
+ %{?_with_zone} \
%{?_with_zookeeper} \
%{?_with_irq} \
%{?_with_load} \
%{_libdir}/%{name}/modbus.so
%endif
+%if %{with_mqtt}
+%files mqtt
+%{_libdir}/%{name}/mqtt.so
+%endif
+
%if %{with_mysql}
%files mysql
%{_libdir}/%{name}/mysql.so
%doc contrib/
%changelog
+#* TODO: next feature release changelog
+#- New upstream version
+#- New plugins enabled by default: mqtt
+#- New plugins disabled by default: zone
+#
* Wed May 27 2015 Marc Fournier <marc.fournier@camptocamp.com> 5.5.0-1
- New upstream version
- New plugins enabled by default: ceph, drbd, log_logstash, write_tsdb, smart,
index b046192b9dd3ddc0fea7941ce69ea6950294ae8a..96df8a576a694670f1af076e344b0be7f1c45767 100644 (file)
[Service]
ExecStart=/usr/sbin/collectd
+EnvironmentFile=-/etc/sysconfig/collectd
+EnvironmentFile=-/etc/default/collectd
# Tell systemd it will receive a notification from collectd over it's control
# socket once the daemon is ready. See systemd.service(5) for more details.
diff --git a/src/Makefile.am b/src/Makefile.am
index 07ffdda9ce58ec20107893a4513bef2d144c2ce1..e522f21172d2f3a603b3f101f76760f07482fdde 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
AUTOMAKE_OPTIONS = subdir-objects
-noinst_LTLIBRARIES = libmount.la liblookup.la
+noinst_LTLIBRARIES =
+check_PROGRAMS =
+TESTS =
+
+noinst_LTLIBRARIES += liblatency.la
+liblatency_la_SOURCES = utils_latency.c utils_latency.h
+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/libcommon.la daemon/libplugin_mock.la -lm
+
+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/libcommon.la daemon/libplugin_mock.la
+noinst_LTLIBRARIES += libmount.la
libmount_la_SOURCES = utils_mount.c utils_mount.h
-libmount_la_LIBADD = daemon/libcommon.la
+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/libcommon.la daemon/libplugin_mock.la
-liblookup_la_SOURCES = utils_vl_lookup.c utils_vl_lookup.h
-liblookup_la_LIBADD = daemon/libavltree.la daemon/libcommon.la
sbin_PROGRAMS = collectdmon
bin_PROGRAMS = collectd-nagios collectdctl collectd-tg
collectdctl_DEPENDENCIES = libcollectdclient/libcollectdclient.la
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_CPPFLAGS = $(AM_CPPFLAGS) \
+ -I$(top_srcdir)/src/libcollectdclient/collectd -I$(top_builddir)/src/libcollectdclient/collectd
collectd_tg_LDADD = daemon/libheap.la
if BUILD_WITH_LIBSOCKET
collectd_tg_LDADD += -lsocket
ipvs_la_SOURCES = ipvs.c
if IP_VS_H_NEEDS_KERNEL_CFLAGS
ipvs_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS)
+else
+ipvs_la_CFLAGS = $(AM_CFLAGS)
endif
ipvs_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
modbus_la_LIBADD = $(BUILD_WITH_LIBMODBUS_LIBS)
endif
+if BUILD_PLUGIN_MQTT
+pkglib_LTLIBRARIES += mqtt.la
+mqtt_la_SOURCES = mqtt.c
+mqtt_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+mqtt_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS)
+mqtt_la_LIBADD = $(BUILD_WITH_LIBMOSQUITTO_LIBS)
+endif
+
if BUILD_PLUGIN_MULTIMETER
pkglib_LTLIBRARIES += multimeter.la
multimeter_la_SOURCES = multimeter.c
if BUILD_PLUGIN_STATSD
pkglib_LTLIBRARIES += statsd.la
-statsd_la_SOURCES = statsd.c \
- utils_latency.h utils_latency.c
+statsd_la_SOURCES = statsd.c
statsd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-statsd_la_LIBADD = -lpthread -lm
+statsd_la_LIBADD = liblatency.la -lpthread -lm
endif
if BUILD_PLUGIN_SWAP
BUILT_SOURCES += $(dist_man_MANS)
+if BUILD_PLUGIN_ZONE
+pkglib_LTLIBRARIES += zone.la
+zone_la_SOURCES = zone.c
+zone_la_CFLAGS = $(AM_CFLAGS)
+zone_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
dist_man_MANS = collectd.1 \
collectd.conf.5 \
collectd-email.5 \
rm -f $(DESTDIR)$(sysconfdir)/collectd.conf
rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
-check_PROGRAMS = test_utils_mount test_utils_vl_lookup
-
-test_utils_mount_SOURCES = utils_mount_test.c testing.h
-test_utils_mount_LDADD = libmount.la daemon/libplugin_mock.la
-
-test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h
-test_utils_vl_lookup_LDADD = liblookup.la daemon/libplugin_mock.la
-TESTS = test_utils_mount test_utils_vl_lookup
diff --git a/src/apache.c b/src/apache.c
index 8910675ad06a67e8f80a322ef75d991123a48b0c..e384d800acdf0758579015c5643d7d50c0920e7a 100644 (file)
--- a/src/apache.c
+++ b/src/apache.c
status = plugin_register_complex_read (/* group = */ NULL,
/* name = */ callback_name,
/* callback = */ apache_read_host,
- /* interval = */ NULL,
+ /* interval = */ 0,
/* user_data = */ &ud);
}
diff --git a/src/apcups.c b/src/apcups.c
index be7673c5df9e1854ed1c32e0a2b55f89561dac3c..718061ae36e693a9125325f3403da98f25be2316 100644 (file)
--- a/src/apcups.c
+++ b/src/apcups.c
/*
* collectd - src/apcups.c
- * Copyright (C) 2006-2012 Florian octo Forster
+ * Copyright (C) 2006-2015 Florian octo Forster
* Copyright (C) 2006 Anthony Gialluca <tonyabg at charter.net>
* Copyright (C) 2000-2004 Kern Sibbald
* Copyright (C) 1996-1999 Andre M. Hedrick <andre at suse.com>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
#if HAVE_NETDB_H
# include <netdb.h>
#endif
# include <netinet/in.h>
#endif
-#define NISPORT 3551
-#define MAXSTRING 256
-#define MODULE_NAME "apcups"
+#ifndef APCUPS_DEFAULT_NODE
+# define APCUPS_DEFAULT_NODE "localhost"
+#endif
-#define APCUPS_DEFAULT_HOST "localhost"
+#ifndef APCUPS_DEFAULT_SERVICE
+# define APCUPS_DEFAULT_SERVICE "3551"
+#endif
/*
* Private data types
* Private variables
*/
/* Default values for contacting daemon */
-static char *conf_host = NULL;
-static int conf_port = NISPORT;
+static char *conf_node = NULL;
+static char *conf_service = NULL;
/* Defaults to false for backwards compatibility. */
static _Bool conf_report_seconds = 0;
+static _Bool conf_persistent_conn = 1;
static int global_sockfd = -1;
static int count_retries = 0;
static int count_iterations = 0;
-static _Bool close_socket = 0;
-
-static const char *config_keys[] =
-{
- "Host",
- "Port",
- "ReportSeconds"
-};
-static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
static int net_shutdown (int *fd)
{
* Returns -1 on error
* Returns socket file descriptor otherwise
*/
-static int net_open (char *host, int port)
+static int net_open (char const *node, char const *service)
{
int sd;
int status;
- char port_str[8];
struct addrinfo ai_hints;
struct addrinfo *ai_return;
struct addrinfo *ai_list;
- assert ((port > 0x00000000) && (port <= 0x0000FFFF));
-
- /* Convert the port to a string */
- ssnprintf (port_str, sizeof (port_str), "%i", port);
-
/* Resolve name */
- memset ((void *) &ai_hints, '\0', sizeof (ai_hints));
- ai_hints.ai_family = AF_INET; /* XXX: Change this to `AF_UNSPEC' if apcupsd can handle IPv6 */
+ memset (&ai_hints, 0, sizeof (ai_hints));
+ /* TODO: Change this to `AF_UNSPEC' if apcupsd can handle IPv6 */
+ ai_hints.ai_family = AF_INET;
ai_hints.ai_socktype = SOCK_STREAM;
- status = getaddrinfo (host, port_str, &ai_hints, &ai_return);
+ status = getaddrinfo (node, service, &ai_hints, &ai_return);
if (status != 0)
{
char errbuf[1024];
DEBUG ("Done opening a socket %i", sd);
return (sd);
-} /* int net_open (char *host, char *service, int port) */
+} /* int net_open */
/*
* Receive a message from the other end. Each message consists of
}
/* Get and print status from apcupsd NIS server */
-static int apc_query_server (char *host, int port,
+static int apc_query_server (char const *node, char const *service,
struct apc_detail_s *apcups_detail)
{
int n;
{
if (global_sockfd < 0)
{
- global_sockfd = net_open (host, port);
+ global_sockfd = net_open (node, service);
if (global_sockfd < 0)
{
ERROR ("apcups plugin: Connecting to the "
"first %i iterations. Will close the socket "
"in future iterations.",
count_retries, count_iterations);
- close_socket = 1;
+ conf_persistent_conn = 0;
}
while ((n = net_recv (&global_sockfd, recvline, sizeof (recvline) - 1)) > 0)
{
- assert ((unsigned int)n < sizeof (recvline));
- recvline[n] = '\0';
+ assert ((size_t)n < sizeof (recvline));
+ recvline[n] = 0;
#if APCMAIN
printf ("net_recv = `%s';\n", recvline);
#endif /* if APCMAIN */
+ if (strncmp ("END APC", recvline, strlen ("END APC")) == 0)
+ break;
+
toksaveptr = NULL;
tokptr = strtok_r (recvline, " :\t", &toksaveptr);
while (tokptr != NULL)
}
status = errno; /* save errno, net_shutdown() may re-set it. */
- if (close_socket)
+ if (!conf_persistent_conn)
net_shutdown (&global_sockfd);
if (n < 0)
return (0);
}
-static int apcups_config (const char *key, const char *value)
+static int apcups_config (oconfig_item_t *ci)
{
- if (strcasecmp (key, "host") == 0)
- {
- if (conf_host != NULL)
- {
- free (conf_host);
- conf_host = NULL;
- }
- if ((conf_host = strdup (value)) == NULL)
- return (1);
- }
- else if (strcasecmp (key, "Port") == 0)
- {
- int port_tmp = atoi (value);
- if (port_tmp < 1 || port_tmp > 65535)
- {
- WARNING ("apcups plugin: Invalid port: %i", port_tmp);
- return (1);
- }
- conf_port = port_tmp;
- }
- else if (strcasecmp (key, "ReportSeconds") == 0)
+ int i;
+
+ for (i = 0; i < ci->children_num; i++)
{
- if (IS_TRUE (value))
- conf_report_seconds = 1;
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp (child->key, "Host") == 0)
+ cf_util_get_string (child, &conf_node);
+ else if (strcasecmp (child->key, "Port") == 0)
+ cf_util_get_service (child, &conf_service);
+ else if (strcasecmp (child->key, "ReportSeconds") == 0)
+ cf_util_get_boolean (child, &conf_report_seconds);
+ else if (strcasecmp (child->key, "PersistentConnection") == 0)
+ cf_util_get_boolean (child, &conf_persistent_conn);
else
- conf_report_seconds = 0;
- }
- else
- {
- return (-1);
+ ERROR ("apcups plugin: Unknown config option \"%s\".", child->key);
}
+
return (0);
-}
+} /* int apcups_config */
static void apc_submit_generic (char *type, char *type_inst, double value)
{
apcups_detail.itemp = -300.0;
apcups_detail.linefreq = -1.0;
- status = apc_query_server (conf_host == NULL
- ? APCUPS_DEFAULT_HOST
- : conf_host,
- conf_port, &apcups_detail);
+ status = apc_query_server ((conf_node == NULL) ? APCUPS_DEFAULT_NODE : conf_node,
+ (conf_service == NULL) ? APCUPS_DEFAULT_SERVICE : conf_service,
+ &apcups_detail);
/*
* if we did not connect then do not bother submitting
*/
if (status != 0)
{
- DEBUG ("apc_query_server (%s, %i) = %i",
- conf_host == NULL
- ? APCUPS_DEFAULT_HOST
- : conf_host,
- conf_port, status);
+ DEBUG ("apc_query_server (%s, %s) = %i",
+ (conf_node == NULL) ? APCUPS_DEFAULT_NODE : conf_node,
+ (conf_service == NULL) ? APCUPS_DEFAULT_SERVICE : conf_service,
+ status);
return (-1);
}
void module_register (void)
{
- plugin_register_config ("apcups", apcups_config, config_keys,
- config_keys_num);
+ plugin_register_complex_config ("apcups", apcups_config);
plugin_register_read ("apcups", apcups_read);
plugin_register_shutdown ("apcups", apcups_shutdown);
} /* void module_register */
diff --git a/src/barometer.c b/src/barometer.c
index a6d98354d7ae2857c9be395e0bb81254c3c2d7cb..c5e7f77b09380acdb31631d3c237cb71fc71013c 100644 (file)
--- a/src/barometer.c
+++ b/src/barometer.c
gauge_t * values = NULL; /**< rate values */
size_t values_num = 0; /**< number of rate values */
- int i;
+ size_t i;
gauge_t values_history[REF_TEMP_AVG_NUM];
for(i=0; i<values_num; ++i)
{
- DEBUG ("barometer: get_reference_temperature - rate %d: %lf **",
- i,
- values[i]);
+ DEBUG ("barometer: get_reference_temperature - rate %zu: %lf **",
+ i, values[i]);
if(!isnan(values[i]))
{
avg_sum += values[i];
for(i=0; i<REF_TEMP_AVG_NUM*list->num_values; ++i)
{
- DEBUG ("barometer: get_reference_temperature - history %d: %lf",
- i,
- values_history[i]);
+ DEBUG ("barometer: get_reference_temperature - history %zu: %lf",
+ i, values_history[i]);
if(!isnan(values_history[i]))
{
avg_sum += values_history[i];
for(i=0; i<values_num; ++i)
{
- DEBUG ("barometer: get_reference_temperature - rate last %d: %lf **",
- i,
- values[i]);
+ DEBUG ("barometer: get_reference_temperature - rate last %zu: %lf **",
+ i, values[i]);
if(!isnan(values[i]))
{
avg_sum += values[i];
diff --git a/src/ceph.c b/src/ceph.c
index d928a7ba4b5db1d71e87449f635783e44000f621..419ca6e56170758c5c05dea2e1e20994b53b2ff3 100644 (file)
--- a/src/ceph.c
+++ b/src/ceph.c
#include <stdlib.h>
#include <string.h>
#include <strings.h>
-#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>
diff --git a/src/collectd-nagios.c b/src/collectd-nagios.c
index 8b0f867949e1f09c1b8f015598c8dd08e8d8925c..b17e47e2e1618949772dd3ccfd3db592ddf643ca 100644 (file)
--- a/src/collectd-nagios.c
+++ b/src/collectd-nagios.c
static _Bool nan_is_error_g = 0;
static char **match_ds_g = NULL;
-static int match_ds_num_g = 0;
+static size_t match_ds_num_g = 0;
/* `strdup' is an XSI extension. I don't want to pull in all of XSI just for
* that, so here's an own implementation.. It's easy enough. The GCC attributes
return (RET_UNKNOWN);
}
- for (i = 0; i < (size_t) match_ds_num_g; i++)
+ for (i = 0; i < match_ds_num_g; i++)
{
size_t j;
diff --git a/src/collectd-tg.c b/src/collectd-tg.c
index 45e788c22206c5c733d696bc6ab778ab732643ec..80473e0ef79816fe53becb2ab41f4f86c5c86715 100644 (file)
--- a/src/collectd-tg.c
+++ b/src/collectd-tg.c
# include "config.h"
#endif
-#ifndef _ISOC99_SOURCE
-# define _ISOC99_SOURCE
-#endif
-
-#ifndef _POSIX_C_SOURCE
-# define _POSIX_C_SOURCE 200809L
-#endif
-
-#ifndef _XOPEN_SOURCE
-# define _XOPEN_SOURCE 700
-#endif
-
#if !__GNUC__
# define __attribute__(x) /**/
#endif
#include <time.h>
#include <signal.h>
#include <errno.h>
+#include <math.h>
#include "utils_heap.h"
loop = 0;
} /* }}} void signal_handler */
+static double dtime (void) /* {{{ */
+{
+ struct timespec ts = { 0 };
+
+ if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0)
+ perror ("clock_gettime");
+
+ return ((double) ts.tv_sec) + (((double) ts.tv_nsec) / 1e9);
+} /* }}} double dtime */
+
static int compare_time (const void *v0, const void *v1) /* {{{ */
{
const lcc_value_list_t *vl0 = v0;
host_num = get_boundet_random (0, conf_num_hosts);
vl->interval = conf_interval;
- vl->time = 1.0 + time (NULL)
+ vl->time = 1.0 + dtime ()
+ (host_num % (1 + (int) vl->interval));
if (get_boundet_random (0, 2) == 0)
if (vl->values_types[0] == LCC_TYPE_GAUGE)
vl->values[0].gauge = 100.0 * ((gauge_t) random ()) / (((gauge_t) RAND_MAX) + 1.0);
else
- vl->values[0].derive += get_boundet_random (0, 100);
+ vl->values[0].derive += (derive_t) get_boundet_random (0, 100);
status = lcc_network_values_send (net, vl);
if (status != 0)
int main (int argc, char **argv) /* {{{ */
{
int i;
- time_t last_time;
+ double last_time;
int values_sent = 0;
read_options (argc, argv);
printf ("%i values have been sent.\n", values_sent);
/* Check if we need to sleep */
- time_t now = time (NULL);
+ double now = dtime ();
while (now < vl->time)
{
/* 1 / 100 second */
struct timespec ts = { 0, 10000000 };
+
+ ts.tv_sec = (time_t) now;
+ ts.tv_nsec = (long) ((now - ((double) ts.tv_sec)) * 1e9);
+
nanosleep (&ts, /* remaining = */ NULL);
- now = time (NULL);
+ now = dtime ();
if (!loop)
break;
diff --git a/src/collectd.conf.in b/src/collectd.conf.in
index 38a053498f19ee851a8d6a1d75ee0cb7bcc83a3c..1f4ccf8175a99d44cecfa325429ddb586631e0dc 100644 (file)
--- a/src/collectd.conf.in
+++ b/src/collectd.conf.in
@BUILD_PLUGIN_MEMORY_TRUE@@BUILD_PLUGIN_MEMORY_TRUE@LoadPlugin memory
#@BUILD_PLUGIN_MIC_TRUE@LoadPlugin mic
#@BUILD_PLUGIN_MODBUS_TRUE@LoadPlugin modbus
+#@BUILD_PLUGIN_MQTT_TRUE@LoadPlugin mqtt
#@BUILD_PLUGIN_MULTIMETER_TRUE@LoadPlugin multimeter
#@BUILD_PLUGIN_MYSQL_TRUE@LoadPlugin mysql
#@BUILD_PLUGIN_NETAPP_TRUE@LoadPlugin netapp
#@BUILD_PLUGIN_WRITE_TSDB_TRUE@LoadPlugin write_tsdb
#@BUILD_PLUGIN_XMMS_TRUE@LoadPlugin xmms
#@BUILD_PLUGIN_ZFS_ARC_TRUE@LoadPlugin zfs_arc
+#@BUILD_PLUGIN_ZONE_TRUE@LoadPlugin zone
#@BUILD_PLUGIN_ZOOKEEPER_TRUE@LoadPlugin zookeeper
##############################################################################
# Host "localhost"
# Port "3551"
# ReportSeconds true
+# PersistentConnection true
#</Plugin>
#<Plugin aquaero>
# </Host>
#</Plugin>
+#<Plugin mqtt>
+# <Publish "name">
+# Host "localhost"
+# Port 1883
+# ClientId "localhost"
+# User "user"
+# Password "secret"
+# QoS 0
+# Prefix "collectd"
+# StoreRates true
+# Retain false
+# </Publish>
+# <Subscribe "name">
+# Host "localhost"
+# Port 1883
+# ClientId "localhost"
+# User "user"
+# Password "secret"
+# QoS 2
+# Topic "collectd/#"
+# CleanSession true
+# </Subscribe>
+#</Plugin>
+
#<Plugin mysql>
# <Database db_name>
# Host "database.serv.er"
# Host "localhost"
# Port "6379"
# Timeout 1000
+# Prefix "collectd/"
# </Node>
#</Plugin>
diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod
index ba2136554a64236d16b4b1eda08c4b4f229e07d5..aaeeaf419b703913392ef5e78448ffa76fc451dc 100644 (file)
--- a/src/collectd.conf.pod
+++ b/src/collectd.conf.pod
global B<Interval> setting. If a plugin provides own support for specifying an
interval, that setting will take precedence.
+=item B<FlushInterval> I<Seconds>
+
+Specifies the the interval, in seconds, to call the flush callback if it's
+defined in this plugin. By default, this is disabled
+
+=item B<FlushTimeout> I<Seconds>
+
+Specifies the value of the timeout argument of the flush callback.
+
=back
=item B<AutoLoadPlugin> B<false>|B<true>
The I<AMQP plugin> can be used to communicate with other instances of
I<collectd> or third party applications using an AMQP message broker. Values
are sent to or received from the broker, which handles routing, queueing and
-possibly filtering or messages.
+possibly filtering out messages.
+
+B<Synopsis:>
<Plugin "amqp">
# Send values to an AMQP broker
TCP-Port to connect to. Defaults to B<3551>.
-=item B<ReportSeconds> B<true|false>
+=item B<ReportSeconds> B<true>|B<false>
If set to B<true>, the time reported in the C<timeleft> metric will be
converted to seconds. This is the recommended setting. If set to B<false>, the
default for backwards compatibility, the time will be reported in minutes.
+=item B<PersistentConnection> B<true>|B<false>
+
+By default, the plugin will try to keep the connection to UPS open between
+reads. Since this appears to be somewhat brittle (I<apcupsd> appears to close
+the connection due to inactivity quite quickly), the plugin will try to detect
+this problem and switch to an open-read-close mode in such cases.
+
+You can instruct the plugin to close the connection after each read by setting
+this option to B<false>.
+
=back
=head2 Plugin C<aquaero>
=back
+=head2 Plugin C<mqtt>
+
+The I<MQTT plugin> can send metrics to MQTT (B<Publish> blocks) and receive
+values from MQTT (B<Subscribe> blocks).
+
+B<Synopsis:>
+
+ <Plugin mqtt>
+ <Publish "name">
+ Host "mqtt.example.com"
+ Prefix "collectd"
+ </Publish>
+ <Subscribe "name">
+ Host "mqtt.example.com"
+ Topic "collectd/#"
+ </Subscribe>
+ </Plugin>
+
+The plugin's configuration is in B<Publish> and/or B<Subscribe> blocks,
+configuring the sending and receiving direction respectively. The plugin will
+register a write callback named C<mqtt/I<name>> where I<name> is the string
+argument given to the B<Publish> block. Both types of blocks share many but not
+all of the following options. If an option is valid in only one of the blocks,
+it will be mentioned explicitly.
+
+B<Options:>
+
+=over 4
+
+=item B<Host> I<Hostname>
+
+Hostname of the MQTT broker to connect to.
+
+=item B<Port> I<Service>
+
+Port number or service name of the MQTT broker to connect to.
+
+=item B<User> I<UserName>
+
+Username used when authenticating to the MQTT broker.
+
+=item B<Password> I<Password>
+
+Password used when authenticating to the MQTT broker.
+
+=item B<ClientId> I<ClientId>
+
+MQTT client ID to use. Defaults to the hostname used by I<collectd>.
+
+=item B<QoS> [B<0>-B<2>]
+
+Sets the I<Quality of Service>, with the values C<0>, C<1> and C<2> meaning:
+
+=over 4
+
+=item B<0>
+
+At most once
+
+=item B<1>
+
+At least once
+
+=item B<2>
+
+Exactly once
+
+=back
+
+In B<Publish> blocks, this option determines the QoS flag set on outgoing
+messages and defaults to B<0>. In B<Subscribe> blocks, determines the maximum
+QoS setting the client is going to accept and defaults to B<2>. If the QoS flag
+on a message is larger than the maximum accepted QoS of a subscriber, the
+message's QoS will be downgraded.
+
+=item B<Prefix> I<Prefix> (Publish only)
+
+This plugin will use one topic per I<value list> which will looks like a path.
+I<Prefix> is used as the first path element and defaults to B<collectd>.
+
+An example topic name would be:
+
+ collectd/cpu-0/cpu-user
+
+=item B<Retain> B<false>|B<true> (Publish only)
+
+Controls whether the MQTT broker will retain (keep a copy of) the last message
+sent to each topic and deliver it to new subscribers. Defaults to B<false>.
+
+=item B<StoreRates> B<true>|B<false> (Publish only)
+
+Controls whether C<DERIVE> and C<COUNTER> metrics are converted to a I<rate>
+before sending. Defaults to B<true>.
+
+=item B<CleanSession> B<true>|B<false> (Subscribe only)
+
+Controls whether the MQTT "cleans" the session up after the subscriber
+disconnects or if it maintains the subscriber's subscriptions and all messages
+that arrive while the subscriber is disconnected. Defaults to B<true>.
+
+=item B<Topic> I<TopicName> (Subscribe only)
+
+Configures the topic(s) to subscribe to. You can use the single level C<+> and
+multi level C<#> wildcards. Defaults to B<collectd/#>, i.e. all topics beneath
+the B<collectd> branch.
+
+=back
+
=head2 Plugin C<mysql>
The C<mysql plugin> requires B<mysqlclient> to be installed. It connects to
Sets the URL to use to connect to the I<OpenLDAP> server. This option is
I<mandatory>.
+=item B<BindDN> I<BindDN>
+
+Name in the form of an LDAP distinguished name intended to be used for
+authentication. Defaults to empty string to establish an anonymous authorization.
+
+=item B<Password> I<Password>
+
+Password for simple bind authentication. If this option is not set,
+unauthenticated bind operation is used.
+
=item B<StartTLS> B<true|false>
Defines whether TLS must be used when connecting to the I<OpenLDAP> server.
allows to "group" several processes together. I<name> must not contain
slashes.
+=item B<CollectContextSwitch> I<Boolean>
+
+Collect context switch of the process.
+
=back
=head2 Plugin C<protocols>
Host "localhost"
Port "6379"
Timeout 1000
+ Prefix "collectd/"
+ Database 1
</Node>
</Plugin>
Values are submitted to I<Sorted Sets>, using the metric name as the key, and
the timestamp as the score. Retrieving a date range can then be done using the
-C<ZRANGEBYSCORE> I<Redis> command. Additionnally, all the identifiers of these
-I<Sorted Sets> are kept in a I<Set> called C<collectd/values> and can be
-retrieved using the C<SMEMBERS> I<Redis> command. See
+C<ZRANGEBYSCORE> I<Redis> command. Additionally, all the identifiers of these
+I<Sorted Sets> are kept in a I<Set> called C<collectd/values> (or
+C<${prefix}/values> if the B<Prefix> option was specified) and can be retrieved
+using the C<SMEMBERS> I<Redis> command. You can specify the database to use
+with the B<Database> parameter (default is C<0>). See
L<http://redis.io/commands#sorted_set> and L<http://redis.io/commands#set> for
details.
=item B<Node> I<Nodename>
The B<Node> block identifies a new I<Redis> node, that is a new I<Redis>
-instance running in an specified host and port. The name for node is a
+instance running on a specified host and port. The node name is a
canonical identifier which is used as I<plugin instance>. It is limited to
-64E<nbsp>characters in length.
+51E<nbsp>characters in length.
=item B<Host> I<Hostname>
The B<Timeout> option sets the socket connection timeout, in milliseconds.
+=item B<Prefix> I<Prefix>
+
+Prefix used when constructing the name of the I<Sorted Sets> and the I<Set>
+containing all metrics. Defaults to C<collectd/>, so metrics will have names
+like C<collectd/cpu-0/cpu-user>. When setting this to something different, it
+is recommended but not required to include a trailing slash in I<Prefix>.
+
+=item B<Database> I<Index>
+
+This index selects the redis database to use for writing operations. Defaults to C<0>.
+
=back
=head2 Plugin C<write_riemann>
diff --git a/src/collectdctl.c b/src/collectdctl.c
index 8357ce841838cad2f85238b5bbe3ba1758e1db43..febc99833aaa917f084e4d606e34a84c70b90fb4 100644 (file)
--- a/src/collectdctl.c
+++ b/src/collectdctl.c
return count;
} /* count_chars */
-static int array_grow (void **array, int *array_len, size_t elem_size)
+static int array_grow (void **array, size_t *array_len, size_t elem_size)
{
void *tmp;
int timeout = -1;
lcc_identifier_t *identifiers = NULL;
- int identifiers_num = 0;
+ size_t identifiers_num = 0;
char **plugins = NULL;
- int plugins_num = 0;
+ size_t plugins_num = 0;
int status;
int i;
values_types[values_len] = LCC_TYPE_GAUGE;
}
else { /* integer */
- values[values_len].counter = strtol (value, &endptr, 0);
+ values[values_len].counter = (counter_t) strtoull (value, &endptr, 0);
values_types[values_len] = LCC_TYPE_COUNTER;
}
++values_len;
int status;
while (42) {
- int c;
+ int opt;
- c = getopt (argc, argv, "s:h");
+ opt = getopt (argc, argv, "s:h");
- if (c == -1)
+ if (opt == -1)
break;
- switch (c) {
+ switch (opt) {
case 's':
snprintf (address, sizeof (address), "unix:%s", optarg);
address[sizeof (address) - 1] = '\0';
diff --git a/src/cpu.c b/src/cpu.c
index 2a2a4a9715d20e9b76055d559edcb1b2f9e55aa1..bcaea38c546305968487a8c509e117b09dfa1e0a 100644 (file)
--- a/src/cpu.c
+++ b/src/cpu.c
/* Adds a derive value to the internal state. This should be used by each read
* function for each state. At the end of the iteration, the read function
* should call cpu_commit(). */
-static int cpu_stage (size_t cpu_num, size_t state, derive_t value, cdtime_t now) /* {{{ */
+static int cpu_stage (size_t cpu_num, size_t state, derive_t d, cdtime_t now) /* {{{ */
{
int status;
cpu_state_t *s;
- value_t v;
+ gauge_t rate = NAN;
+ value_t val = {.derive = d};
if (state >= COLLECTD_CPU_STATE_ACTIVE)
return (EINVAL);
@@ -544,12 +545,11 @@ static int cpu_stage (size_t cpu_num, size_t state, derive_t value, cdtime_t now
s = get_cpu_state (cpu_num, state);
- v.gauge = NAN;
- status = value_to_rate (&v, value, &s->conv, DS_TYPE_DERIVE, now);
+ status = value_to_rate (&rate, val, DS_TYPE_DERIVE, now, &s->conv);
if (status != 0)
return (status);
- s->rate = v.gauge;
+ s->rate = rate;
s->has_value = 1;
return (0);
} /* }}} int cpu_stage */
diff --git a/src/csv.c b/src/csv.c
index b6e535ee6b4c9b44eae4cde70052e877c1c5e2ee..15494f450dd60a852be2b948c8356c781194c2e1 100644 (file)
--- a/src/csv.c
+++ b/src/csv.c
{
int offset;
int status;
- int i;
+ size_t i;
gauge_t *rates = NULL;
assert (0 == strcmp (ds->type, vl->type));
static int csv_create_file (const char *filename, const data_set_t *ds)
{
FILE *csv;
- int i;
+ size_t i;
if (check_create_dir (filename))
return (-1);
diff --git a/src/curl_json.c b/src/curl_json.c
index 3ba55603d329342e6a30fa86b6908531e3e36e73..80632424785ae697b8a809588cac5f1b2e61ba15 100644 (file)
--- a/src/curl_json.c
+++ b/src/curl_json.c
#include "utils_avltree.h"
#include "utils_complain.h"
-#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
if (*ptr == '/')
{
c_avl_tree_t *value;
- int len;
+ size_t len;
len = ptr-name;
if (len == 0)
{
user_data_t ud;
char *cb_name;
- struct timespec interval = { 0, 0 };
-
- CDTIME_T_TO_TIMESPEC (db->interval, &interval);
if (db->instance == NULL)
db->instance = strdup("default");
db->instance, db->url ? db->url : db->sock);
plugin_register_complex_read (/* group = */ NULL, cb_name, cj_read,
- /* interval = */ (db->interval > 0) ? &interval : NULL,
+ /* interval = */ db->interval,
&ud);
sfree (cb_name);
}
diff --git a/src/curl_xml.c b/src/curl_xml.c
index 37a36866c91982345f56b0371fac92ed42a78449..8a466bae6f98ff383979e60a2c586ae8e274e6cd 100644 (file)
--- a/src/curl_xml.c
+++ b/src/curl_xml.c
char *path;
char *type;
cx_values_t *values;
- int values_len;
+ size_t values_len;
char *instance_prefix;
char *instance;
int is_table;
if (ds->ds_num != xpath->values_len)
{
- WARNING ("curl_xml plugin: DataSet `%s' requires %i values, but config talks about %i",
+ WARNING ("curl_xml plugin: DataSet `%s' requires %zu values, but config talks about %zu",
xpath->type, ds->ds_num, xpath->values_len);
return (-1);
}
{
value_t values[xpath->values_len];
int status;
- int i;
+ size_t i;
assert (xpath->values_len > 0);
assert (xpath->values_len == vl->values_len);
xpath->values = (cx_values_t *) malloc (sizeof (cx_values_t) * ci->values_num);
if (xpath->values == NULL)
return (-1);
- xpath->values_len = ci->values_num;
+ xpath->values_len = (size_t) ci->values_num;
/* populate cx_values_t structure */
for (i = 0; i < ci->values_num; i++)
cb_name = ssnprintf_alloc ("curl_xml-%s-%s", db->instance, db->url);
plugin_register_complex_read (/* group = */ "curl_xml", cb_name, cx_read,
- /* interval = */ NULL, &ud);
+ /* interval = */ 0, &ud);
sfree (cb_name);
}
else
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
index 99dc1584f62b2afbd4e14fbe201369012189711a..1634713b97393a8ecd97d0d31b0f87494aafcb38 100644 (file)
--- a/src/daemon/Makefile.am
+++ b/src/daemon/Makefile.am
sbin_PROGRAMS = collectd
-noinst_LTLIBRARIES = libavltree.la libcommon.la libheap.la libplugin_mock.la
+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_mock.c
+libplugin_mock_la_LIBADD = $(COMMON_LIBS)
collectd_SOURCES = collectd.c collectd.h \
configfile.c configfile.h \
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
+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
collectd_LDADD += -loconfig
endif
-check_PROGRAMS = test_common test_utils_avltree test_utils_heap
-TESTS = test_common test_utils_avltree test_utils_heap
+check_PROGRAMS = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_subst
+TESTS = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_subst
test_common_SOURCES = common_test.c ../testing.h
-test_common_LDADD = libcommon.la libplugin_mock.la $(COMMON_LIBS)
+test_common_LDADD = libcommon.la 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_subst_SOURCES = utils_subst_test.c ../testing.h \
+ utils_subst.c utils_subst.h
+test_utils_subst_LDADD = libcommon.la libplugin_mock.la
diff --git a/src/daemon/collectd.c b/src/daemon/collectd.c
index 88c38acea0990e1aa8684959c55ca9e8d94877e1..58325b95be73973b5cd5c596466255d3a325f6a5 100644 (file)
--- a/src/daemon/collectd.c
+++ b/src/daemon/collectd.c
#include "configfile.h"
#include <sys/types.h>
-#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#ifdef KERNEL_LINUX
int notify_upstart (void)
{
- const char *upstart_job = getenv("UPSTART_JOB");
+ char const *upstart_job = getenv("UPSTART_JOB");
if (upstart_job == NULL)
return 0;
if (strcmp(upstart_job, "collectd") != 0)
+ {
+ WARNING ("Environment specifies unexpected UPSTART_JOB=\"%s\", expected \"collectd\". Ignoring the variable.", upstart_job);
return 0;
+ }
- WARNING ("supervised by upstart, will stop to signal readyness");
+ NOTICE("Upstart detected, stopping now to signal readyness.");
raise(SIGSTOP);
unsetenv("UPSTART_JOB");
int notify_systemd (void)
{
- int fd = -1;
- const char *notifysocket = getenv("NOTIFY_SOCKET");
+ int fd;
+ const char *notifysocket;
struct sockaddr_un su;
- struct iovec iov;
- struct msghdr hdr;
+ size_t su_size;
+ char buffer[] = "READY=1\n";
+ notifysocket = getenv ("NOTIFY_SOCKET");
if (notifysocket == NULL)
return 0;
- if ((strchr("@/", notifysocket[0])) == NULL ||
- strlen(notifysocket) < 2)
+ if ((strlen (notifysocket) < 2)
+ || ((notifysocket[0] != '@') && (notifysocket[0] != '/')))
+ {
+ ERROR ("invalid notification socket NOTIFY_SOCKET=\"%s\": path must be absolute", notifysocket);
return 0;
+ }
+ NOTICE ("Systemd detected, trying to signal readyness.");
+
+ unsetenv ("NOTIFY_SOCKET");
- WARNING ("supervised by systemd, will signal readyness");
- if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
- WARNING ("cannot contact systemd socket %s", notifysocket);
+ fd = socket (AF_UNIX, SOCK_DGRAM, /* protocol = */ 0);
+ if (fd < 0) {
+ char errbuf[1024];
+ ERROR ("creating UNIX socket failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
return 0;
}
- bzero(&su, sizeof(su));
+ memset (&su, 0, sizeof (su));
su.sun_family = AF_UNIX;
- sstrncpy (su.sun_path, notifysocket, sizeof(su.sun_path));
-
- if (notifysocket[0] == '@')
+ if (notifysocket[0] != '@')
+ {
+ /* regular UNIX socket */
+ sstrncpy (su.sun_path, notifysocket, sizeof (su.sun_path));
+ su_size = sizeof (su);
+ }
+ else
+ {
+#if KERNEL_LINUX
+ /* Linux abstract namespace socket: specify address as "\0foo", i.e.
+ * start with a null byte. Since null bytes have no special meaning in
+ * that case, we have to set su_size correctly to cover only the bytes
+ * that are part of the address. */
+ sstrncpy (su.sun_path, notifysocket, sizeof (su.sun_path));
su.sun_path[0] = 0;
+ su_size = sizeof (sa_family_t) + strlen (notifysocket);
+ if (su_size > sizeof (su))
+ su_size = sizeof (su);
+#else
+ ERROR ("Systemd socket uses Linux abstract namespace notation (\"%s\"), "
+ "but I don't appear to be running on Linux.", notifysocket);
+ return 0;
+#endif
+ }
- bzero(&iov, sizeof(iov));
- iov.iov_base = "READY=1";
- iov.iov_len = strlen("READY=1");
-
- bzero(&hdr, sizeof(hdr));
- hdr.msg_name = &su;
- hdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) +
- strlen(notifysocket);
- hdr.msg_iov = &iov;
- hdr.msg_iovlen = 1;
-
- unsetenv("NOTIFY_SOCKET");
- if (sendmsg(fd, &hdr, MSG_NOSIGNAL) < 0) {
- WARNING ("cannot send notification to systemd");
+ if (sendto (fd, buffer, strlen (buffer), MSG_NOSIGNAL, (void *) &su, (socklen_t) su_size) < 0)
+ {
+ char errbuf[1024];
+ ERROR ("sendto(\"%s\") failed: %s", notifysocket,
+ sstrerror (errno, errbuf, sizeof (errbuf)));
close(fd);
return 0;
}
+
close(fd);
return 1;
}
diff --git a/src/daemon/collectd.h b/src/daemon/collectd.h
index 80b753c8a83442b3e278858a8cb54528bf9868d1..66b485681b223c97c7fda9cc595a16d9616e0494 100644 (file)
--- a/src/daemon/collectd.h
+++ b/src/daemon/collectd.h
# include <time.h>
# endif
#endif
+#if HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
#if HAVE_ASSERT_H
# include <assert.h>
diff --git a/src/daemon/common.c b/src/daemon/common.c
index b2448086c53aadc0641b63bf7eef9b51e8c1decf..8f22011ed57c46c94244f8273461fce3fa7af155 100644 (file)
--- a/src/daemon/common.c
+++ b/src/daemon/common.c
/* for getaddrinfo */
#include <sys/types.h>
-#include <sys/socket.h>
#include <netdb.h>
#if HAVE_NETINET_IN_H
assert ((0 > status) || (nleft >= (size_t)status));
- nleft = nleft - status;
- ptr = ptr + status;
+ nleft = nleft - ((size_t) status);
+ ptr = ptr + ((size_t) status);
}
return (0);
if (status < 0)
return (status);
- nleft = nleft - status;
- ptr = ptr + status;
+ nleft = nleft - ((size_t) status);
+ ptr = ptr + ((size_t) status);
}
return (0);
}
assert (buffer[buffer_size - 1] == 0);
- return (strlen (buffer));
+ return ((int) strlen (buffer));
}
int strsubstitute (char *str, char c_from, char c_to)
int escape_slashes (char *buffer, size_t buffer_size)
{
- int i;
size_t buffer_len;
+ size_t i;
buffer_len = strlen (buffer);
* Join the components together again
*/
dir[0] = '/';
- if (strjoin (dir + path_is_absolute, dir_len - path_is_absolute,
- fields, i + 1, "/") < 0)
+ 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);
{
size_t offset = 0;
int status;
- int i;
+ size_t i;
gauge_t *rates = NULL;
assert (0 == strcmp (ds->type, vl->type));
int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds)
{
- int i;
+ size_t i;
char *dummy;
char *ptr;
char *saveptr;
- i = -1;
+ i = 0;
dummy = buffer;
saveptr = NULL;
+ vl->time = 0;
while ((ptr = strtok_r (dummy, ":", &saveptr)) != NULL)
{
dummy = NULL;
if (i >= vl->values_len)
{
/* Make sure i is invalid. */
- i = vl->values_len + 1;
+ i = 0;
break;
}
- if (i == -1)
+ if (vl->time == 0)
{
if (strcmp ("N", ptr) == 0)
vl->time = cdtime ();
vl->time = DOUBLE_TO_CDTIME_T (tmp);
}
- }
- else
- {
- if ((strcmp ("U", ptr) == 0) && (ds->ds[i].type == DS_TYPE_GAUGE))
- vl->values[i].gauge = NAN;
- else if (0 != parse_value (ptr, &vl->values[i], ds->ds[i].type))
- return -1;
+
+ continue;
}
+ if ((strcmp ("U", ptr) == 0) && (ds->ds[i].type == DS_TYPE_GAUGE))
+ vl->values[i].gauge = NAN;
+ else if (0 != parse_value (ptr, &vl->values[i], ds->ds[i].type))
+ return -1;
+
i++;
} /* while (strtok_r) */
- if ((ptr != NULL) || (i != vl->values_len))
+ if ((ptr != NULL) || (i == 0))
return (-1);
return (0);
} /* int parse_values */
if (old_value > new_value)
{
if (old_value <= 4294967295U)
- diff = (4294967295U - old_value) + new_value;
+ diff = (4294967295U - old_value) + new_value + 1;
else
- diff = (18446744073709551615ULL - old_value)
- + new_value;
+ diff = (18446744073709551615ULL - old_value) + new_value + 1;
}
else
{
return (0);
} /* }}} value_t rate_to_value */
-int value_to_rate (value_t *ret_rate, derive_t value, /* {{{ */
- value_to_rate_state_t *state,
- int ds_type, cdtime_t t)
+int value_to_rate (gauge_t *ret_rate, /* {{{ */
+ value_t value, int ds_type, cdtime_t t, value_to_rate_state_t *state)
{
- double interval;
+ gauge_t interval;
/* Another invalid state: The time is not increasing. */
if (t <= state->last_time)
interval = CDTIME_T_TO_DOUBLE(t - state->last_time);
/* Previous value is invalid. */
- if (state->last_time == 0) /* {{{ */
+ if (state->last_time == 0)
{
- if (ds_type == DS_TYPE_DERIVE)
- {
- state->last_value.derive = value;
- }
- else if (ds_type == DS_TYPE_COUNTER)
- {
- state->last_value.counter = (counter_t) value;
- }
- else if (ds_type == DS_TYPE_ABSOLUTE)
- {
- state->last_value.absolute = (absolute_t) value;
- }
- else
- {
- assert (23 == 42);
- }
-
+ state->last_value = value;
state->last_time = t;
return (EAGAIN);
- } /* }}} */
+ }
- if (ds_type == DS_TYPE_DERIVE)
- {
- ret_rate->gauge = (value - state->last_value.derive) / interval;
- state->last_value.derive = value;
+ switch (ds_type) {
+ case DS_TYPE_DERIVE: {
+ derive_t diff = value.derive - state->last_value.derive;
+ *ret_rate = ((gauge_t) diff) / ((gauge_t) interval);
+ break;
}
- else if (ds_type == DS_TYPE_COUNTER)
- {
- ret_rate->gauge = (((counter_t)value) - state->last_value.counter) / interval;
- state->last_value.counter = (counter_t) value;
+ case DS_TYPE_GAUGE: {
+ *ret_rate = value.gauge;
+ break;
}
- else if (ds_type == DS_TYPE_ABSOLUTE)
- {
- ret_rate->gauge = (((absolute_t)value) - state->last_value.absolute) / interval;
- state->last_value.absolute = (absolute_t) value;
+ case DS_TYPE_COUNTER: {
+ counter_t diff = counter_diff (state->last_value.counter, value.counter);
+ *ret_rate = ((gauge_t) diff) / ((gauge_t) interval);
+ break;
}
- else
- {
- assert (23 == 42);
+ case DS_TYPE_ABSOLUTE: {
+ absolute_t diff = value.absolute;
+ *ret_rate = ((gauge_t) diff) / ((gauge_t) interval);
+ break;
+ }
+ default:
+ return EINVAL;
}
- state->last_time = t;
+ state->last_value = value;
+ state->last_time = t;
return (0);
} /* }}} value_t rate_to_value */
diff --git a/src/daemon/common.h b/src/daemon/common.h
index da21cad9a6f3a81f1120b466740a669ec009c231..c3f7f5485cb5888ed7a95634e538ff9c35b82d46 100644 (file)
--- a/src/daemon/common.h
+++ b/src/daemon/common.h
int rate_to_value (value_t *ret_value, gauge_t rate,
rate_to_value_state_t *state, int ds_type, cdtime_t t);
-int value_to_rate (value_t *ret_rate, derive_t value,
- value_to_rate_state_t *state, int ds_type, cdtime_t t);
+int value_to_rate (gauge_t *ret_rate, value_t value, int ds_type, cdtime_t t,
+ value_to_rate_state_t *state);
/* Converts a service name (a string) to a port number
* (in the range [1-65535]). Returns less than zero on error. */
index 1fa8f324461293c201b30440a8bb3e857062a993..0ee4e7e0eb2c6823e81f32063ceff48eaca8c127 100644 (file)
--- a/src/daemon/common_test.c
+++ b/src/daemon/common_test.c
return (0);
}
+DEF_TEST(escape_slashes)
+{
+ struct {
+ char *str;
+ char *want;
+ } cases[] = {
+ {"foo/bar/baz", "foo_bar_baz"},
+ {"/like/a/path", "like_a_path"},
+ {"trailing/slash/", "trailing_slash_"},
+ {"foo//bar", "foo__bar"},
+ };
+ size_t i;
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ char buffer[32];
+
+ strncpy (buffer, cases[i].str, sizeof (buffer));
+ OK(escape_slashes (buffer, sizeof (buffer)) == 0);
+ STREQ(cases[i].want, buffer);
+ }
+
+ return 0;
+}
+
+DEF_TEST(escape_string)
+{
+ struct {
+ char *str;
+ char *want;
+ } cases[] = {
+ {"foobar", "foobar"},
+ {"f00bar", "f00bar"},
+ {"foo bar", "\"foo bar\""},
+ {"foo \"bar\"", "\"foo \\\"bar\\\"\""},
+ {"012345678901234", "012345678901234"},
+ {"012345 78901234", "\"012345 789012\""},
+ {"012345 78901\"34", "\"012345 78901\""},
+ };
+ size_t i;
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ char buffer[16];
+
+ strncpy (buffer, cases[i].str, sizeof (buffer));
+ OK(escape_string (buffer, sizeof (buffer)) == 0);
+ STREQ(cases[i].want, buffer);
+ }
+
+ return 0;
+}
+
DEF_TEST(strunescape)
{
char buffer[16];
return (0);
}
+DEF_TEST(parse_values)
+{
+ struct {
+ char buffer[64];
+ int status;
+ gauge_t value;
+ } cases[] = {
+ {"1435044576:42", 0, 42.0},
+ {"1435044576:42:23", -1, NAN},
+ {"1435044576:U", 0, NAN},
+ {"N:12.3", 0, 12.3},
+ {"N:42.0:23", -1, NAN},
+ {"N:U", 0, NAN},
+ {"T:42.0", -1, NAN},
+ };
+
+ size_t i;
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ {
+ data_source_t dsrc = {
+ .name = "value",
+ .type = DS_TYPE_GAUGE,
+ .min = 0.0,
+ .max = NAN,
+ };
+ data_set_t ds = {
+ .type = "example",
+ .ds_num = 1,
+ .ds = &dsrc,
+ };
+
+ value_t v = {
+ .gauge = NAN,
+ };
+ value_list_t vl = {
+ .values = &v,
+ .values_len = 1,
+ .time = 0,
+ .interval = 0,
+ .host = "example.com",
+ .plugin = "common_test",
+ .type = "example",
+ .meta = NULL,
+ };
+
+ int status = parse_values (cases[i].buffer, &vl, &ds);
+ EXPECT_INTEQ (cases[i].status, status);
+ if (status != 0)
+ continue;
+
+ DBLEQ (cases[i].value, vl.values[0].gauge);
+ }
+
+ return (0);
+}
+
+DEF_TEST(value_to_rate)
+{
+ struct {
+ time_t t0;
+ time_t t1;
+ int ds_type;
+ value_t v0;
+ value_t v1;
+ gauge_t want;
+ } cases[] = {
+ { 0, 10, DS_TYPE_DERIVE, {.derive = 0}, {.derive = 1000}, NAN},
+ {10, 20, DS_TYPE_DERIVE, {.derive = 1000}, {.derive = 2000}, 100.0},
+ {20, 30, DS_TYPE_DERIVE, {.derive = 2000}, {.derive = 1800}, -20.0},
+ { 0, 10, DS_TYPE_COUNTER, {.counter = 0}, {.counter = 1000}, NAN},
+ {10, 20, DS_TYPE_COUNTER, {.counter = 1000}, {.counter = 5000}, 400.0},
+ /* 32bit wrap-around. */
+ {20, 30, DS_TYPE_COUNTER, {.counter = 4294967238ULL}, {.counter = 42}, 10.0},
+ /* 64bit wrap-around. */
+ {30, 40, DS_TYPE_COUNTER, {.counter = 18446744073709551558ULL}, {.counter = 42}, 10.0},
+ };
+ size_t i;
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ value_to_rate_state_t state = { cases[i].v0, TIME_T_TO_CDTIME_T (cases[i].t0) };
+ gauge_t got;
+
+ if (cases[i].t0 == 0) {
+ OK(value_to_rate (&got, cases[i].v1, cases[i].ds_type, TIME_T_TO_CDTIME_T(cases[i].t1), &state) == EAGAIN);
+ continue;
+ }
+
+ OK(value_to_rate (&got, cases[i].v1, cases[i].ds_type, TIME_T_TO_CDTIME_T(cases[i].t1), &state) == 0);
+ DBLEQ(cases[i].want, got);
+ }
+
+ return 0;
+}
+
int main (void)
{
RUN_TEST(sstrncpy);
RUN_TEST(sstrdup);
RUN_TEST(strsplit);
RUN_TEST(strjoin);
+ RUN_TEST(escape_slashes);
+ RUN_TEST(escape_string);
RUN_TEST(strunescape);
+ RUN_TEST(parse_values);
+ RUN_TEST(value_to_rate);
END_TEST;
}
index ae3e79899d2eddf1304bcc00ba178289b3602d02..ae9ab3a6cfe6bd6679fbc3dadc5ffa5a124fc25f 100644 (file)
--- a/src/daemon/configfile.c
+++ b/src/daemon/configfile.c
/* default to the global interval set before loading this plugin */
memset (&ctx, 0, sizeof (ctx));
ctx.interval = cf_get_default_interval ();
+ ctx.flush_interval = 0;
+ ctx.flush_timeout = 0;
- for (i = 0; i < ci->children_num; ++i) {
- if (strcasecmp("Globals", ci->children[i].key) == 0)
- cf_util_get_flag (ci->children + i, &flags, PLUGIN_FLAGS_GLOBAL);
- else if (strcasecmp ("Interval", ci->children[i].key) == 0) {
- if (cf_util_get_cdtime (ci->children + i, &ctx.interval) != 0) {
- /* cf_util_get_cdtime will log an error */
- continue;
- }
- }
+ for (i = 0; i < ci->children_num; ++i)
+ {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp("Globals", child->key) == 0)
+ cf_util_get_flag (child, &flags, PLUGIN_FLAGS_GLOBAL);
+ else if (strcasecmp ("Interval", child->key) == 0)
+ cf_util_get_cdtime (child, &ctx.interval);
+ else if (strcasecmp ("FlushInterval", child->key) == 0)
+ cf_util_get_cdtime (child, &ctx.flush_interval);
+ else if (strcasecmp ("FlushTimeout", child->key) == 0)
+ cf_util_get_cdtime (child, &ctx.flush_timeout);
else {
WARNING("Ignoring unknown LoadPlugin option \"%s\" "
"for plugin \"%s\"",
- ci->children[i].key, ci->values[0].value.string);
+ child->key, ci->values[0].value.string);
}
}
diff --git a/src/daemon/meta_data_test.c b/src/daemon/meta_data_test.c
--- /dev/null
@@ -0,0 +1,119 @@
+/**
+ * collectd - src/daemon/meta_data_test.c
+ * Copyright (C) 2015 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>
+ */
+
+#include "testing.h"
+#include "collectd.h"
+#include "common.h" /* for STATIC_ARRAY_SIZE */
+#include "meta_data.h"
+
+DEF_TEST(base)
+{
+ meta_data_t *m;
+
+ char *s;
+ int64_t si;
+ uint64_t ui;
+ double d;
+ _Bool b;
+
+ CHECK_NOT_NULL (m = meta_data_create ());
+
+ /* all of these are absent */
+ OK(meta_data_get_string (m, "string", &s) != 0);
+ OK(meta_data_get_signed_int (m, "signed_int", &si) != 0);
+ OK(meta_data_get_unsigned_int (m, "unsigned_int", &ui) != 0);
+ OK(meta_data_get_double (m, "double", &d) != 0);
+ OK(meta_data_get_boolean (m, "boolean", &b) != 0);
+
+ /* populate structure */
+ CHECK_ZERO (meta_data_add_string (m, "string", "foobar"));
+ OK(meta_data_exists (m, "string"));
+ OK(meta_data_type (m, "string") == MD_TYPE_STRING);
+
+ CHECK_ZERO (meta_data_add_signed_int (m, "signed_int", -1));
+ OK(meta_data_exists (m, "signed_int"));
+ OK(meta_data_type (m, "signed_int") == MD_TYPE_SIGNED_INT);
+
+ CHECK_ZERO (meta_data_add_unsigned_int (m, "unsigned_int", 1));
+ OK(meta_data_exists (m, "unsigned_int"));
+ OK(meta_data_type (m, "unsigned_int") == MD_TYPE_UNSIGNED_INT);
+
+ CHECK_ZERO (meta_data_add_double (m, "double", 47.11));
+ OK(meta_data_exists (m, "double"));
+ OK(meta_data_type (m, "double") == MD_TYPE_DOUBLE);
+
+ CHECK_ZERO (meta_data_add_boolean (m, "boolean", 1));
+ OK(meta_data_exists (m, "boolean"));
+ OK(meta_data_type (m, "boolean") == MD_TYPE_BOOLEAN);
+
+ /* retrieve and check all values */
+ CHECK_ZERO (meta_data_get_string (m, "string", &s));
+ STREQ ("foobar", s);
+ sfree (s);
+
+ CHECK_ZERO (meta_data_get_signed_int (m, "signed_int", &si));
+ EXPECT_INTEQ (-1, (int) si);
+
+ CHECK_ZERO (meta_data_get_unsigned_int (m, "unsigned_int", &ui));
+ EXPECT_INTEQ (1, (int) ui);
+
+ CHECK_ZERO (meta_data_get_double (m, "double", &d));
+ DBLEQ (47.11, d);
+
+ CHECK_ZERO (meta_data_get_boolean (m, "boolean", &b));
+ OK1 (b, "b evaluates to true");
+
+ /* retrieving the wrong type always fails */
+ EXPECT_INTEQ (-2, meta_data_get_boolean (m, "string", &b));
+ EXPECT_INTEQ (-2, meta_data_get_string (m, "signed_int", &s));
+ EXPECT_INTEQ (-2, meta_data_get_string (m, "unsigned_int", &s));
+ EXPECT_INTEQ (-2, meta_data_get_string (m, "double", &s));
+ EXPECT_INTEQ (-2, meta_data_get_string (m, "boolean", &s));
+
+ /* replace existing keys */
+ CHECK_ZERO (meta_data_add_signed_int (m, "string", 666));
+ OK(meta_data_type (m, "string") == MD_TYPE_SIGNED_INT);
+
+ CHECK_ZERO (meta_data_add_signed_int (m, "signed_int", 666));
+ CHECK_ZERO (meta_data_get_signed_int (m, "signed_int", &si));
+ EXPECT_INTEQ (666, (int) si);
+
+ /* deleting keys */
+ CHECK_ZERO (meta_data_delete (m, "signed_int"));
+ EXPECT_INTEQ (-2, meta_data_delete (m, "doesnt exist"));
+
+ meta_data_destroy (m);
+ return 0;
+}
+
+int main (void)
+{
+ RUN_TEST(base);
+
+ END_TEST;
+}
+
+/* vim: set sw=2 sts=2 et : */
diff --git a/src/daemon/plugin.c b/src/daemon/plugin.c
index 3da8eccbb3b2b147f8042c866ded54ee788fe127..be3f03fc57d5a7d1a68a4fd0b831543f44b6f03f 100644 (file)
--- a/src/daemon/plugin.c
+++ b/src/daemon/plugin.c
write_queue_t *next;
};
+struct flush_callback_s {
+ char *name;
+ cdtime_t timeout;
+};
+typedef struct flush_callback_s flush_callback_t;
+
/*
* Private variables
*/
static void stop_write_threads (void) /* {{{ */
{
write_queue_t *q;
- int i;
+ size_t i;
if (write_threads == NULL)
return;
if (i > 0)
{
- WARNING ("plugin: %i value list%s left after shutting down "
+ WARNING ("plugin: %zu value list%s left after shutting down "
"the write threads.",
i, (i == 1) ? " was" : "s were");
}
int plugin_register_complex_read (const char *group, const char *name,
plugin_read_cb callback,
- const struct timespec *interval,
+ cdtime_t interval,
user_data_t *user_data)
{
read_func_t *rf;
rf->rf_group[0] = '\0';
rf->rf_name = strdup (name);
rf->rf_type = RF_COMPLEX;
- if (interval != NULL)
- rf->rf_interval = TIMESPEC_TO_CDTIME_T (interval);
- else
- rf->rf_interval = plugin_get_interval ();
+ rf->rf_interval = (interval != 0) ? interval : plugin_get_interval ();
/* Set user data */
if (user_data == NULL)
(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);
+} /* static int plugin_flush_callback */
+
+static void plugin_flush_timeout_callback_free (void *data)
+{
+ flush_callback_t *cb = data;
+
+ if (cb == NULL) return;
+
+ sfree(cb->name);
+ sfree(cb);
+} /* static void plugin_flush_callback_free */
+
+static char *plugin_flush_callback_name (const char *name)
+{
+ char *flush_prefix = "flush/";
+ size_t prefix_size;
+ char *flush_name;
+ size_t name_size;
+
+ prefix_size = strlen(flush_prefix);
+ name_size = strlen(name);
+
+ flush_name = malloc (sizeof(char) * (name_size + prefix_size + 1));
+ if (flush_name == NULL)
+ {
+ ERROR ("plugin_flush_callback_name: malloc failed.");
+ return (NULL);
+ }
+
+ sstrncpy (flush_name, flush_prefix, prefix_size + 1);
+ sstrncpy (flush_name + prefix_size, name, name_size + 1);
+
+ return flush_name;
+} /* static char *plugin_flush_callback_name */
+
int plugin_register_flush (const char *name,
plugin_flush_cb callback, user_data_t *ud)
{
- return (create_register_callback (&list_flush, name,
- (void *) callback, ud));
+ int status;
+ plugin_ctx_t ctx = plugin_get_ctx ();
+
+ status = create_register_callback (&list_flush, name,
+ (void *) callback, ud);
+ if (status != 0)
+ return status;
+
+ if (ctx.flush_interval != 0)
+ {
+ char *flush_name;
+ user_data_t ud;
+ flush_callback_t *cb;
+
+ flush_name = plugin_flush_callback_name (name);
+ if (flush_name == NULL)
+ return (-1);
+
+ cb = malloc(sizeof(flush_callback_t));
+ if (cb == NULL)
+ {
+ ERROR ("plugin_register_flush: malloc failed.");
+ sfree(flush_name);
+ return (-1);
+ }
+
+ cb->name = strdup (name);
+ if (cb->name == NULL)
+ {
+ ERROR ("plugin_register_flush: strdup failed.");
+ sfree(cb);
+ sfree(flush_name);
+ return (-1);
+ }
+ cb->timeout = ctx.flush_timeout;
+
+ ud.data = cb;
+ ud.free_func = plugin_flush_timeout_callback_free;
+
+ status = plugin_register_complex_read (
+ /* group = */ "flush",
+ /* name = */ flush_name,
+ /* callback = */ plugin_flush_timeout_callback,
+ /* interval = */ ctx.flush_interval,
+ /* user data = */ &ud);
+
+ sfree(flush_name);
+ if (status != 0)
+ {
+ sfree(cb->name);
+ sfree(cb);
+ return status;
+ }
+ }
+
+ return 0;
} /* int plugin_register_flush */
int plugin_register_missing (const char *name,
int plugin_register_data_set (const data_set_t *ds)
{
data_set_t *ds_copy;
- int i;
+ size_t i;
if ((data_sets != NULL)
&& (c_avl_get (data_sets, ds->type, NULL) == 0))
int plugin_unregister_flush (const char *name)
{
- return (plugin_unregister (list_flush, name));
+ plugin_ctx_t ctx = plugin_get_ctx ();
+
+ if (ctx.flush_interval != 0)
+ {
+ char *flush_name;
+
+ flush_name = plugin_flush_callback_name (name);
+ if (flush_name != NULL)
+ {
+ plugin_unregister_read(flush_name);
+ sfree(flush_name);
+ }
+ }
+
+ return plugin_unregister (list_flush, name);
}
int plugin_unregister_missing (const char *name)
if (ds->ds_num != vl->values_len)
{
ERROR ("plugin_dispatch_values: ds->type = %s: "
- "(ds->ds_num = %i) != "
- "(vl->values_len = %i)",
+ "(ds->ds_num = %zu) != "
+ "(vl->values_len = %zu)",
ds->type, ds->ds_num, vl->values_len);
return (-1);
}
diff --git a/src/daemon/plugin.h b/src/daemon/plugin.h
index 70a22326e09f7b3f492877711e6b5152e5e369c8..b1adb527bb46536334af708275e1cbd0232a4f1d 100644 (file)
--- a/src/daemon/plugin.h
+++ b/src/daemon/plugin.h
struct value_list_s
{
value_t *values;
- int values_len;
+ size_t values_len;
cdtime_t time;
cdtime_t interval;
char host[DATA_MAX_NAME_LEN];
struct data_set_s
{
char type[DATA_MAX_NAME_LEN];
- int ds_num;
+ size_t ds_num;
data_source_t *ds;
};
typedef struct data_set_s data_set_t;
struct plugin_ctx_s
{
cdtime_t interval;
+ cdtime_t flush_interval;
+ cdtime_t flush_timeout;
};
typedef struct plugin_ctx_s plugin_ctx_t;
* "plugin_register_complex_read" returns an error (non-zero). */
int plugin_register_complex_read (const char *group, const char *name,
plugin_read_cb callback,
- const struct timespec *interval,
+ cdtime_t interval,
user_data_t *user_data);
int plugin_register_write (const char *name,
plugin_write_cb callback, user_data_t *user_data);
index 865288099500979c5ebaeab904899693a8e2cff1..f7bf1c016ad894f926003ad179112a6196edd161 100644 (file)
--- a/src/daemon/plugin_mock.c
+++ b/src/daemon/plugin_mock.c
#include "plugin.h"
+#if HAVE_LIBKSTAT
+kstat_ctl_t *kc = NULL;
+#endif /* HAVE_LIBKSTAT */
+
void plugin_log (int level, char const *format, ...)
{
char buffer[1024];
index c0e61c54b0e9e52168c85b31c9cd7bd9b422efde..75a980aa2a9801c2d754362beb1ca2e12642c820 100644 (file)
--- a/src/daemon/types_list.c
+++ b/src/daemon/types_list.c
char *fields[64];
size_t fields_num;
data_set_t *ds;
- int i;
+ size_t i;
fields_num = strsplit (buf, fields, 64);
if (fields_num < 2)
if (parse_ds (ds->ds + i, fields[i + 1], strlen (fields[i + 1])) != 0)
{
sfree (ds->ds);
- ERROR ("types_list: parse_line: Cannot parse data source #%i "
+ ERROR ("types_list: parse_line: Cannot parse data source #%zu "
"of data set %s", i, ds->type);
return;
}
index 76213955ca168dc17c9b01833b15fdd5afe3c517..3f7a596b1d6acae1b4ce6a4e82db7346a3ac78d3 100644 (file)
--- a/src/daemon/utils_cache.c
+++ b/src/daemon/utils_cache.c
typedef struct cache_entry_s
{
char name[6 * DATA_MAX_NAME_LEN];
- int values_num;
+ size_t values_num;
gauge_t *values_gauge;
value_t *values_raw;
/* Time contained in the package
return (strcmp (a->name, b->name));
} /* int cache_compare */
-static cache_entry_t *cache_alloc (int values_num)
+static cache_entry_t *cache_alloc (size_t values_num)
{
cache_entry_t *ce;
static void uc_check_range (const data_set_t *ds, cache_entry_t *ce)
{
- int i;
+ size_t i;
for (i = 0; i < ds->ds_num; i++)
{
static int uc_insert (const data_set_t *ds, const value_list_t *vl,
const char *key)
{
- int i;
char *key_copy;
cache_entry_t *ce;
+ size_t i;
/* `cache_lock' has been locked by `uc_update' */
if (ce == NULL)
{
sfree (key_copy);
- ERROR ("uc_insert: cache_alloc (%i) failed.", ds->ds_num);
+ ERROR ("uc_insert: cache_alloc (%zu) failed.", ds->ds_num);
return (-1);
}
char name[6 * DATA_MAX_NAME_LEN];
cache_entry_t *ce = NULL;
int status;
- int i;
+ size_t i;
if (FORMAT_VL (name, sizeof (name), vl) != 0)
{
{
case DS_TYPE_COUNTER:
{
- counter_t diff;
-
- /* check if the counter has wrapped around */
- if (vl->values[i].counter < ce->values_raw[i].counter)
- {
- if (ce->values_raw[i].counter <= 4294967295U)
- diff = (4294967295U - ce->values_raw[i].counter)
- + vl->values[i].counter;
- else
- diff = (18446744073709551615ULL - ce->values_raw[i].counter)
- + vl->values[i].counter;
- }
- else /* counter has NOT wrapped around */
- {
- diff = vl->values[i].counter - ce->values_raw[i].counter;
- }
-
+ counter_t diff = counter_diff (ce->values_raw[i].counter, vl->values[i].counter);
ce->values_gauge[i] = ((double) diff)
/ (CDTIME_T_TO_DOUBLE (vl->time - ce->last_time));
ce->values_raw[i].counter = vl->values[i].counter;
case DS_TYPE_DERIVE:
{
- derive_t diff;
-
- diff = vl->values[i].derive - ce->values_raw[i].derive;
+ derive_t diff = vl->values[i].derive - ce->values_raw[i].derive;
ce->values_gauge[i] = ((double) diff)
/ (CDTIME_T_TO_DOUBLE (vl->time - ce->last_time));
return (-1);
} /* switch (ds->ds[i].type) */
- DEBUG ("uc_update: %s: ds[%i] = %lf", name, i, ce->values_gauge[i]);
+ DEBUG ("uc_update: %s: ds[%zu] = %lf", name, i, ce->values_gauge[i]);
} /* for (i) */
/* Update the history if it exists. */
* values are returned. */
if (ret_num != (size_t) ds->ds_num)
{
- ERROR ("utils_cache: uc_get_rate: ds[%s] has %i values, "
+ ERROR ("utils_cache: uc_get_rate: ds[%s] has %zu values, "
"but uc_get_rate_by_name returned %zu.",
ds->type, ds->ds_num, ret_num);
sfree (ret);
index 6c78d64dc86c01bc731ff5a09ed6688fd94a5587..37f21edb0f9023d1e3132999b75953e6e6cbec17 100644 (file)
#include "utils_cache.h"
-gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl)
+gauge_t *uc_get_rate (__attribute((unused)) data_set_t const *ds,
+ __attribute((unused)) value_list_t const *vl)
{
return (NULL);
}
index 2f28eb9b141fabbdaf452b227727dfa3f1b40bd5..43634df2d6a0a7ef4a8d586b6ea97f6522fb0205 100644 (file)
--- a/src/daemon/utils_subst.c
+++ b/src/daemon/utils_subst.c
#include "collectd.h"
#include "common.h"
-char *subst (char *buf, size_t buflen, const char *string, int off1, int off2,
+char *subst (char *buf, size_t buflen, const char *string, size_t off1, size_t off2,
const char *replacement)
{
- char *buf_ptr = buf;
- size_t len = buflen;
+ char *out = buf;
- if ((NULL == buf) || (0 >= buflen) || (NULL == string)
- || (0 > off1) || (0 > off2) || (off1 > off2)
- || (NULL == replacement))
+ char const *front;
+ char const *back;
+ size_t front_len;
+ size_t replacement_len;
+ size_t back_len;
+
+ if ((NULL == buf) || (0 == buflen) || (NULL == string) || (NULL == replacement))
return NULL;
- sstrncpy (buf_ptr, string,
- ((size_t)off1 + 1 > buflen) ? buflen : (size_t)off1 + 1);
- buf_ptr += off1;
- len -= off1;
+ size_t string_len = strlen (string);
+ if ((off1 > string_len) || (off2 > string_len) || (off1 > off2))
+ return NULL;
- if (0 >= len)
- return buf;
+ front = string;
+ back = string + off2;
+ front_len = off1;
+ replacement_len = strlen (replacement);
+ back_len = strlen (back);
+
+ if (front_len >= buflen) {
+ front_len = buflen - 1;
+ replacement_len = 0;
+ back_len = 0;
+ } else if ((front_len + replacement_len) >= buflen) {
+ replacement_len = buflen - (front_len + 1);
+ back_len = 0;
+ } else if ((front_len + replacement_len + back_len) >= buflen) {
+ back_len = buflen - (front_len + replacement_len + 1);
+ } else {
+ buflen = front_len + replacement_len + back_len + 1;
+ }
+ assert ((front_len + replacement_len + back_len) == (buflen - 1));
- sstrncpy (buf_ptr, replacement, len);
- buf_ptr += strlen (replacement);
- len -= strlen (replacement);
+ if (front_len != 0) {
+ sstrncpy (out, front, front_len + 1);
+ out += front_len;
+ }
- if (0 >= len)
- return buf;
+ if (replacement_len != 0) {
+ sstrncpy (out, replacement, replacement_len + 1);
+ out += replacement_len;
+ }
- sstrncpy (buf_ptr, string + off2, len);
+ if (back_len != 0) {
+ sstrncpy (out, back, back_len + 1);
+ out += back_len;
+ }
+
+ out[0] = 0;
return buf;
} /* subst */
char *subst_string (char *buf, size_t buflen, const char *string,
const char *needle, const char *replacement)
{
- char *temp;
size_t needle_len;
size_t i;
|| (needle == NULL) || (replacement == NULL))
return (NULL);
- temp = (char *) malloc (buflen);
- if (temp == NULL)
- {
- ERROR ("subst_string: malloc failed.");
- return (NULL);
- }
-
needle_len = strlen (needle);
- strncpy (buf, string, buflen);
+ sstrncpy (buf, string, buflen);
/* Limit the loop to prevent endless loops. */
for (i = 0; i < buflen; i++)
{
+ char temp[buflen];
char *begin_ptr;
size_t begin;
i, string, needle, replacement);
}
- sfree (temp);
return (buf);
} /* char *subst_string */
diff --git a/src/daemon/utils_subst_test.c b/src/daemon/utils_subst_test.c
--- /dev/null
@@ -0,0 +1,129 @@
+/**
+ * collectd - src/daemon/utils_subst_test.c
+ * Copyright (C) 2015 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>
+ */
+
+#include "testing.h"
+#include "collectd.h"
+#include "common.h" /* for STATIC_ARRAY_SIZE */
+#include "utils_subst.h"
+
+DEF_TEST(subst)
+{
+ struct {
+ char *str;
+ int off1;
+ int off2;
+ char *rplmt;
+ char *want;
+ } cases[] = {
+ {"foo_____bar", 3, 8, " - ", "foo - bar"}, /* documentation example */
+ {"foo bar", 0, 2, "m", "mo bar"}, /* beginning, shorten */
+ {"foo bar", 0, 1, "m", "moo bar"}, /* beginning, same length */
+ {"foo bar", 0, 3, "milk", "milk bar"}, /* beginning, extend */
+ {"foo bar", 3, 6, "de", "fooder"}, /* center, shorten */
+ {"foo bar", 2, 6, "rste", "forster"}, /* center, same length */
+ {"foo bar", 1, 3, "ish", "fish bar"}, /* center, extend */
+ {"foo bar", 2, 7, "ul", "foul"}, /* end, shorten */
+ {"foo bar", 3, 7, "lish", "foolish"}, /* end, same length */
+ {"foo bar", 3, 7, "dwear", "foodwear"}, /* end, extend */
+ /* truncation (buffer is 16 chars) */
+ {"01234567890123", 8, 8, "", "01234567890123"},
+ {"01234567890123", 8, 8, "*", "01234567*890123"},
+ {"01234567890123", 8, 8, "**", "01234567**89012"},
+ /* input > buffer */
+ {"012345678901234----", 0, 0, "", "012345678901234"},
+ {"012345678901234----", 17, 18, "", "012345678901234"},
+ {"012345678901234----", 0, 3, "", "345678901234---"},
+ {"012345678901234----", 0, 4, "", "45678901234----"},
+ {"012345678901234----", 0, 5, "", "5678901234----"},
+ {"012345678901234----", 8, 8, "#", "01234567#890123"},
+ {"012345678901234----", 12, 12, "##", "012345678901##2"},
+ {"012345678901234----", 13, 13, "##", "0123456789012##"},
+ {"012345678901234----", 14, 14, "##", "01234567890123#"},
+ {"012345678901234----", 15, 15, "##", "012345678901234"},
+ {"012345678901234----", 16, 16, "##", "012345678901234"},
+ /* error cases */
+ {NULL, 3, 4, "_", NULL}, /* no input */
+ {"foo bar", 3, 10, "_", NULL}, /* offset exceeds input */
+ {"foo bar", 10, 13, "_", NULL}, /* offset exceeds input */
+ {"foo bar", 4, 3, "_", NULL}, /* off1 > off2 */
+ {"foo bar", 3, 4, NULL, NULL}, /* no replacement */
+ };
+ size_t i;
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ char buffer[16] = "!!!!!!!!!!!!!!!";
+
+ if (cases[i].want == NULL) {
+ OK(subst (buffer, sizeof (buffer), cases[i].str, cases[i].off1, cases[i].off2, cases[i].rplmt) == NULL);
+ continue;
+ }
+
+ OK(subst (buffer, sizeof (buffer), cases[i].str, cases[i].off1, cases[i].off2, cases[i].rplmt) == &buffer[0]);
+ STREQ(cases[i].want, buffer);
+ }
+
+ return 0;
+}
+
+DEF_TEST(subst_string)
+{
+ struct {
+ char *str; char *srch; char *rplmt; char *want;
+ } cases[] = {
+ {"Hello %{name}", "%{name}", "world", "Hello world"},
+ {"abcccccc", "abc", "cab", "ccccccab"},
+ {"(((()(())))())", "()", "", ""},
+ {"food booth", "oo", "ee", "feed beeth"},
+ {"foo bar", "baz", "qux", "foo bar"},
+ {"foo bar", "oo", "oo", "foo bar"},
+ {"sixteen chars", "chars", "characters", "sixteen charact"},
+ };
+ size_t i;
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ char buffer[16];
+
+ if (cases[i].want == NULL) {
+ OK(subst_string (buffer, sizeof (buffer), cases[i].str, cases[i].srch, cases[i].rplmt) == NULL);
+ continue;
+ }
+
+ OK(subst_string (buffer, sizeof (buffer), cases[i].str, cases[i].srch, cases[i].rplmt) == buffer);
+ STREQ(cases[i].want, buffer);
+ }
+
+ return 0;
+}
+
+int main (void)
+{
+ RUN_TEST(subst);
+ RUN_TEST(subst_string);
+
+ END_TEST;
+}
+
+/* vim: set sw=2 sts=2 et : */
index 6603c15e89f161afc832a5e2cd8ef08b335564ea..5d905d9b7c2dbe9fad9fcf6e45ad027a0e56947b 100644 (file)
--- a/src/daemon/utils_time.c
+++ b/src/daemon/utils_time.c
if (max - len > 2) {
int n = snprintf (s + len, max - len, ".%09i", (int)t_spec.tv_nsec);
- len += (n < max - len) ? n : max - len;
+ len += (n < 0) ? 0
+ : (((size_t) n) < (max - len)) ? ((size_t) n)
+ : (max - len);
}
if (max - len > 3) {
- int n = strftime (s + len, max - len, "%z", &t_tm);
+ size_t n = strftime (s + len, max - len, "%z", &t_tm);
len += (n < max - len) ? n : max - len;
}
index 5edfe6f922a751c2df1a29a245cd83ad9e5c938f..217515ebd752e99c1b5a7cedac4c347ca7614394 100644 (file)
cdtime_t cdtime (void)
{
- return (0);
+ return ((cdtime_t) 1542455354518929408ULL);
}
diff --git a/src/dbi.c b/src/dbi.c
index a7963ea223371f5d70a4ef63f2d0a3a6263db22a..c851ba2b121dc272874e513a18eb26ea888178e7 100644 (file)
--- a/src/dbi.c
+++ b/src/dbi.c
while ((status == 0) && (db->queries_num > 0))
{
+ size_t j;
db->q_prep_areas = (udb_query_preparation_area_t **) calloc (
db->queries_num, sizeof (*db->q_prep_areas));
break;
}
- for (i = 0; i < db->queries_num; ++i)
+ for (j = 0; j < db->queries_num; ++j)
{
- db->q_prep_areas[i]
- = udb_query_allocate_preparation_area (db->queries[i]);
+ db->q_prep_areas[j]
+ = udb_query_allocate_preparation_area (db->queries[j]);
- if (db->q_prep_areas[i] == NULL)
+ if (db->q_prep_areas[j] == NULL)
{
WARNING ("dbi plugin: udb_query_allocate_preparation_area failed");
status = -1;
plugin_register_complex_read (/* group = */ NULL,
/* name = */ name ? name : db->name,
/* callback = */ cdbi_read_database,
- /* interval = */ NULL,
+ /* interval = */ 0,
/* user_data = */ &ud);
free (name);
}
diff --git a/src/email.c b/src/email.c
index 365af274d4274cb70d42215e04c11e2fb08c3851..1bf9addaea09631f005ec96af2e97c9fdd602a56 100644 (file)
--- a/src/email.c
+++ b/src/email.c
# include <pthread.h>
#endif
-#include <sys/socket.h>
#include <sys/un.h>
#include <sys/select.h>
diff --git a/src/gmond.c b/src/gmond.c
index 336fbb9468b8eeb6c1002fc79dea02136829390d..c778d48dceb9a1ff4848c72571107d8f87c63471 100644 (file)
--- a/src/gmond.c
+++ b/src/gmond.c
#if HAVE_PTHREAD_H
# include <pthread.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
#if HAVE_NETDB_H
# include <netdb.h>
#endif
struct metric_map_s
{
- char *ganglia_name;
- char *type;
- char *type_instance;
- char *ds_name;
- int ds_type;
- int ds_index;
+ char *ganglia_name;
+ char *type;
+ char *type_instance;
+ char *ds_name;
+ int ds_type;
+ size_t ds_index;
};
typedef struct metric_map_s metric_map_t;
return (NULL);
/* Look up the DS type and ds_index. */
- if ((map[i].ds_type < 0) || (map[i].ds_index < 0)) /* {{{ */
+ if (map[i].ds_type < 0) /* {{{ */
{
const data_set_t *ds;
}
else
{
- int j;
+ size_t j;
for (j = 0; j < ds->ds_num; j++)
if (strcasecmp (ds->ds[j].name, map[i].ds_name) == 0)
static int staging_entry_update (const char *host, const char *name, /* {{{ */
const char *type, const char *type_instance,
- int ds_index, int ds_type, value_t value)
+ size_t ds_index, int ds_type, value_t value)
{
const data_set_t *ds;
staging_entry_t *se;
if (ds->ds_num <= ds_index)
{
- ERROR ("gmond plugin: Invalid index %i: %s has only %i data source(s).",
+ ERROR ("gmond plugin: Invalid index %zu: %s has only %zu data source(s).",
ds_index, ds->type, ds->ds_num);
return (-1);
}
diff --git a/src/hddtemp.c b/src/hddtemp.c
index 82c158cab17180dc18a4d5e878d1704b60e081ce..3de18fd91354d166a58beff919d4b38e65e0fe33 100644 (file)
--- a/src/hddtemp.c
+++ b/src/hddtemp.c
#include "configfile.h"
# include <netdb.h>
-# include <sys/socket.h>
# include <netinet/in.h>
# include <netinet/tcp.h>
# include <libgen.h> /* for basename */
diff --git a/src/interface.c b/src/interface.c
index df8ffb46c34522ee5696b22a3409a687c37161e4..e17711e3105ae31ccd106576ede46b72dc5b48a4 100644 (file)
--- a/src/interface.c
+++ b/src/interface.c
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
/* One cannot include both. This sucks. */
#if HAVE_LINUX_IF_H
diff --git a/src/iptables.c b/src/iptables.c
index 606b24d9afdacfeda05ecd30a44f4976d674377a..806b7a457f76308c3226aa3255444e97eeda20d5 100644 (file)
--- a/src/iptables.c
+++ b/src/iptables.c
#include "plugin.h"
#include "configfile.h"
-#include <sys/socket.h>
-
#include <libiptc/libiptc.h>
#include <libiptc/libip6tc.h>
diff --git a/src/ipvs.c b/src/ipvs.c
index cbb554286bd08f292219ff91b8a81a601925638d..4345a46532237081bcd8ff075102e6d34635f4a7 100644 (file)
--- a/src/ipvs.c
+++ b/src/ipvs.c
#if HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif /* HAVE_ARPA_INET_H */
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif /* HAVE_SYS_SOCKET_H */
#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
(se->protocol == IPPROTO_TCP) ? "TCP" : "UDP",
ntohs (se->port));
- if ((0 > len) || (size <= len)) {
+ if ((0 > len) || (size <= ((size_t) len))) {
log_err ("plugin instance truncated: %s", pi);
return -1;
}
len = ssnprintf (ti, size, "%s_%u", inet_ntoa (addr),
ntohs (de->port));
- if ((0 > len) || (size <= len)) {
+ if ((0 > len) || (size <= ((size_t) len))) {
log_err ("type instance truncated: %s", ti);
return -1;
}
char pi[DATA_MAX_NAME_LEN];
- int i = 0;
+ size_t i;
if (0 != get_pi (se, pi, sizeof (pi)))
{
static int cipvs_read (void)
{
struct ip_vs_get_services *services = NULL;
- int i = 0;
+ size_t i;
if (sockfd < 0)
return (-1);
diff --git a/src/java.c b/src/java.c
index c74fe6c79de8fee4a3e80cd3a6fd7f15ea7dcb62..6b92f54e966f313e907514d17569aed104312f1c 100644 (file)
--- a/src/java.c
+++ b/src/java.c
jmethodID m_add;
jobject o_type;
jobject o_dataset;
- int i;
+ size_t i;
/* Look up the org/collectd/api/DataSet class */
c_dataset = (*jvm_env)->FindClass (jvm_env, "org/collectd/api/DataSet");
jmethodID m_valuelist_constructor;
jobject o_valuelist;
int status;
- int i;
+ size_t i;
/* First, create a new ValueList instance..
* Look up the class.. */
ud.free_func = cjni_callback_info_destroy;
plugin_register_complex_read (/* group = */ NULL, cbi->name, cjni_read,
- /* interval = */ NULL, &ud);
+ /* interval = */ 0, &ud);
(*jvm_env)->DeleteLocalRef (jvm_env, o_read);
index a97dc509e4d7ff7e94b491f28244ad9e9e1d10cc..eaee9c0f7cb0f411d199a1cfc8051212fe15fa84 100644 (file)
* beginning of the message. */
ptr = NULL;
errno = 0;
- res.status = strtol (buffer, &ptr, 0);
+ res.status = (int) strtol (buffer, &ptr, 0);
if ((errno != 0) || (ptr == &buffer[0]))
{
lcc_set_errno (c, errno);
index c390a1ce7cada8de9b029cb5d088de05ad0c8c3e..0539cd0c05266a9965ac522e4599b5fd5bf07bb4 100644 (file)
int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ */
{
- int if_index;
+ unsigned int if_index;
int status;
if ((srv == NULL) || (interface == NULL))
@@ -421,7 +421,7 @@ int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ *
memset (&mreq, 0, sizeof (mreq));
mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
mreq.imr_address.s_addr = ntohl (INADDR_ANY);
- mreq.imr_ifindex = if_index;
+ mreq.imr_ifindex = (int) if_index;
#else
struct ip_mreq mreq;
@@ -457,8 +457,8 @@ int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ *
/* else: Not a multicast interface. */
#if defined(SO_BINDTODEVICE)
- status = setsockopt (srv->fd, SOL_SOCKET, SO_BINDTODEVICE,
- interface, strlen (interface) + 1);
+ status = setsockopt (srv->fd, SOL_SOCKET, SO_BINDTODEVICE, interface,
+ (socklen_t) (strlen (interface) + 1));
if (status != 0)
return (-1);
#endif
index f422f5adcb905e1d2bb5abed011ba10424c779a6..d01c79dd3f164f5da66bf17b208c0af4d534164a 100644 (file)
--- a/src/liboconfig/oconfig.c
+++ b/src/liboconfig/oconfig.c
yyset_in (fh);
if (NULL == c_file) {
- int status;
-
status = snprintf (file, sizeof (file), "<fd#%d>", fileno (fh));
- if ((status < 0) || (status >= sizeof (file))) {
+ if ((status < 0) || (((size_t) status) >= sizeof (file))) {
c_file = "<unknown>";
}
else {
{
int i;
- ci_copy->values = (oconfig_value_t *) calloc (ci_orig->values_num,
- sizeof (*ci_copy->values));
+ ci_copy->values = (oconfig_value_t *) calloc ((size_t) ci_orig->values_num,
+ sizeof (*ci_copy->values));
if (ci_copy->values == NULL)
{
fprintf (stderr, "calloc failed.\n");
ci_copy->values[i].type = ci_orig->values[i].type;
if (ci_copy->values[i].type == OCONFIG_TYPE_STRING)
{
- ci_copy->values[i].value.string
- = strdup (ci_orig->values[i].value.string);
- if (ci_copy->values[i].value.string == NULL)
- {
- fprintf (stderr, "strdup failed.\n");
- oconfig_free (ci_copy);
- return (NULL);
- }
+ ci_copy->values[i].value.string = strdup (ci_orig->values[i].value.string);
+ if (ci_copy->values[i].value.string == NULL)
+ {
+ fprintf (stderr, "strdup failed.\n");
+ oconfig_free (ci_copy);
+ return (NULL);
+ }
}
else /* ci_copy->values[i].type != OCONFIG_TYPE_STRING) */
{
- ci_copy->values[i].value = ci_orig->values[i].value;
+ ci_copy->values[i].value = ci_orig->values[i].value;
}
}
} /* }}} if (ci_orig->values_num > 0) */
{
int i;
- ci_copy->children = (oconfig_item_t *) calloc (ci_orig->children_num,
- sizeof (*ci_copy->children));
+ ci_copy->children = (oconfig_item_t *) calloc ((size_t) ci_orig->children_num,
+ sizeof (*ci_copy->children));
if (ci_copy->children == NULL)
{
fprintf (stderr, "calloc failed.\n");
diff --git a/src/madwifi.c b/src/madwifi.c
index 13301fffe15aea8afbce76c3ce06105ededfa195..bb33b15d2c7818fe6cd3b623fd3fece4d1f47814 100644 (file)
--- a/src/madwifi.c
+++ b/src/madwifi.c
#include <dirent.h>
#include <sys/ioctl.h>
-#include <sys/socket.h>
#if !KERNEL_LINUX
# error "No applicable input method."
static inline int item_watched(int i)
{
assert (i >= 0);
- assert (i < ((STATIC_ARRAY_SIZE (watch_items) + 1) * 32));
+ assert (((size_t) i) < ((STATIC_ARRAY_SIZE (watch_items) + 1) * 32));
return watch_items[i / 32] & FLAG (i);
}
static inline int item_summed(int i)
{
assert (i >= 0);
- assert (i < ((STATIC_ARRAY_SIZE (misc_items) + 1) * 32));
+ assert (((size_t) i) < ((STATIC_ARRAY_SIZE (misc_items) + 1) * 32));
return misc_items[i / 32] & FLAG (i);
}
static int madwifi_real_init (void)
{
- int max = STATIC_ARRAY_SIZE (specs);
- int i;
+ size_t max = STATIC_ARRAY_SIZE (specs);
+ size_t i;
for (i = 0; i < STATIC_ARRAY_SIZE (bounds); i++)
bounds[i] = 0;
@@ -618,7 +617,7 @@ process_stat_struct (int which, const void *ptr, const char *dev, const char *ma
int i;
assert (which >= 1);
- assert (which < STATIC_ARRAY_SIZE (bounds));
+ assert (((size_t) which) < STATIC_ARRAY_SIZE (bounds));
for (i = bounds[which - 1]; i < bounds[which]; i++)
{
uint8_t buf[24*1024];
struct iwreq iwr;
uint8_t *cp;
- int len, nodes;
+ int nodes;
+ size_t len;
int status;
memset (&iwr, 0, sizeof (iwr));
index abde2b3495f818bf25b3188b4dadfd090210d6c9..e30ff91bc7f17e6a9983a9215e53497ea8c78794 100644 (file)
{
int num_counters;
int num_empty;
- int i;
+ size_t i;
if ((user_data == NULL) || (*user_data == NULL))
return (-1);
diff --git a/src/match_value.c b/src/match_value.c
index 4d49984f618173b48323634a3ed34a1b85cde048..9ffcecaae473b9bc24b49d721e5b2914ae4bcfbe 100644 (file)
--- a/src/match_value.c
+++ b/src/match_value.c
*/
static void mv_free_match (mv_match_t *m) /* {{{ */
{
- int i;
+ size_t i;
if (m == NULL)
return;
mv_match_t *m;
gauge_t *values;
int status;
- int i;
+ size_t i;
if ((user_data == NULL) || (*user_data == NULL))
return (-1);
diff --git a/src/mbmon.c b/src/mbmon.c
index d23062db2d54734551789c76cac837c9915c43f2..5e87f00b7087935786d695a6b37387df00901ce5 100644 (file)
--- a/src/mbmon.c
+++ b/src/mbmon.c
#include "configfile.h"
#include <netdb.h>
-#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
diff --git a/src/memcached.c b/src/memcached.c
index f6af4fc77c2019e3152f26af5aa77ac4b43cc26d..f684abffe9314515771d75cef1d1cd81143838ee 100644 (file)
--- a/src/memcached.c
+++ b/src/memcached.c
#include "configfile.h"
#include <netdb.h>
-#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
status = plugin_register_complex_read (/* group = */ "memcached",
/* name = */ callback_name,
/* callback = */ memcached_read,
- /* interval = */ NULL,
+ /* interval = */ 0,
/* user_data = */ &ud);
return (status);
} /* int memcached_add_read_callback */
diff --git a/src/modbus.c b/src/modbus.c
index 08871a25732f60ab7bc5ef9c67fe248a303ecd48..cfc6331e293218b4fdfaca1d99eadabae02754fa 100644 (file)
--- a/src/modbus.c
+++ b/src/modbus.c
if (ds->ds_num != 1)
{
- ERROR ("Modbus plugin: The type \"%s\" has %i data sources. "
+ 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);
{
user_data_t ud;
char name[1024];
- struct timespec interval = { 0, 0 };
ud.data = host;
ud.free_func = host_free;
ssnprintf (name, sizeof (name), "modbus-%s", host->host);
- CDTIME_T_TO_TIMESPEC (host->interval, &interval);
-
plugin_register_complex_read (/* group = */ NULL, name,
/* callback = */ mb_read,
- /* interval = */ (host->interval > 0) ? &interval : NULL,
+ /* interval = */ host->interval,
&ud);
}
else
diff --git a/src/mqtt.c b/src/mqtt.c
--- /dev/null
+++ b/src/mqtt.c
@@ -0,0 +1,734 @@
+/**
+ * collectd - src/mqtt.c
+ * Copyright (C) 2014 Marc Falzon
+ * Copyright (C) 2014,2015 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:
+ * Marc Falzon <marc at baha dot mu>
+ * Florian octo Forster <octo at collectd.org>
+ **/
+
+// Reference: http://mosquitto.org/api/files/mosquitto-h.html
+
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "utils_cache.h"
+#include "utils_complain.h"
+
+#include <pthread.h>
+
+#include <mosquitto.h>
+
+#define MQTT_MAX_TOPIC_SIZE 1024
+#define MQTT_MAX_MESSAGE_SIZE MQTT_MAX_TOPIC_SIZE + 1024
+#define MQTT_DEFAULT_HOST "localhost"
+#define MQTT_DEFAULT_PORT 1883
+#define MQTT_DEFAULT_TOPIC_PREFIX "collectd"
+#define MQTT_DEFAULT_TOPIC "collectd/#"
+#ifndef MQTT_KEEPALIVE
+# define MQTT_KEEPALIVE 60
+#endif
+
+
+/*
+ * Data types
+ */
+struct mqtt_client_conf
+{
+ _Bool publish;
+ char *name;
+
+ struct mosquitto *mosq;
+ _Bool connected;
+
+ char *host;
+ int port;
+ char *client_id;
+ char *username;
+ char *password;
+ int qos;
+
+ /* For publishing */
+ char *topic_prefix;
+ _Bool store_rates;
+ _Bool retain;
+
+ /* For subscribing */
+ pthread_t thread;
+ _Bool loop;
+ char *topic;
+ _Bool clean_session;
+
+ c_complain_t complaint_cantpublish;
+ pthread_mutex_t lock;
+};
+typedef struct mqtt_client_conf mqtt_client_conf_t;
+
+static mqtt_client_conf_t **subscribers = NULL;
+static size_t subscribers_num = 0;
+
+/*
+ * Functions
+ */
+#if LIBMOSQUITTO_MAJOR == 0
+static char const *mosquitto_strerror (int code)
+{
+ switch (code)
+ {
+ case MOSQ_ERR_SUCCESS: return "MOSQ_ERR_SUCCESS";
+ case MOSQ_ERR_NOMEM: return "MOSQ_ERR_NOMEM";
+ case MOSQ_ERR_PROTOCOL: return "MOSQ_ERR_PROTOCOL";
+ case MOSQ_ERR_INVAL: return "MOSQ_ERR_INVAL";
+ case MOSQ_ERR_NO_CONN: return "MOSQ_ERR_NO_CONN";
+ case MOSQ_ERR_CONN_REFUSED: return "MOSQ_ERR_CONN_REFUSED";
+ case MOSQ_ERR_NOT_FOUND: return "MOSQ_ERR_NOT_FOUND";
+ case MOSQ_ERR_CONN_LOST: return "MOSQ_ERR_CONN_LOST";
+ case MOSQ_ERR_SSL: return "MOSQ_ERR_SSL";
+ case MOSQ_ERR_PAYLOAD_SIZE: return "MOSQ_ERR_PAYLOAD_SIZE";
+ case MOSQ_ERR_NOT_SUPPORTED: return "MOSQ_ERR_NOT_SUPPORTED";
+ case MOSQ_ERR_AUTH: return "MOSQ_ERR_AUTH";
+ case MOSQ_ERR_ACL_DENIED: return "MOSQ_ERR_ACL_DENIED";
+ case MOSQ_ERR_UNKNOWN: return "MOSQ_ERR_UNKNOWN";
+ case MOSQ_ERR_ERRNO: return "MOSQ_ERR_ERRNO";
+ }
+
+ return "UNKNOWN ERROR CODE";
+}
+#else
+/* provided by libmosquitto */
+#endif
+
+static void mqtt_free (mqtt_client_conf_t *conf)
+{
+ if (conf == NULL)
+ return;
+
+ if (conf->connected)
+ (void) mosquitto_disconnect (conf->mosq);
+ conf->connected = 0;
+ (void) mosquitto_destroy (conf->mosq);
+
+ sfree (conf->host);
+ sfree (conf->username);
+ sfree (conf->password);
+ sfree (conf->client_id);
+ sfree (conf->topic_prefix);
+ sfree (conf);
+}
+
+static char *strip_prefix (char *topic)
+{
+ size_t num;
+ size_t i;
+
+ num = 0;
+ for (i = 0; topic[i] != 0; i++)
+ if (topic[i] == '/')
+ num++;
+
+ if (num < 2)
+ return (NULL);
+
+ while (num > 2)
+ {
+ char *tmp = strchr (topic, '/');
+ if (tmp == NULL)
+ return (NULL);
+ topic = tmp + 1;
+ num--;
+ }
+
+ return (topic);
+}
+
+static void on_message (
+#if LIBMOSQUITTO_MAJOR == 0
+#else
+ __attribute__((unused)) struct mosquitto *m,
+#endif
+ __attribute__((unused)) void *arg,
+ const struct mosquitto_message *msg)
+{
+ value_list_t vl = VALUE_LIST_INIT;
+ data_set_t const *ds;
+ char *topic;
+ char *name;
+ char *payload;
+ int status;
+
+ if ((msg->payloadlen <= 0)
+ || (((uint8_t *) msg->payload)[msg->payloadlen - 1] != 0))
+ return;
+
+ topic = strdup (msg->topic);
+ name = strip_prefix (topic);
+
+ status = parse_identifier_vl (name, &vl);
+ if (status != 0)
+ {
+ ERROR ("mqtt plugin: Unable to parse topic \"%s\".", topic);
+ sfree (topic);
+ return;
+ }
+ sfree (topic);
+
+ ds = plugin_get_ds (vl.type);
+ if (ds == NULL)
+ {
+ ERROR ("mqtt plugin: Unknown type: \"%s\".", vl.type);
+ return;
+ }
+
+ vl.values = calloc (ds->ds_num, sizeof (*vl.values));
+ if (vl.values == NULL)
+ {
+ ERROR ("mqtt plugin: calloc failed.");
+ return;
+ }
+ vl.values_len = ds->ds_num;
+
+ payload = strdup ((void *) msg->payload);
+ DEBUG ("mqtt plugin: payload = \"%s\"", payload);
+ status = parse_values (payload, &vl, ds);
+ if (status != 0)
+ {
+ ERROR ("mqtt plugin: Unable to parse payload \"%s\".", payload);
+ sfree (payload);
+ sfree (vl.values);
+ return;
+ }
+ sfree (payload);
+
+ plugin_dispatch_values (&vl);
+ sfree (vl.values);
+} /* void on_message */
+
+/* must hold conf->lock when calling. */
+static int mqtt_reconnect (mqtt_client_conf_t *conf)
+{
+ int status;
+
+ if (conf->connected)
+ return (0);
+
+ status = mosquitto_reconnect (conf->mosq);
+ if (status != MOSQ_ERR_SUCCESS)
+ {
+ char errbuf[1024];
+ ERROR ("mqtt_connect_broker: mosquitto_connect failed: %s",
+ (status == MOSQ_ERR_ERRNO)
+ ? sstrerror(errno, errbuf, sizeof (errbuf))
+ : mosquitto_strerror (status));
+ return (-1);
+ }
+
+ conf->connected = 1;
+
+ c_release (LOG_INFO,
+ &conf->complaint_cantpublish,
+ "mqtt plugin: successfully reconnected to broker \"%s:%d\"",
+ conf->host, conf->port);
+
+ return (0);
+} /* mqtt_reconnect */
+
+/* must hold conf->lock when calling. */
+static int mqtt_connect (mqtt_client_conf_t *conf)
+{
+ char const *client_id;
+ int status;
+
+ if (conf->mosq != NULL)
+ return mqtt_reconnect (conf);
+
+ if (conf->client_id)
+ client_id = conf->client_id;
+ else
+ client_id = hostname_g;
+
+#if LIBMOSQUITTO_MAJOR == 0
+ conf->mosq = mosquitto_new (client_id, /* user data = */ conf);
+#else
+ conf->mosq = mosquitto_new (client_id, conf->clean_session, /* user data = */ conf);
+#endif
+ if (conf->mosq == NULL)
+ {
+ ERROR ("mqtt plugin: mosquitto_new failed");
+ return (-1);
+ }
+
+ if (conf->username && conf->password)
+ {
+ status = mosquitto_username_pw_set (conf->mosq, conf->username, conf->password);
+ if (status != MOSQ_ERR_SUCCESS)
+ {
+ char errbuf[1024];
+ ERROR ("mqtt plugin: mosquitto_username_pw_set failed: %s",
+ (status == MOSQ_ERR_ERRNO)
+ ? sstrerror (errno, errbuf, sizeof (errbuf))
+ : mosquitto_strerror (status));
+
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ return (-1);
+ }
+ }
+
+#if LIBMOSQUITTO_MAJOR == 0
+ status = mosquitto_connect (conf->mosq, conf->host, conf->port,
+ /* keepalive = */ MQTT_KEEPALIVE, /* clean session = */ conf->clean_session);
+#else
+ status = mosquitto_connect (conf->mosq, conf->host, conf->port, MQTT_KEEPALIVE);
+#endif
+ if (status != MOSQ_ERR_SUCCESS)
+ {
+ char errbuf[1024];
+ ERROR ("mqtt plugin: mosquitto_connect failed: %s",
+ (status == MOSQ_ERR_ERRNO)
+ ? sstrerror (errno, errbuf, sizeof (errbuf))
+ : mosquitto_strerror (status));
+
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ return (-1);
+ }
+
+ if (!conf->publish)
+ {
+ mosquitto_message_callback_set (conf->mosq, on_message);
+
+ status = mosquitto_subscribe (conf->mosq,
+ /* message_id = */ NULL,
+ conf->topic, conf->qos);
+ if (status != MOSQ_ERR_SUCCESS)
+ {
+ ERROR ("mqtt plugin: Subscribing to \"%s\" failed: %s",
+ conf->topic, mosquitto_strerror (status));
+
+ mosquitto_disconnect (conf->mosq);
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ return (-1);
+ }
+ }
+
+ conf->connected = 1;
+ return (0);
+} /* mqtt_connect */
+
+static void *subscribers_thread (void *arg)
+{
+ mqtt_client_conf_t *conf = arg;
+ int status;
+
+ conf->loop = 1;
+
+ while (conf->loop)
+ {
+ status = mqtt_connect (conf);
+ if (status != 0)
+ {
+ sleep (1);
+ continue;
+ }
+
+ /* The documentation says "0" would map to the default (1000ms), but
+ * that does not work on some versions. */
+#if LIBMOSQUITTO_MAJOR == 0
+ status = mosquitto_loop (conf->mosq, /* timeout = */ 1000 /* ms */);
+#else
+ status = mosquitto_loop (conf->mosq,
+ /* timeout[ms] = */ 1000,
+ /* max_packets = */ 100);
+#endif
+ if (status == MOSQ_ERR_CONN_LOST)
+ {
+ conf->connected = 0;
+ continue;
+ }
+ else if (status != MOSQ_ERR_SUCCESS)
+ {
+ ERROR ("mqtt plugin: mosquitto_loop failed: %s",
+ mosquitto_strerror (status));
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ conf->connected = 0;
+ continue;
+ }
+
+ DEBUG ("mqtt plugin: mosquitto_loop succeeded.");
+ } /* while (conf->loop) */
+
+ pthread_exit (0);
+} /* void *subscribers_thread */
+
+static int publish (mqtt_client_conf_t *conf, char const *topic,
+ void const *payload, size_t payload_len)
+{
+ int status;
+
+ pthread_mutex_lock (&conf->lock);
+
+ status = mqtt_connect (conf);
+ if (status != 0) {
+ pthread_mutex_unlock (&conf->lock);
+ ERROR ("mqtt plugin: unable to reconnect to broker");
+ return (status);
+ }
+
+ status = mosquitto_publish(conf->mosq, /* message_id */ NULL, topic,
+#if LIBMOSQUITTO_MAJOR == 0
+ (uint32_t) payload_len, payload,
+#else
+ (int) payload_len, payload,
+#endif
+ conf->qos, conf->retain);
+ if (status != MOSQ_ERR_SUCCESS)
+ {
+ char errbuf[1024];
+ c_complain (LOG_ERR,
+ &conf->complaint_cantpublish,
+ "plugin mqtt: mosquitto_publish failed: %s",
+ status == MOSQ_ERR_ERRNO ?
+ sstrerror(errno, errbuf, sizeof (errbuf)) :
+ mosquitto_strerror(status));
+ /* Mark our connection "down" regardless of the error as a safety
+ * measure; we will try to reconnect the next time we have to publish a
+ * message */
+ conf->connected = 0;
+
+ pthread_mutex_unlock (&conf->lock);
+ return (-1);
+ }
+
+ pthread_mutex_unlock (&conf->lock);
+ return (0);
+} /* int publish */
+
+static int format_topic (char *buf, size_t buf_len,
+ data_set_t const *ds, value_list_t const *vl,
+ mqtt_client_conf_t *conf)
+{
+ char name[MQTT_MAX_TOPIC_SIZE];
+ int status;
+
+ if ((conf->topic_prefix == NULL) || (conf->topic_prefix[0] == 0))
+ return (FORMAT_VL (buf, buf_len, vl));
+
+ status = FORMAT_VL (name, sizeof (name), vl);
+ if (status != 0)
+ return (status);
+
+ status = ssnprintf (buf, buf_len, "%s/%s", conf->topic_prefix, name);
+ if ((status < 0) || (((size_t) status) >= buf_len))
+ return (ENOMEM);
+
+ return (0);
+} /* int format_topic */
+
+static int mqtt_write (const data_set_t *ds, const value_list_t *vl,
+ user_data_t *user_data)
+{
+ mqtt_client_conf_t *conf;
+ char topic[MQTT_MAX_TOPIC_SIZE];
+ char payload[MQTT_MAX_MESSAGE_SIZE];
+ int status = 0;
+
+ if ((user_data == NULL) || (user_data->data == NULL))
+ 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);
+ }
+
+ 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);
+ }
+
+ status = publish (conf, topic, payload, strlen (payload) + 1);
+ if (status != 0)
+ {
+ ERROR ("mqtt plugin: publish failed: %s", mosquitto_strerror (status));
+ return (status);
+ }
+
+ return (status);
+} /* mqtt_write */
+
+/*
+ * <Publish "name">
+ * Host "example.com"
+ * Port 1883
+ * ClientId "collectd"
+ * User "guest"
+ * Password "secret"
+ * Prefix "collectd"
+ * StoreRates true
+ * Retain false
+ * QoS 0
+ * </Publish>
+ */
+static int mqtt_config_publisher (oconfig_item_t *ci)
+{
+ mqtt_client_conf_t *conf;
+ char cb_name[1024];
+ user_data_t user_data;
+ int status;
+ int i;
+
+ conf = calloc (1, sizeof (*conf));
+ if (conf == NULL)
+ {
+ ERROR ("mqtt plugin: malloc failed.");
+ return (-1);
+ }
+ conf->publish = 1;
+
+ conf->name = NULL;
+ status = cf_util_get_string (ci, &conf->name);
+ if (status != 0)
+ {
+ mqtt_free (conf);
+ return (status);
+ }
+
+ conf->host = strdup (MQTT_DEFAULT_HOST);
+ conf->port = MQTT_DEFAULT_PORT;
+ conf->client_id = NULL;
+ conf->qos = 0;
+ conf->topic_prefix = strdup (MQTT_DEFAULT_TOPIC_PREFIX);
+ conf->store_rates = 1;
+
+ C_COMPLAIN_INIT (&conf->complaint_cantpublish);
+
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child = ci->children + i;
+ if (strcasecmp ("Host", child->key) == 0)
+ cf_util_get_string (child, &conf->host);
+ else if (strcasecmp ("Port", child->key) == 0)
+ {
+ int tmp = cf_util_get_port_number (child);
+ if (tmp < 0)
+ ERROR ("mqtt plugin: Invalid port number.");
+ else
+ conf->port = tmp;
+ }
+ else if (strcasecmp ("ClientId", child->key) == 0)
+ cf_util_get_string (child, &conf->client_id);
+ else if (strcasecmp ("User", child->key) == 0)
+ cf_util_get_string (child, &conf->username);
+ else if (strcasecmp ("Password", child->key) == 0)
+ cf_util_get_string (child, &conf->password);
+ else if (strcasecmp ("QoS", child->key) == 0)
+ {
+ int tmp = -1;
+ status = cf_util_get_int (child, &tmp);
+ if ((status != 0) || (tmp < 0) || (tmp > 2))
+ ERROR ("mqtt plugin: Not a valid QoS setting.");
+ else
+ conf->qos = tmp;
+ }
+ else if (strcasecmp ("Prefix", child->key) == 0)
+ cf_util_get_string (child, &conf->topic_prefix);
+ else if (strcasecmp ("StoreRates", child->key) == 0)
+ cf_util_get_boolean (child, &conf->store_rates);
+ else if (strcasecmp ("Retain", child->key) == 0)
+ cf_util_get_boolean (child, &conf->retain);
+ else
+ ERROR ("mqtt plugin: Unknown config option: %s", child->key);
+ }
+
+ ssnprintf (cb_name, sizeof (cb_name), "mqtt/%s", conf->name);
+ memset (&user_data, 0, sizeof (user_data));
+ user_data.data = conf;
+
+ plugin_register_write (cb_name, mqtt_write, &user_data);
+ return (0);
+} /* mqtt_config_publisher */
+
+/*
+ * <Subscribe "name">
+ * Host "example.com"
+ * Port 1883
+ * ClientId "collectd"
+ * User "guest"
+ * Password "secret"
+ * Topic "collectd/#"
+ * </Publish>
+ */
+static int mqtt_config_subscriber (oconfig_item_t *ci)
+{
+ mqtt_client_conf_t **tmp;
+ mqtt_client_conf_t *conf;
+ int status;
+ int i;
+
+ conf = calloc (1, sizeof (*conf));
+ if (conf == NULL)
+ {
+ ERROR ("mqtt plugin: malloc failed.");
+ return (-1);
+ }
+ conf->publish = 0;
+
+ conf->name = NULL;
+ status = cf_util_get_string (ci, &conf->name);
+ if (status != 0)
+ {
+ mqtt_free (conf);
+ return (status);
+ }
+
+ conf->host = strdup (MQTT_DEFAULT_HOST);
+ conf->port = MQTT_DEFAULT_PORT;
+ conf->client_id = NULL;
+ conf->qos = 2;
+ conf->topic = strdup (MQTT_DEFAULT_TOPIC);
+ conf->clean_session = 1;
+
+ C_COMPLAIN_INIT (&conf->complaint_cantpublish);
+
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child = ci->children + i;
+ if (strcasecmp ("Host", child->key) == 0)
+ cf_util_get_string (child, &conf->host);
+ else if (strcasecmp ("Port", child->key) == 0)
+ {
+ int tmp = cf_util_get_port_number (child);
+ if (tmp < 0)
+ ERROR ("mqtt plugin: Invalid port number.");
+ else
+ conf->port = tmp;
+ }
+ else if (strcasecmp ("ClientId", child->key) == 0)
+ cf_util_get_string (child, &conf->client_id);
+ else if (strcasecmp ("User", child->key) == 0)
+ cf_util_get_string (child, &conf->username);
+ else if (strcasecmp ("Password", child->key) == 0)
+ cf_util_get_string (child, &conf->password);
+ else if (strcasecmp ("QoS", child->key) == 0)
+ {
+ int tmp = -1;
+ status = cf_util_get_int (child, &tmp);
+ if ((status != 0) || (tmp < 0) || (tmp > 2))
+ ERROR ("mqtt plugin: Not a valid QoS setting.");
+ else
+ conf->qos = tmp;
+ }
+ else if (strcasecmp ("Topic", child->key) == 0)
+ cf_util_get_string (child, &conf->topic);
+ else if (strcasecmp ("CleanSession", child->key) == 0)
+ cf_util_get_boolean (child, &conf->clean_session);
+ else
+ ERROR ("mqtt plugin: Unknown config option: %s", child->key);
+ }
+
+ tmp = realloc (subscribers, sizeof (*subscribers) * subscribers_num);
+ if (tmp == NULL)
+ {
+ ERROR ("mqtt plugin: realloc failed.");
+ mqtt_free (conf);
+ return (-1);
+ }
+ subscribers = tmp;
+ subscribers[subscribers_num] = conf;
+ subscribers_num++;
+
+ return (0);
+} /* mqtt_config_subscriber */
+
+/*
+ * <Plugin mqtt>
+ * <Publish "name">
+ * # ...
+ * </Publish>
+ * <Subscribe "name">
+ * # ...
+ * </Subscribe>
+ * </Plugin>
+ */
+static int mqtt_config (oconfig_item_t *ci)
+{
+ int i;
+
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp ("Publish", child->key) == 0)
+ mqtt_config_publisher (child);
+ else if (strcasecmp ("Subscribe", child->key) == 0)
+ mqtt_config_subscriber (child);
+ else
+ ERROR ("mqtt plugin: Unknown config option: %s", child->key);
+ }
+
+ return (0);
+} /* int mqtt_config */
+
+static int mqtt_init (void)
+{
+ size_t i;
+
+ mosquitto_lib_init ();
+
+ for (i = 0; i < subscribers_num; i++)
+ {
+ int status;
+
+ if (subscribers[i]->loop)
+ continue;
+
+ status = plugin_thread_create (&subscribers[i]->thread,
+ /* attrs = */ NULL,
+ /* func = */ subscribers_thread,
+ /* args = */ subscribers[i]);
+ if (status != 0)
+ {
+ char errbuf[1024];
+ ERROR ("mqtt plugin: pthread_create failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ continue;
+ }
+ }
+
+ 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 : */
diff --git a/src/mysql.c b/src/mysql.c
index eaa03719c5216b23ba316273af40aa654bc891e3..a8a8e86d906f79572754dab09a7af08931078a03 100644 (file)
--- a/src/mysql.c
+++ b/src/mysql.c
plugin_register_complex_read (/* group = */ NULL, cb_name,
mysql_read,
- /* interval = */ NULL, &ud);
+ /* interval = */ 0, &ud);
}
else
{
diff --git a/src/netapp.c b/src/netapp.c
index f446d597de1f27610b0be1c7e2cfde8957509a79..020bfba192baffad8eb59661c464aaaf77bc585c 100644 (file)
--- a/src/netapp.c
+++ b/src/netapp.c
static int cna_register_host (host_config_t *host) /* {{{ */
{
char cb_name[256];
- struct timespec interval;
user_data_t ud;
if (host->vfiler)
else
ssnprintf (cb_name, sizeof (cb_name), "netapp-%s", host->name);
- CDTIME_T_TO_TIMESPEC (host->interval, &interval);
-
memset (&ud, 0, sizeof (ud));
ud.data = host;
ud.free_func = (void (*) (void *)) free_host_config;
plugin_register_complex_read (/* group = */ NULL, cb_name,
/* callback = */ cna_read,
- /* interval = */ (host->interval > 0) ? &interval : NULL,
+ /* interval = */ host->interval,
/* user data = */ &ud);
return (0);
diff --git a/src/netlink.c b/src/netlink.c
index aa9760f9328b78eb87e14f70501bc1622a57f12d..e1f378d9408a741a6e75c85efe62ee5a80426028 100644 (file)
--- a/src/netlink.c
+++ b/src/netlink.c
#include "common.h"
#include <asm/types.h>
-#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
diff --git a/src/network.c b/src/network.c
index af24911ee365b1ae512000cce93103ffdaf86a94..916900065aff9241a99454ab86cd2bf675655d8f 100644 (file)
--- a/src/network.c
+++ b/src/network.c
#if HAVE_PTHREAD_H
# include <pthread.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
#if HAVE_NETDB_H
# include <netdb.h>
#endif
static int network_config_ttl = 0;
/* Ethernet - (IPv6 + UDP) = 1500 - (40 + 8) = 1452 */
static size_t network_config_packet_size = 1452;
-static int network_config_forward = 0;
-static int network_config_stats = 0;
+static _Bool network_config_forward = 0;
+static _Bool network_config_stats = 0;
static sockent_t *sending_sockets = NULL;
static char *send_buffer;
static char *send_buffer_ptr;
static int send_buffer_fill;
+static cdtime_t send_buffer_last_update;
static value_list_t send_buffer_vl = VALUE_LIST_STATIC;
static pthread_mutex_t send_buffer_lock = PTHREAD_MUTEX_INITIALIZER;
_Bool received = 0;
int status;
- if (network_config_forward != 0)
+ if (network_config_forward)
return (1);
if (vl->meta == NULL)
} /* int write_part_string */
static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len,
- value_t **ret_values, int *ret_num_values)
+ value_t **ret_values, size_t *ret_num_values)
{
char *buffer = *ret_buffer;
size_t buffer_len = *ret_buffer_len;
*ret_buffer = buffer;
*ret_buffer_len = buffer_len - pkg_length;
- *ret_num_values = pkg_numval;
+ *ret_num_values = (size_t) pkg_numval;
*ret_values = pkg_values;
sfree (pkg_types);
char buffer[network_config_packet_size];
int buffer_len;
- int i;
+ size_t i;
int status = 0;
receive_list_entry_t *private_list_head;
memset (send_buffer, 0, network_config_packet_size);
send_buffer_ptr = send_buffer;
send_buffer_fill = 0;
+ send_buffer_last_update = 0;
memset (&send_buffer_vl, 0, sizeof (send_buffer_vl));
} /* int network_init_buffer */
/* status == bytes added to the buffer */
send_buffer_fill += status;
send_buffer_ptr += status;
+ send_buffer_last_update = cdtime();
stats_values_sent++;
}
return ((status < 0) ? -1 : 0);
} /* int network_write */
-static int network_config_set_boolean (const oconfig_item_t *ci, /* {{{ */
- int *retval)
-{
- if ((ci->values_num != 1)
- || ((ci->values[0].type != OCONFIG_TYPE_BOOLEAN)
- && (ci->values[0].type != OCONFIG_TYPE_STRING)))
- {
- ERROR ("network plugin: The `%s' config option needs "
- "exactly one boolean argument.", ci->key);
- return (-1);
- }
-
- if (ci->values[0].type == OCONFIG_TYPE_BOOLEAN)
- {
- if (ci->values[0].value.boolean)
- *retval = 1;
- else
- *retval = 0;
- }
- else
- {
- char *str = ci->values[0].value.string;
-
- if (IS_TRUE (str))
- *retval = 1;
- else if (IS_FALSE (str))
- *retval = 0;
- else
- {
- ERROR ("network plugin: Cannot parse string value `%s' of the `%s' "
- "option as boolean value.",
- str, ci->key);
- return (-1);
- }
- }
-
- return (0);
-} /* }}} int network_config_set_boolean */
-
static int network_config_set_ttl (const oconfig_item_t *ci) /* {{{ */
{
- int tmp;
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
- {
- WARNING ("network plugin: The `TimeToLive' config option needs exactly "
- "one numeric argument.");
- return (-1);
- }
+ int tmp = 0;
- tmp = (int) ci->values[0].value.number;
- if ((tmp > 0) && (tmp <= 255))
+ if (cf_util_get_int (ci, &tmp) != 0)
+ return (-1);
+ else if ((tmp > 0) && (tmp <= 255))
network_config_ttl = tmp;
else {
WARNING ("network plugin: The `TimeToLive' must be between 1 and 255.");
static int network_config_set_interface (const oconfig_item_t *ci, /* {{{ */
int *interface)
{
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("network plugin: The `Interface' config option needs exactly "
- "one string argument.");
- return (-1);
- }
+ char if_name[256];
- if (interface == NULL)
+ if (cf_util_get_string_buffer (ci, if_name, sizeof (if_name)) != 0)
return (-1);
- *interface = if_nametoindex (ci->values[0].value.string);
-
+ *interface = if_nametoindex (if_name);
return (0);
} /* }}} int network_config_set_interface */
static int network_config_set_buffer_size (const oconfig_item_t *ci) /* {{{ */
{
- int tmp;
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
- {
- WARNING ("network plugin: The `MaxPacketSize' config option needs exactly "
- "one numeric argument.");
- return (-1);
- }
+ int tmp = 0;
- tmp = (int) ci->values[0].value.number;
- if ((tmp >= 1024) && (tmp <= 65535))
+ if (cf_util_get_int (ci, &tmp) != 0)
+ return (-1);
+ else if ((tmp >= 1024) && (tmp <= 65535))
network_config_packet_size = tmp;
-
- return (0);
-} /* }}} int network_config_set_buffer_size */
-
-#if HAVE_LIBGCRYPT
-static int network_config_set_string (const oconfig_item_t *ci, /* {{{ */
- char **ret_string)
-{
- char *tmp;
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("network plugin: The `%s' config option needs exactly "
- "one string argument.", ci->key);
+ else {
+ WARNING ("network plugin: The `MaxPacketSize' must be between 1024 and 65535.");
return (-1);
}
- tmp = strdup (ci->values[0].value.string);
- if (tmp == NULL)
- return (-1);
-
- sfree (*ret_string);
- *ret_string = tmp;
-
return (0);
-} /* }}} int network_config_set_string */
-#endif /* HAVE_LIBGCRYPT */
+} /* }}} int network_config_set_buffer_size */
#if HAVE_LIBGCRYPT
static int network_config_set_security_level (oconfig_item_t *ci, /* {{{ */
#if HAVE_LIBGCRYPT
if (strcasecmp ("AuthFile", child->key) == 0)
- network_config_set_string (child, &se->data.server.auth_file);
+ 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 */
if (strcasecmp ("Interface", child->key) == 0)
- network_config_set_interface (child,
- &se->interface);
+ network_config_set_interface (child, &se->interface);
else
{
WARNING ("network plugin: Option `%s' is not allowed here.",
status = sockent_server_listen (se);
if (status != 0)
{
- ERROR ("network plugin: network_config_add_server: sockent_server_listen failed.");
+ ERROR ("network plugin: network_config_add_listen: sockent_server_listen failed.");
sockent_destroy (se);
return (-1);
}
#if HAVE_LIBGCRYPT
if (strcasecmp ("Username", child->key) == 0)
- network_config_set_string (child, &se->data.client.username);
+ cf_util_get_string (child, &se->data.client.username);
else if (strcasecmp ("Password", child->key) == 0)
- network_config_set_string (child, &se->data.client.password);
+ cf_util_get_string (child, &se->data.client.password);
else if (strcasecmp ("SecurityLevel", child->key) == 0)
network_config_set_security_level (child,
&se->data.client.security_level);
else
#endif /* HAVE_LIBGCRYPT */
if (strcasecmp ("Interface", child->key) == 0)
- network_config_set_interface (child,
- &se->interface);
- else if (strcasecmp ("ResolveInterval", child->key) == 0)
- cf_util_get_cdtime(child, &se->data.client.resolve_interval);
+ network_config_set_interface (child, &se->interface);
+ else if (strcasecmp ("ResolveInterval", child->key) == 0)
+ cf_util_get_cdtime(child, &se->data.client.resolve_interval);
else
{
WARNING ("network plugin: Option `%s' is not allowed here.",
else if (strcasecmp ("MaxPacketSize", child->key) == 0)
network_config_set_buffer_size (child);
else if (strcasecmp ("Forward", child->key) == 0)
- network_config_set_boolean (child, &network_config_forward);
+ cf_util_get_boolean (child, &network_config_forward);
else if (strcasecmp ("ReportStats", child->key) == 0)
- network_config_set_boolean (child, &network_config_stats);
+ cf_util_get_boolean (child, &network_config_stats);
else
{
WARNING ("network plugin: Option `%s' is not allowed here.",
network_init_gcrypt ();
#endif
- if (network_config_stats != 0)
+ if (network_config_stats)
plugin_register_read ("network", network_stats_read);
plugin_register_shutdown ("network", network_shutdown);
* just send the buffer if `flush' is called - if the requested value was in
* there, good. If not, well, then there is nothing to flush.. -octo
*/
-static int network_flush (__attribute__((unused)) cdtime_t timeout,
+static int network_flush (cdtime_t timeout,
__attribute__((unused)) const char *identifier,
__attribute__((unused)) user_data_t *user_data)
{
pthread_mutex_lock (&send_buffer_lock);
if (send_buffer_fill > 0)
- flush_buffer ();
-
+ {
+ if (timeout > 0)
+ {
+ cdtime_t now = cdtime ();
+ if ((send_buffer_last_update + timeout) > now)
+ {
+ pthread_mutex_unlock (&send_buffer_lock);
+ return (0);
+ }
+ }
+ flush_buffer ();
+ }
pthread_mutex_unlock (&send_buffer_lock);
return (0);
diff --git a/src/ntpd.c b/src/ntpd.c
index 5fdfef3f0db415c0bae5634ac69b5af64e31518f..dbde6609f64527ff8d58c91a4e9fda5f53e226e6 100644 (file)
--- a/src/ntpd.c
+++ b/src/ntpd.c
#if HAVE_NETDB_H
# include <netdb.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
"JJY", "TT_IRIG", "GPS_ZYFER", "GPS_RIPENCC", /* 40-43 */
"NEOCLK4X" /* 44 */
};
-static int refclock_names_num = STATIC_ARRAY_SIZE (refclock_names);
+static size_t refclock_names_num = STATIC_ARRAY_SIZE (refclock_names);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* End of the copied stuff.. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
uint32_t refclock_id = ntpd_get_refclock_id (peer_info);
uint32_t unit_id = ntohl (peer_info->srcadr) & 0x00FF;
- if (refclock_id >= refclock_names_num)
+ if (((size_t) refclock_id) >= refclock_names_num)
return (ntpd_get_name_from_address (buffer, buffer_size,
peer_info,
/* do_reverse_lookup = */ 0));
diff --git a/src/olsrd.c b/src/olsrd.c
index 6d0576cf7bc7d26e39567646f40fa1ebd49262cc..bbf387f4123dfe12a375ca85b234fd315843e385 100644 (file)
--- a/src/olsrd.c
+++ b/src/olsrd.c
#include <sys/types.h>
#include <netdb.h>
-#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
diff --git a/src/onewire.c b/src/onewire.c
index 51e6407137b0f2c8bc64598f822cac804c5a9fab..58c35e1eb83be009b342fbfbb7af8f2a7642cb2b 100644 (file)
--- a/src/onewire.c
+++ b/src/onewire.c
static int cow_init (void)
{
int status;
- struct timespec cb_interval;
if (device_g == NULL)
{
return (1);
}
- CDTIME_T_TO_TIMESPEC (ow_interval, &cb_interval);
-
plugin_register_complex_read (/* group = */ NULL, "onewire", cow_read,
- (ow_interval != 0) ? &cb_interval : NULL,
- /* user data = */ NULL);
+ ow_interval, /* user data = */ NULL);
plugin_register_shutdown ("onewire", cow_shutdown);
return (0);
diff --git a/src/openldap.c b/src/openldap.c
index 8667058ed049b164d7e496f37917253e55adcf14..ffcdb94e8049000961cd19bc65a167387532f9c0 100644 (file)
--- a/src/openldap.c
+++ b/src/openldap.c
{
char *name;
+ char *binddn;
+ char *password;
char *cacert;
char *host;
int state;
if (st == NULL)
return;
+ sfree (st->binddn);
+ sfree (st->password);
sfree (st->cacert);
sfree (st->host);
sfree (st->name);
}
struct berval cred;
- cred.bv_val = "";
- cred.bv_len = 0;
+ if (st->password != NULL)
+ {
+ cred.bv_val = st->password;
+ cred.bv_len = strlen (st->password);
+ }
+ else
+ {
+ cred.bv_val = "";
+ cred.bv_len = 0;
+ }
- rc = ldap_sasl_bind_s (st->ld, NULL, NULL, &cred, NULL, NULL, NULL);
+ rc = ldap_sasl_bind_s (st->ld, st->binddn, LDAP_SASL_SIMPLE, &cred,
+ NULL, NULL, NULL);
if (rc != LDAP_SUCCESS)
{
ERROR ("openldap plugin: Failed to bind to %s: %s",
{
oconfig_item_t *child = ci->children + i;
- if (strcasecmp ("CACert", child->key) == 0)
+ if (strcasecmp ("BindDN", child->key) == 0)
+ status = cf_util_get_string (child, &st->binddn);
+ else if (strcasecmp ("Password", child->key) == 0)
+ status = cf_util_get_string (child, &st->password);
+ else if (strcasecmp ("CACert", child->key) == 0)
status = cf_util_get_string (child, &st->cacert);
else if (strcasecmp ("StartTLS", child->key) == 0)
status = cf_util_get_boolean (child, &st->starttls);
status = plugin_register_complex_read (/* group = */ NULL,
/* name = */ callback_name,
/* callback = */ cldap_read_host,
- /* interval = */ NULL,
+ /* interval = */ 0,
/* user_data = */ &ud);
}
diff --git a/src/perl.c b/src/perl.c
index a964cce4eb58b548e2842063ef38afb6664e5e44..0a98684e9e809f30be3eb042abe3a254bb028510 100644 (file)
--- a/src/perl.c
+++ b/src/perl.c
return 0;
} /* static int hv2data_source (HV *, data_source_t *) */
-static int av2value (pTHX_ char *name, AV *array, value_t *value, int len)
+/* av2value converts at most "len" elements from "array" to "value". Returns the
+ * number of elements converted or zero on error. */
+static size_t av2value (pTHX_ char *name, AV *array, value_t *value, size_t array_len)
{
const data_set_t *ds;
+ size_t i;
- int i = 0;
-
- if ((NULL == name) || (NULL == array) || (NULL == value))
- return -1;
-
- if (av_len (array) < len - 1)
- len = av_len (array) + 1;
-
- if (0 >= len)
- return -1;
+ if ((NULL == name) || (NULL == array) || (NULL == value) || (array_len == 0))
+ return 0;
ds = plugin_get_ds (name);
if (NULL == ds) {
log_err ("av2value: Unknown dataset \"%s\"", name);
- return -1;
+ return 0;
}
- if (ds->ds_num < len) {
- log_warn ("av2value: Value length exceeds data set length.");
- len = ds->ds_num;
+ if (array_len < ds->ds_num) {
+ log_warn ("av2value: array does not contain enough elements for type \"%s\": got %zu, want %zu",
+ name, array_len, ds->ds_num);
+ return 0;
+ } else if (array_len > ds->ds_num) {
+ log_warn ("av2value: array contains excess elements for type \"%s\": got %zu, want %zu",
+ name, array_len, ds->ds_num);
}
- for (i = 0; i < len; ++i) {
+ for (i = 0; i < ds->ds_num; ++i) {
SV **tmp = av_fetch (array, i, 0);
if (NULL != tmp) {
value[i].absolute = SvIV (*tmp);
}
else {
- return -1;
+ return 0;
}
}
- return len;
-} /* static int av2value (char *, AV *, value_t *, int) */
+
+ return ds->ds_num;
+} /* static size_t av2value (char *, AV *, value_t *, size_t) */
/*
* value list:
{
AV *array = (AV *)SvRV (*tmp);
- int len = av_len (array) + 1;
-
- if (len <= 0)
+ /* av_len returns the highest index, not the actual length. */
+ size_t array_len = (size_t) (av_len (array) + 1);
+ if (array_len == 0)
return -1;
- vl->values = (value_t *)smalloc (len * sizeof (value_t));
- vl->values_len = av2value (aTHX_ vl->type, (AV *)SvRV (*tmp),
- vl->values, len);
-
- if (-1 == vl->values_len) {
+ vl->values = calloc (array_len, sizeof (*vl->values));
+ vl->values_len = av2value (aTHX_ vl->type, (AV *)SvRV (*tmp), vl->values, array_len);
+ if (vl->values_len == 0) {
sfree (vl->values);
return -1;
}
static int data_set2av (pTHX_ data_set_t *ds, AV *array)
{
- int i = 0;
+ size_t i;
if ((NULL == ds) || (NULL == array))
return -1;
static int value_list2hv (pTHX_ value_list_t *vl, data_set_t *ds, HV *hash)
{
AV *values = NULL;
-
- int i = 0;
- int len = 0;
+ size_t i;
if ((NULL == vl) || (NULL == ds) || (NULL == hash))
return -1;
- len = vl->values_len;
-
- if (ds->ds_num < len) {
- log_warn ("value2av: Value length exceeds data set length.");
- len = ds->ds_num;
- }
-
values = newAV ();
- av_extend (values, len - 1);
+ /* av_extend takes the last *index* to which the array should be extended. */
+ av_extend (values, vl->values_len - 1);
- for (i = 0; i < len; ++i) {
+ assert (ds->ds_num == vl->values_len);
+ for (i = 0; i < vl->values_len; ++i) {
SV *val = NULL;
if (DS_TYPE_COUNTER == ds->ds[i].type)
diff --git a/src/pf.c b/src/pf.c
index 29f3a3d539f19ecefceb6d5f9c09201ef7fb8dd3..d11bd8aaedabb6c2b5232009671007218156a0a3 100644 (file)
--- a/src/pf.c
+++ b/src/pf.c
#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
diff --git a/src/pinba.c b/src/pinba.c
index 9f0a80023324d55c00871c2299a22aa484978f74..b6e7b152554a13b00af34ab0fe6bbf3d9be67381 100644 (file)
--- a/src/pinba.c
+++ b/src/pinba.c
#include "configfile.h"
#include <pthread.h>
-#include <sys/socket.h>
#include <netdb.h>
#include <poll.h>
diff --git a/src/ping.c b/src/ping.c
index d669aa937d4b15f187e7d3c69edd4f2d341b25f9..df2f6da6e6bc69158ebad65e8c47615cd10bfcad 100644 (file)
--- a/src/ping.c
+++ b/src/ping.c
hl->pkg_missed++;
/* if the host did not answer our last N packages, trigger a resolv. */
- if (ping_max_missed >= 0 && hl->pkg_missed >= ping_max_missed)
+ if ((ping_max_missed >= 0)
+ && (hl->pkg_missed >= ((uint32_t) ping_max_missed)))
{ /* {{{ */
/* we reset the missed package counter here, since we only want to
* trigger a resolv every N packages and not every package _AFTER_ N
diff --git a/src/postgresql.c b/src/postgresql.c
index 54c856d66464f68f9683a16c5c73cb630c180cbf..bef3490ff0f16852d345c85bf8c167f851116597 100644 (file)
--- a/src/postgresql.c
+++ b/src/postgresql.c
c_psql_database_t *db;
int success = 0;
- int i;
+ size_t i;
if ((ud == NULL) || (ud->data == NULL)) {
log_err ("c_psql_read: Invalid user data.");
{
char *str_ptr;
size_t str_len;
-
- int i;
+ size_t i;
str_ptr = string;
str_len = string_len;
{
char *str_ptr;
size_t str_len;
-
- int i;
+ size_t i;
str_ptr = string;
str_len = string_len;
size_t str_len;
gauge_t *rates = NULL;
-
- int i;
+ size_t i;
str_ptr = string;
str_len = string_len;
const char *params[9];
int success = 0;
- int i;
+ size_t i;
if ((ud == NULL) || (ud->data == NULL)) {
log_err ("c_psql_write: Invalid user data.");
c_psql_database_t *db;
char cb_name[DATA_MAX_NAME_LEN];
- struct timespec cb_interval = { 0, 0 };
user_data_t ud;
static _Bool have_flush = 0;
ssnprintf (cb_name, sizeof (cb_name), "postgresql-%s", db->instance);
if (db->queries_num > 0) {
- CDTIME_T_TO_TIMESPEC (db->interval, &cb_interval);
-
++db->ref_cnt;
plugin_register_complex_read ("postgresql", cb_name, c_psql_read,
- /* interval = */ (db->interval > 0) ? &cb_interval : NULL,
- &ud);
+ /* interval = */ db->interval, &ud);
}
if (db->writers_num > 0) {
++db->ref_cnt;
diff --git a/src/powerdns.c b/src/powerdns.c
index f9f291aed08b924cf6c9940e1020bc1b80ec647a..5ea1b098402c5e6c1c8231f72f0d1a74bbe96c8a 100644 (file)
--- a/src/powerdns.c
+++ b/src/powerdns.c
#include <string.h>
#include <errno.h>
#include <sys/types.h>
-#include <sys/socket.h>
#include <sys/un.h>
#ifndef UNIX_PATH_MAX
if (ds->ds_num != 1)
{
- ERROR ("powerdns plugin: type `%s' has %i data sources, "
+ ERROR ("powerdns plugin: type `%s' has %zu data sources, "
"but I can only handle one.",
type, ds->ds_num);
return;
return (-1);
}
buffer[sizeof (buffer) - 1] = 0;
- int i = strlen (buffer);
- if (i < sizeof (buffer) - 2)
+ size_t len = strlen (buffer);
+ if (len < sizeof (buffer) - 2)
{
- buffer[i++] = ' ';
- buffer[i++] = '\n';
- buffer[i++] = '\0';
+ buffer[len++] = ' ';
+ buffer[len++] = '\n';
+ buffer[len++] = '\0';
}
}
diff --git a/src/processes.c b/src/processes.c
index fde96f89d245c3b79d3a6c5a5239f1d76052cae0..24dbf49299edfcaa964ce54fd8a5cf6ce7d695fd 100644 (file)
--- a/src/processes.c
+++ b/src/processes.c
derive_t io_syscr;
derive_t io_syscw;
+ derive_t cswitch_vol;
+ derive_t cswitch_invol;
+
struct procstat_entry_s *next;
} procstat_entry_t;
derive_t io_syscr;
derive_t io_syscw;
+ derive_t cswitch_vol;
+ derive_t cswitch_invol;
+
struct procstat *next;
struct procstat_entry_s *instances;
} procstat_t;
static procstat_t *list_head_g = NULL;
+static _Bool report_ctx_switch = 0;
+
#if HAVE_THREAD_INFO
static mach_port_t port_host_self;
static mach_port_t port_task_self;
@@ -398,6 +406,8 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t
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;
@@ -412,6 +422,9 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t
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);
+
if ((entry->vmem_minflt_counter == 0)
&& (entry->vmem_majflt_counter == 0))
{
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;
ps_list_register (c->values[0].value.string,
c->values[1].value.string);
}
+ else if (strcasecmp (c->key, "CollectContextSwitch") == 0)
+ {
+ cf_util_get_boolean (c, &report_ctx_switch);
+ }
else
{
ERROR ("processes plugin: The `%s' configuration option is not "
plugin_dispatch_values (&vl);
}
+ if ( report_ctx_switch )
+ {
+ sstrncpy (vl.type, "contextswitch", sizeof (vl.type));
+ sstrncpy (vl.type_instance, "voluntary", sizeof (vl.type_instance));
+ vl.values[0].derive = ps->cswitch_vol;
+ vl.values_len = 1;
+ plugin_dispatch_values (&vl);
+
+ sstrncpy (vl.type, "contextswitch", sizeof (vl.type));
+ sstrncpy (vl.type_instance, "involuntary", sizeof (vl.type_instance));
+ vl.values[0].derive = ps->cswitch_invol;
+ vl.values_len = 1;
+ 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";",
+ "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->io_rchar, ps->io_wchar, ps->io_syscr, ps->io_syscw,
+ 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 (int pid)
+static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps)
{
char dirname[64];
DIR *dh;
+ char filename[64];
+ FILE *fh;
struct dirent *ent;
- int count = 0;
+ derive_t cswitch_vol = 0;
+ derive_t cswitch_invol = 0;
+ char buffer[1024];
+ char *fields[8];
+ int numfields;
ssnprintf (dirname, sizeof (dirname), "/proc/%i/task", pid);
if ((dh = opendir (dirname)) == NULL)
{
DEBUG ("Failed to open directory `%s'", dirname);
- return (-1);
+ return (NULL);
}
while ((ent = readdir (dh)) != NULL)
{
+ char *tpid;
+
if (!isdigit ((int) ent->d_name[0]))
continue;
- else
- count++;
+
+ tpid = ent->d_name;
+
+ ssnprintf (filename, sizeof (filename), "/proc/%i/task/%s/status", pid, tpid);
+ if ((fh = fopen (filename, "r")) == NULL)
+ {
+ DEBUG ("Failed to open file `%s'", filename);
+ continue;
+ }
+
+ while (fgets (buffer, sizeof(buffer), fh) != NULL)
+ {
+ derive_t tmp;
+ char *endptr;
+
+ if (strncmp (buffer, "voluntary_ctxt_switches", 23) != 0
+ && strncmp (buffer, "nonvoluntary_ctxt_switches", 26) != 0)
+ continue;
+
+ numfields = strsplit (buffer, fields,
+ STATIC_ARRAY_SIZE (fields));
+
+ if (numfields < 2)
+ continue;
+
+ errno = 0;
+ endptr = NULL;
+ tmp = (derive_t) strtoll (fields[1], &endptr, /* base = */ 10);
+ if ((errno == 0) && (endptr != fields[1]))
+ {
+ if (strncmp (buffer, "voluntary_ctxt_switches", 23) == 0)
+ {
+ cswitch_vol += tmp;
+ }
+ else if (strncmp (buffer, "nonvoluntary_ctxt_switches", 26) == 0)
+ {
+ cswitch_invol += tmp;
+ }
+ }
+ } /* while (fgets) */
+
+ if (fclose (fh))
+ {
+ char errbuf[1024];
+ WARNING ("processes: fclose: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
}
closedir (dh);
- return ((count >= 1) ? count : 1);
-} /* int *ps_read_tasks */
+ ps->cswitch_vol = cswitch_vol;
+ ps->cswitch_invol = cswitch_invol;
-/* Read advanced virtual memory data from /proc/pid/status */
-static procstat_t *ps_read_vmem (int pid, procstat_t *ps)
+ return (ps);
+} /* int *ps_read_tasks_status */
+
+/* Read data from /proc/pid/status */
+static procstat_t *ps_read_status (int pid, procstat_t *ps)
{
FILE *fh;
char buffer[1024];
char filename[64];
- unsigned long long lib = 0;
- unsigned long long exe = 0;
- unsigned long long data = 0;
+ unsigned long lib = 0;
+ unsigned long exe = 0;
+ unsigned long data = 0;
+ unsigned long threads = 0;
char *fields[8];
int numfields;
while (fgets (buffer, sizeof(buffer), fh) != NULL)
{
- long long tmp;
+ unsigned long tmp;
char *endptr;
- if (strncmp (buffer, "Vm", 2) != 0)
+ if (strncmp (buffer, "Vm", 2) != 0
+ && strncmp (buffer, "Threads", 7) != 0)
continue;
numfields = strsplit (buffer, fields,
errno = 0;
endptr = NULL;
- tmp = strtoll (fields[1], &endptr, /* base = */ 10);
+ tmp = strtoul (fields[1], &endptr, /* base = */ 10);
if ((errno == 0) && (endptr != fields[1]))
{
if (strncmp (buffer, "VmData", 6) == 0)
{
exe = tmp;
}
+ else if (strncmp(buffer, "Threads", 7) == 0)
+ {
+ threads = tmp;
+ }
}
} /* while (fgets) */
ps->vmem_data = data * 1024;
ps->vmem_code = (exe + lib) * 1024;
+ if (threads != 0)
+ ps->num_lwp = threads;
return (ps);
} /* procstat_t *ps_read_vmem */
char *fields[64];
char fields_len;
- int buffer_len;
+ size_t buffer_len;
- char *buffer_ptr;
+ char *buffer_ptr;
size_t name_start_pos;
size_t name_end_pos;
size_t name_len;
long long unsigned vmem_rss;
long long unsigned stack_size;
+ ssize_t status;
+
memset (ps, 0, sizeof (procstat_t));
ssnprintf (filename, sizeof (filename), "/proc/%i/stat", pid);
- buffer_len = read_file_contents (filename,
- buffer, sizeof(buffer) - 1);
- if (buffer_len <= 0)
+ status = read_file_contents (filename, buffer, sizeof(buffer) - 1);
+ if (status <= 0)
return (-1);
+ buffer_len = (size_t) status;
buffer[buffer_len] = 0;
/* The name of the process is enclosed in parens. Since the name can
}
else
{
- if ( (ps->num_lwp = ps_read_tasks (pid)) == -1 )
+ ps->num_lwp = strtoul (fields[17], /* endptr = */ NULL, /* base = */ 10);
+ if ((ps_read_status(pid, ps)) == NULL)
{
- /* returns -1 => kernel 2.4 */
- ps->num_lwp = 1;
+ /* No VMem data */
+ ps->vmem_data = -1;
+ ps->vmem_code = -1;
+ DEBUG("ps_read_process: did not get vmem data for pid %i",pid);
}
+ if (ps->num_lwp <= 0)
+ ps->num_lwp = 1;
ps->num_proc = 1;
}
cpu_system_counter = cpu_system_counter * 1000000 / CONFIG_HZ;
vmem_rss = vmem_rss * pagesize_g;
- if ( (ps_read_vmem(pid, ps)) == NULL)
- {
- /* No VMem data */
- ps->vmem_data = -1;
- ps->vmem_code = -1;
- DEBUG("ps_read_process: did not get vmem data for pid %i",pid);
- }
-
ps->cpu_user_counter = cpu_user_counter;
ps->cpu_system_counter = cpu_system_counter;
ps->vmem_size = (unsigned long) vmem_size;
DEBUG("ps_read_process: not get io data for pid %i",pid);
}
+ if ( report_ctx_switch )
+ {
+ if ( (ps_read_tasks_status(pid, ps)) == NULL)
+ {
+ ps->cswitch_vol = -1;
+ ps->cswitch_invol = -1;
+
+ DEBUG("ps_read_tasks_status: not get context "
+ "switch data for pid %i",pid);
+ }
+ }
+
/* success */
return (0);
} /* int ps_read_process (...) */
{
char path[PATH_MAX];
psinfo_t info;
- int status;
+ ssize_t status;
snprintf(path, sizeof (path), "/proc/%li/psinfo", pid);
status = read_file_contents (path, (void *) &info, sizeof (info));
- if (status != sizeof (info))
+ if ((status < 0) || (((size_t) status) != sizeof (info)))
{
ERROR ("processes plugin: Unexpected return value "
"while reading \"%s\": "
- "Returned %i but expected %zu.",
+ "Returned %zd but expected %zu.",
path, status, buffer_size);
return (NULL);
}
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;
diff --git a/src/python.c b/src/python.c
index 8b378a299994105f9a7584e0e247d7a2710e2558..b7cc5b9150e4b10eef61e251218258124da95c2b 100644 (file)
--- a/src/python.c
+++ b/src/python.c
}
static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_list, user_data_t *data) {
- int i;
+ size_t i;
cpy_callback_t *c = data->data;
PyObject *ret, *list, *temp, *dict = NULL;
Values *v;
@@ -358,22 +358,13 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
}
for (i = 0; i < value_list->values_len; ++i) {
if (ds->ds[i].type == DS_TYPE_COUNTER) {
- if ((long) value_list->values[i].counter == value_list->values[i].counter)
- PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].counter));
- else
- PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].counter));
+ PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].counter));
} else if (ds->ds[i].type == DS_TYPE_GAUGE) {
PyList_SetItem(list, i, PyFloat_FromDouble(value_list->values[i].gauge));
} else if (ds->ds[i].type == DS_TYPE_DERIVE) {
- if ((long) value_list->values[i].derive == value_list->values[i].derive)
- PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].derive));
- else
- PyList_SetItem(list, i, PyLong_FromLongLong(value_list->values[i].derive));
+ PyList_SetItem(list, i, PyLong_FromLongLong(value_list->values[i].derive));
} else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) {
- if ((long) value_list->values[i].absolute == value_list->values[i].absolute)
- PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].absolute));
- else
- PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].absolute));
+ 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);
}
static PyObject *cpy_get_dataset(PyObject *self, PyObject *args) {
- int i;
+ size_t i;
char *name;
const data_set_t *ds;
PyObject *list, *tuple;
@@ -656,7 +647,6 @@ static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwd
double interval = 0;
char *name = NULL;
PyObject *callback = NULL, *data = NULL;
- struct timespec ts;
static char *kwlist[] = {"callback", "interval", "data", "name", NULL};
if (PyArg_ParseTupleAndKeywords(args, kwds, "O|dOet", kwlist, &callback, &interval, &data, NULL, &name) == 0) return NULL;
@@ -678,10 +668,8 @@ static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwd
user_data = malloc(sizeof(*user_data));
user_data->free_func = cpy_destroy_user_data;
user_data->data = c;
- ts.tv_sec = interval;
- ts.tv_nsec = (interval - ts.tv_sec) * 1000000000;
plugin_register_complex_read(/* group = */ NULL, buf,
- cpy_read_callback, &ts, user_data);
+ cpy_read_callback, DOUBLE_TO_CDTIME_T (interval), user_data);
return cpy_string_to_unicode_or_bytes(buf);
}
diff --git a/src/pyvalues.c b/src/pyvalues.c
index 78e6cf9d450413ed242fb73e6126a09f4dd86057..44176014fc27dc68de218f00acf6c2e8bf8560d7 100644 (file)
--- a/src/pyvalues.c
+++ b/src/pyvalues.c
}
static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
- int i, ret;
+ int ret;
const data_set_t *ds;
- int size;
+ size_t size, i;
value_t *value;
value_list_t value_list = VALUE_LIST_INIT;
PyObject *values = self->values, *meta = self->meta;
@@ -542,15 +542,15 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
PyErr_Format(PyExc_TypeError, "meta must be a dict");
return NULL;
}
- size = (int) PySequence_Length(values);
+ size = (size_t) PySequence_Length(values);
if (size != ds->ds_num) {
- PyErr_Format(PyExc_RuntimeError, "type %s needs %d values, got %i", value_list.type, ds->ds_num, size);
+ PyErr_Format(PyExc_RuntimeError, "type %s needs %zu values, got %zu", value_list.type, ds->ds_num, size);
return NULL;
}
- value = malloc(size * sizeof(*value));
+ value = calloc(size, sizeof(*value));
for (i = 0; i < size; ++i) {
PyObject *item, *num;
- item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */
+ item = PySequence_Fast_GET_ITEM(values, (int) i); /* Borrowed reference. */
if (ds->ds->type == DS_TYPE_COUNTER) {
num = PyNumber_Long(item); /* New reference. */
if (num != NULL) {
@@ -611,9 +611,9 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
}
static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
- int i, ret;
+ int ret;
const data_set_t *ds;
- int size;
+ size_t size, i;
value_t *value;
value_list_t value_list = VALUE_LIST_INIT;
PyObject *values = self->values, *meta = self->meta;
PyErr_Format(PyExc_TypeError, "values must be list or tuple");
return NULL;
}
- size = (int) PySequence_Length(values);
+ size = (size_t) PySequence_Length(values);
if (size != ds->ds_num) {
- PyErr_Format(PyExc_RuntimeError, "type %s needs %d values, got %i", value_list.type, ds->ds_num, size);
+ PyErr_Format(PyExc_RuntimeError, "type %s needs %zu values, got %zu", value_list.type, ds->ds_num, size);
return NULL;
}
- value = malloc(size * sizeof(*value));
+ value = calloc(size, sizeof(*value));
for (i = 0; i < size; ++i) {
PyObject *item, *num;
item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */
diff --git a/src/routeros.c b/src/routeros.c
index 4863d7c082b1e8297b48152c379dc6a4701b0a1d..667c2fa581722e00ef01161e385d6e13d0c4e36a 100644 (file)
--- a/src/routeros.c
+++ b/src/routeros.c
user_data.free_func = (void *) cr_free_data;
if (status == 0)
status = plugin_register_complex_read (/* group = */ NULL, read_name,
- cr_read, /* interval = */ NULL, &user_data);
+ cr_read, /* interval = */ 0, &user_data);
if (status != 0)
cr_free_data (router_data);
diff --git a/src/rrdcached.c b/src/rrdcached.c
index 645032cbe189686a707c7e6d34db7343432b8882..5d98de8e0dbd5dec3aaba79ea5bda1a03363c85f 100644 (file)
--- a/src/rrdcached.c
+++ b/src/rrdcached.c
{
int offset;
int status;
- int i;
+ size_t i;
time_t t;
assert (0 == strcmp (ds->type, vl->type));
diff --git a/src/rrdtool.c b/src/rrdtool.c
index 8497a24cd8b1f393a922acadd9907f02020ce77c..764d6d65db0d2b545c94f41b8a105cd0cda3e97e 100644 (file)
--- a/src/rrdtool.c
+++ b/src/rrdtool.c
int offset;
int status;
time_t tt;
- int i;
+ size_t i;
memset (buffer, '\0', buffer_len);
diff --git a/src/serial.c b/src/serial.c
index 430082220595c58f2b927089871a76e4e482a157..0878d3c93b1dac2b4d4bc331e4d13e56a358ede9 100644 (file)
--- a/src/serial.c
+++ b/src/serial.c
FILE *fh;
char buffer[1024];
- derive_t rx = 0;
- derive_t tx = 0;
-
- char *fields[16];
- int i, numfields;
- int len;
-
/* there are a variety of names for the serial device */
if ((fh = fopen ("/proc/tty/driver/serial", "r")) == NULL &&
(fh = fopen ("/proc/tty/driver/ttyS", "r")) == NULL)
while (fgets (buffer, sizeof (buffer), fh) != NULL)
{
- int have_rx = 0, have_tx = 0;
+ derive_t rx = 0;
+ derive_t tx = 0;
+ _Bool have_rx = 0, have_tx = 0;
+ size_t len;
- numfields = strsplit (buffer, fields, 16);
+ char *fields[16];
+ int numfields;
+ int i;
+ numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
if (numfields < 6)
continue;
* 0: uart:16550A port:000003F8 irq:4 tx:0 rx:0
* 1: uart:16550A port:000002F8 irq:3 tx:0 rx:0
*/
- len = strlen (fields[0]) - 1;
- if (len < 1)
+ len = strlen (fields[0]);
+ if (len < 2)
continue;
- if (fields[0][len] != ':')
+ if (fields[0][len - 1] != ':')
continue;
- fields[0][len] = '\0';
+ fields[0][len - 1] = 0;
for (i = 1; i < numfields; i++)
{
if (strncmp (fields[i], "tx:", 3) == 0)
{
- tx = atoll (fields[i] + 3);
- have_tx++;
+ if (strtoderive (fields[i] + 3, &tx) == 0)
+ have_tx = 1;
}
else if (strncmp (fields[i], "rx:", 3) == 0)
{
- rx = atoll (fields[i] + 3);
- have_rx++;
+ if (strtoderive (fields[i] + 3, &rx) == 0)
+ have_rx = 1;
}
}
- if ((have_rx == 0) || (have_tx == 0))
- continue;
-
- serial_submit (fields[0], rx, tx);
+ if (have_rx && have_tx)
+ serial_submit (fields[0], rx, tx);
}
fclose (fh);
diff --git a/src/snmp.c b/src/snmp.c
index 8564c681705669a9d71901a2051e329a1a792b06..d9a932a393ba65e33be5c3970046326d5df6c0e8 100644 (file)
--- a/src/snmp.c
+++ b/src/snmp.c
instance_t instance;
char *instance_prefix;
oid_t *values;
- int values_len;
+ size_t values_len;
double scale;
double shift;
struct data_definition_s *next;
@@ -313,7 +313,7 @@ static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t *
dd->values = (oid_t *) malloc (sizeof (oid_t) * ci->values_num);
if (dd->values == NULL)
return (-1);
- dd->values_len = ci->values_num;
+ dd->values_len = (size_t) ci->values_num;
for (i = 0; i < ci->values_num; i++)
{
return (-1);
}
- DEBUG ("snmp plugin: dd = { name = %s, type = %s, is_table = %s, values_len = %i }",
+ DEBUG ("snmp plugin: dd = { name = %s, type = %s, is_table = %s, values_len = %zu }",
dd->name, dd->type, (dd->is_table != 0) ? "true" : "false", dd->values_len);
if (data_head == NULL)
/* Registration stuff. */
char cb_name[DATA_MAX_NAME_LEN];
user_data_t cb_data;
- struct timespec cb_interval;
hd = (host_definition_t *) malloc (sizeof (host_definition_t));
if (hd == NULL)
cb_data.data = hd;
cb_data.free_func = csnmp_host_definition_destroy;
- CDTIME_T_TO_TIMESPEC (hd->interval, &cb_interval);
-
status = plugin_register_complex_read (/* group = */ NULL, cb_name,
- csnmp_read_host, /* interval = */ &cb_interval,
- /* user_data = */ &cb_data);
+ csnmp_read_host, hd->interval, /* user_data = */ &cb_data);
if (status != 0)
{
ERROR ("snmp plugin: Registering complex read function failed.");
@@ -1053,6 +1049,10 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
return (ret);
} /* value_t csnmp_value_list_to_value */
+/* csnmp_strvbcopy_hexstring converts the bit string contained in "vb" to a hex
+ * representation and writes it to dst. Returns zero on success and ENOMEM if
+ * dst is not large enough to hold the string. dst is guaranteed to be
+ * nul-terminated. */
static int csnmp_strvbcopy_hexstring (char *dst, /* {{{ */
const struct variable_list *vb, size_t dst_size)
{
size_t buffer_free;
size_t i;
+ dst[0] = 0;
+
buffer_ptr = dst;
buffer_free = dst_size;
status = snprintf (buffer_ptr, buffer_free,
(i == 0) ? "%02x" : ":%02x", (unsigned int) vb->val.bitstring[i]);
+ assert (status >= 0);
- if (status >= buffer_free)
+ if (((size_t) status) >= buffer_free) /* truncated */
{
- buffer_ptr += (buffer_free - 1);
- *buffer_ptr = 0;
- return (dst_size + (buffer_free - status));
+ dst[dst_size - 1] = 0;
+ return ENOMEM;
}
else /* if (status < buffer_free) */
{
- buffer_ptr += status;
- buffer_free -= status;
+ buffer_ptr += (size_t) status;
+ buffer_free -= (size_t) status;
}
}
- return ((int) (dst_size - buffer_free));
+ return 0;
} /* }}} int csnmp_strvbcopy_hexstring */
+/* csnmp_strvbcopy copies the octet string or bit string contained in vb to
+ * dst. If non-printable characters are detected, it will switch to a hex
+ * representation of the string. Returns zero on success, EINVAL if vb does not
+ * contain a string and ENOMEM if dst is not large enough to contain the
+ * string. */
static int csnmp_strvbcopy (char *dst, /* {{{ */
const struct variable_list *vb, size_t dst_size)
{
dst[i] = src[i];
}
dst[num_chars] = 0;
+ dst[dst_size - 1] = 0;
- return ((int) vb->val_len);
+ if (dst_size <= vb->val_len)
+ return ENOMEM;
+
+ return 0;
} /* }}} int csnmp_strvbcopy */
static int csnmp_instance_list_add (csnmp_list_instances_t **head,
@@ -1224,7 +1235,7 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat
csnmp_list_instances_t *instance_list_ptr;
csnmp_table_values_t **value_table_ptr;
- int i;
+ size_t i;
_Bool have_more;
oid_t current_suffix;
@@ -1239,7 +1250,7 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat
instance_list_ptr = instance_list;
- value_table_ptr = calloc ((size_t) data->values_len, sizeof (*value_table_ptr));
+ 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++)
@@ -1382,7 +1393,7 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
const data_set_t *ds;
- uint32_t oid_list_len = (uint32_t) (data->values_len + 1);
+ size_t oid_list_len = data->values_len + 1;
/* Holds the last OID returned by the device. We use this in the GETNEXT
* request to proceed. */
oid_t oid_list[oid_list_len];
@@ -1391,8 +1402,7 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
_Bool oid_list_todo[oid_list_len];
int status;
- int i;
- uint32_t j;
+ size_t i;
/* `value_list_head' and `value_list_tail' implement a linked list for each
* value. `instance_list_head' and `instance_list_tail' implement a linked list of
@@ -1420,7 +1430,7 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
if (ds->ds_num != data->values_len)
{
- ERROR ("snmp plugin: DataSet `%s' requires %i values, but config talks about %i",
+ ERROR ("snmp plugin: DataSet `%s' requires %zu values, but config talks about %zu",
data->type, ds->ds_num, data->values_len);
return (-1);
}
@@ -1433,8 +1443,8 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
else /* no InstanceFrom option specified. */
oid_list_len--;
- for (j = 0; j < oid_list_len; j++)
- oid_list_todo[j] = 1;
+ for (i = 0; i < oid_list_len; i++)
+ oid_list_todo[i] = 1;
/* We're going to construct n linked lists, one for each "value".
* value_list_head will contain pointers to the heads of these linked lists,
@@ -1466,13 +1476,13 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
}
oid_list_todo_num = 0;
- for (j = 0; j < oid_list_len; j++)
+ for (i = 0; i < oid_list_len; i++)
{
/* Do not rerequest already finished OIDs */
- if (!oid_list_todo[j])
+ if (!oid_list_todo[i])
continue;
oid_list_todo_num++;
- snmp_add_null_var (req, oid_list[j].oid, oid_list[j].oid_len);
+ snmp_add_null_var (req, oid_list[i].oid, oid_list[i].oid_len);
}
if (oid_list_todo_num == 0)
@@ -1568,7 +1578,7 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
ret = csnmp_oid_suffix (&suffix, &vb_name, data->values + i);
if (ret != 0)
{
- DEBUG ("snmp plugin: host = %s; data = %s; i = %i; "
+ DEBUG ("snmp plugin: host = %s; data = %s; i = %zu; "
"Value probably left its subtree.",
host->name, data->name, i);
oid_list_todo[i] = 0;
@@ -1580,7 +1590,7 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
if ((value_list_tail[i] != NULL)
&& (csnmp_oid_compare (&suffix, &value_list_tail[i]->suffix) <= 0))
{
- DEBUG ("snmp plugin: host = %s; data = %s; i = %i; "
+ DEBUG ("snmp plugin: host = %s; data = %s; i = %zu; "
"Suffix is not increasing.",
host->name, data->name, i);
oid_list_todo[i] = 0;
@@ -1664,7 +1674,7 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
value_list_t vl = VALUE_LIST_INIT;
int status;
- int i;
+ size_t i;
DEBUG ("snmp plugin: csnmp_read_value (host = %s, data = %s)",
host->name, data->name);
@@ -1684,7 +1694,7 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
if (ds->ds_num != data->values_len)
{
- ERROR ("snmp plugin: DataSet `%s' requires %i values, but config talks about %i",
+ ERROR ("snmp plugin: DataSet `%s' requires %zu values, but config talks about %zu",
data->type, ds->ds_num, data->values_len);
return (-1);
}
diff --git a/src/statsd.c b/src/statsd.c
index 5b0bdd693de71088f8ec47f3560b29c4c87f79f5..9a6da1d34fafafa49f2681149e5d7161176a613e 100644 (file)
--- a/src/statsd.c
+++ b/src/statsd.c
#include <pthread.h>
#include <sys/types.h>
-#include <sys/socket.h>
#include <netdb.h>
#include <poll.h>
diff --git a/src/table.c b/src/table.c
index beded1ae9eeafef7e7bbfe0232ee80e954622fbe..b0bc95f80bb90c5f999c525d17aa9d94bbc1d8b7 100644 (file)
--- a/src/table.c
+++ b/src/table.c
*/
typedef struct {
- char *type;
- char *instance_prefix;
- int *instances;
- size_t instances_num;
- int *values;
- size_t values_num;
+ char *type;
+ char *instance_prefix;
+ size_t *instances;
+ size_t instances_num;
+ size_t *values;
+ size_t values_num;
const data_set_t *ds;
} tbl_result_t;
return 0;
} /* tbl_config_set_separator */
-static int tbl_config_append_array_i (char *name, int **var, size_t *len,
+static int tbl_config_append_array_i (char *name, size_t **var, size_t *len,
oconfig_item_t *ci)
{
- int *tmp;
-
+ size_t *tmp;
+ size_t num;
size_t i;
if (1 > ci->values_num) {
return 1;
}
- for (i = 0; i < ci->values_num; ++i) {
+ num = (size_t) ci->values_num;
+ for (i = 0; i < num; ++i) {
if (OCONFIG_TYPE_NUMBER != ci->values[i].type) {
log_err ("\"%s\" expects numerical arguments only.", name);
return 1;
}
}
- *len += ci->values_num;
- tmp = (int *)realloc (*var, *len * sizeof (**var));
+ tmp = realloc (*var, ((*len) + num) * sizeof (**var));
if (NULL == tmp) {
char errbuf[1024];
log_err ("realloc failed: %s.",
sstrerror (errno, errbuf, sizeof (errbuf)));
return -1;
}
-
*var = tmp;
- for (i = *len - ci->values_num; i < *len; ++i)
- (*var)[i] = (int)ci->values[i].value.number;
+ for (i = 0; i < num; ++i) {
+ (*var)[*len] = (size_t) ci->values[i].value.number;
+ (*len)++;
+ }
+
return 0;
} /* tbl_config_append_array_s */
tbl_result_t *res;
int status = 0;
- size_t i;
+ int i;
if (0 != ci->values_num) {
log_err ("<Result> does not expect any arguments.");
tbl = tables + tables_num - 1;
tbl_setup (tbl, ci->values[0].value.string);
- for (i = 0; i < ci->children_num; ++i) {
+ for (i = 0; i < ((size_t) ci->children_num); ++i) {
oconfig_item_t *c = ci->children + i;
if (0 == strcasecmp (c->key, "Separator"))
static int tbl_config (oconfig_item_t *ci)
{
- size_t i;
+ int i;
for (i = 0; i < ci->children_num; ++i) {
oconfig_item_t *c = ci->children + i;
return -1;
}
- if (res->values_num != (size_t)res->ds->ds_num) {
+ if (res->values_num != res->ds->ds_num) {
log_err ("Invalid type \"%s\". Expected %zu data source%s, "
- "got %i.", res->type, res->values_num,
+ "got %zu.", res->type, res->values_num,
(1 == res->values_num) ? "" : "s",
res->ds->ds_num);
return -1;
diff --git a/src/tail.c b/src/tail.c
index 3904f1be201acb31c089057bfe189d78e7e8c5ed..751243bcb58c219adc86d465cebb9aad3ece8337 100644 (file)
--- a/src/tail.c
+++ b/src/tail.c
static int ctail_init (void)
{
- struct timespec cb_interval;
char str[255];
user_data_t ud;
size_t i;
{
ud.data = (void *)tail_match_list[i];
ssnprintf(str, sizeof(str), "tail-%zu", i);
- CDTIME_T_TO_TIMESPEC (tail_match_list_intervals[i], &cb_interval);
- plugin_register_complex_read (NULL, str, ctail_read, &cb_interval, &ud);
+ plugin_register_complex_read (NULL, str, ctail_read, tail_match_list_intervals[i], &ud);
}
return (0);
diff --git a/src/tail_csv.c b/src/tail_csv.c
index c3efcc9a3d3c79c844590f5a898b5c45ccb00de0..bb9b58aceaa1edc459bbf7220f581c5e796997db 100644 (file)
--- a/src/tail_csv.c
+++ b/src/tail_csv.c
#include <string.h>
struct metric_definition_s {
- char *name;
- char *type;
- char *instance;
- int data_source_type;
- int value_from;
+ char *name;
+ char *type;
+ char *instance;
+ int data_source_type;
+ ssize_t value_from;
struct metric_definition_s *next;
};
typedef struct metric_definition_s metric_definition_t;
struct instance_definition_s {
- char *instance;
- char *path;
- cu_tail_t *tail;
+ char *instance;
+ char *path;
+ cu_tail_t *tail;
metric_definition_t **metric_list;
- size_t metric_list_len;
- cdtime_t interval;
- int time_from;
+ size_t metric_list_len;
+ cdtime_t interval;
+ ssize_t time_from;
struct instance_definition_s *next;
};
typedef struct instance_definition_s instance_definition_t;
char **fields, size_t fields_num)
{
value_t v;
- cdtime_t t;
+ cdtime_t t = 0;
int status;
if (md->data_source_type == -1)
return (EINVAL);
- if (md->value_from >= fields_num)
+ assert (md->value_from >= 0);
+ if (((size_t) md->value_from) >= fields_num)
return (EINVAL);
- if (id->time_from >= 0 && (id->time_from >= fields_num))
- return (EINVAL);
-
- t = 0;
- if (id->time_from >= 0)
- t = parse_time (fields[id->time_from]);
-
status = parse_value (fields[md->value_from], &v, md->data_source_type);
if (status != 0)
return (status);
+ if (id->time_from >= 0) {
+ if (((size_t) id->time_from) >= fields_num)
+ return (EINVAL);
+ t = parse_time (fields[id->time_from]);
+ }
+
return (tcsv_submit (id, md, v, t));
}
-static _Bool tcsv_check_index (int index, size_t fields_num, char const *name)
+static _Bool tcsv_check_index (ssize_t index, size_t fields_num, char const *name)
{
if (index < 0)
return 1;
else if (((size_t) index) < fields_num)
return 1;
- ERROR ("tail_csv plugin: Metric \"%s\": Request for index %i when "
+ ERROR ("tail_csv plugin: Metric \"%s\": Request for index %zd when "
"only %zu fields are available.",
name, index, fields_num);
return (0);
tcsv_metric_definition_destroy (next);
}
-static int tcsv_config_get_index(oconfig_item_t *ci, int *ret_index) {
- int index;
-
+static int tcsv_config_get_index(oconfig_item_t *ci, ssize_t *ret_index) {
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)){
WARNING("tail_csv plugin: The \"%s\" config option needs exactly one "
"integer argument.", ci->key);
return (-1);
}
- index = (int) ci->values[0].value.number;
- if (index < 0) {
+ if (ci->values[0].value.number < 0) {
WARNING("tail_csv plugin: The \"%s\" config option must be positive "
"(or zero).", ci->key);
return (-1);
}
- *ret_index = index;
+ *ret_index = (ssize_t) ci->values[0].value.number;
return (0);
}
/* Parse metric */
static int tcsv_config_add_metric(oconfig_item_t *ci){
metric_definition_t *md;
- int status = 0;
+ int status;
int i;
md = (metric_definition_t *)malloc(sizeof(*md));
/* Registration variables */
char cb_name[DATA_MAX_NAME_LEN];
user_data_t cb_data;
- struct timespec cb_interval;
id = malloc(sizeof(*id));
if (id == NULL)
memset(&cb_data, 0, sizeof(cb_data));
cb_data.data = id;
cb_data.free_func = tcsv_instance_definition_destroy;
- CDTIME_T_TO_TIMESPEC(id->interval, &cb_interval);
- status = plugin_register_complex_read(NULL, cb_name, tcsv_read, &cb_interval, &cb_data);
+ status = plugin_register_complex_read(NULL, cb_name, tcsv_read, id->interval, &cb_data);
if (status != 0){
ERROR("tail_csv plugin: Registering complex read function failed.");
}
else if (ds->ds_num != 1)
{
- ERROR ("tail_csv plugin: The type \"%s\" has %i data sources. "
+ ERROR ("tail_csv plugin: The type \"%s\" has %zu data sources. "
"Only types with a single data soure are supported.",
ds->type, ds->ds_num);
continue;
index ceb454ecba7bb6e8579e27044468c876310437e0..14fb5418addc659a5c429c03160ff3ef8e84871a 100644 (file)
gauge_t *rates;
int rates_failed;
- int i;
+ size_t i;
if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
return (-EINVAL);
diff --git a/src/target_replace.c b/src/target_replace.c
index a85eced33532a75b7e81732ec7755ded9d2c1f66..bd8f9e5c51d443650545bc94325fe53df25233e3 100644 (file)
--- a/src/target_replace.c
+++ b/src/target_replace.c
}
subst_status = subst (temp, sizeof (temp), buffer,
- matches[0].rm_so, matches[0].rm_eo, act->replacement);
+ (size_t) matches[0].rm_so, (size_t) matches[0].rm_eo, act->replacement);
if (subst_status == NULL)
{
ERROR ("Target `replace': subst (buffer = %s, start = %zu, end = %zu, "
diff --git a/src/target_scale.c b/src/target_scale.c
index b29a02bfa64801d9e967294ba4d1af7e6ce0cb48..6169fa05d585ce4c7a97abc6c882b80dbbeb78db 100644 (file)
--- a/src/target_scale.c
+++ b/src/target_scale.c
if (failure == 0)
{
- uint64_t difference;
+ uint64_t diff;
double rate;
- /* Calcualte the rate */
- if (prev_counter > curr_counter) /* => counter overflow */
- {
- if (prev_counter <= 4294967295UL) /* 32 bit overflow */
- difference = (4294967295UL - prev_counter) + curr_counter;
- else /* 64 bit overflow */
- difference = (18446744073709551615ULL - prev_counter) + curr_counter;
- }
- else /* no overflow */
- {
- difference = curr_counter - prev_counter;
- }
- rate = ((double) difference) / CDTIME_T_TO_DOUBLE (vl->interval);
+ diff = (uint64_t) counter_diff (prev_counter, curr_counter);
+ rate = ((double) diff) / CDTIME_T_TO_DOUBLE (vl->interval);
/* Modify the rate. */
if (!isnan (data->factor))
/* Calculate the internal counter. */
int_fraction += (rate * CDTIME_T_TO_DOUBLE (vl->interval));
- difference = (uint64_t) int_fraction;
- int_fraction -= ((double) difference);
- int_counter += difference;
+ diff = (uint64_t) int_fraction;
+ int_fraction -= ((double) diff);
+ int_counter += diff;
assert (int_fraction >= 0.0);
assert (int_fraction < 1.0);
notification_meta_t __attribute__((unused)) **meta, void **user_data)
{
ts_data_t *data;
- int i;
+ size_t i;
if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
return (-EINVAL);
diff --git a/src/tcpconns.c b/src/tcpconns.c
index 5d4bb6966f98b024e57ffc7fd0956082777212ab..8f40be6f786b13d901c4ee5847580c0a01db270e 100644 (file)
--- a/src/tcpconns.c
+++ b/src/tcpconns.c
#if KERNEL_LINUX
# include <asm/types.h>
-/* sys/socket.h is necessary to compile when using netlink on older systems. */
-# include <sys/socket.h>
# include <linux/netlink.h>
#if HAVE_LINUX_INET_DIAG_H
# include <linux/inet_diag.h>
#endif
-# include <sys/socket.h>
# include <arpa/inet.h>
/* #endif KERNEL_LINUX */
#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
/* This is for OpenBSD and NetBSD. */
#elif HAVE_LIBKVM_NLIST
# include <sys/queue.h>
-# include <sys/socket.h>
# include <net/route.h>
# include <netinet/in.h>
# include <netinet/in_systm.h>
diff --git a/src/teamspeak2.c b/src/teamspeak2.c
index 201e1828a2b2037093fde4b02c45709a53d6d062..56e8d14e968642d4f632542ac8f9047a3562bf0d 100644 (file)
--- a/src/teamspeak2.c
+++ b/src/teamspeak2.c
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
-#include <sys/socket.h>
#include <netdb.h>
/*
diff --git a/src/ted.c b/src/ted.c
index 5dd75bc924b7bdea84f6664d89e8c85c77f33139..e76b3c9234f70878bf465ada946d6605642fdc86 100644 (file)
--- a/src/ted.c
+++ b/src/ted.c
WARNING ("ted plugin: Received EOF from file descriptor.");
return (-1);
}
- else if (receive_buffer_length > sizeof (receive_buffer))
+ else if (((size_t) receive_buffer_length) > sizeof (receive_buffer))
{
ERROR ("ted plugin: read(2) returned invalid value %zi.",
receive_buffer_length);
diff --git a/src/testing.h b/src/testing.h
index 5df1b83a3e0f076b3a35bff53df09b021b9a0ea5..84a1242953284309fe015df0ee6c43d95e6ba434 100644 (file)
--- a/src/testing.h
+++ b/src/testing.h
/**
* collectd - src/tests/macros.h
- * Copyright (C) 2013 Florian octo Forster
+ * Copyright (C) 2013-2015 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"),
static int fail_count__ = 0;
static int check_count__ = 0;
+#ifndef DBL_PRECISION
+# define DBL_PRECISION 1e-12
+#endif
+
#define DEF_TEST(func) static int test_##func ()
#define RUN_TEST(func) do { \
#define OK1(cond, text) do { \
_Bool result = (cond); \
printf ("%s %i - %s\n", result ? "ok" : "not ok", ++check_count__, text); \
+ if (!result) { return -1; } \
} while (0)
#define OK(cond) OK1(cond, #cond)
printf ("ok %i - %s evaluates to \"%s\"\n", ++check_count__, #actual, expect); \
} while (0)
+#define EXPECT_INTEQ(expect, actual) do { \
+ if ((expect) != (actual)) {\
+ printf ("not ok %i - %s incorrect: expected %d, got %d\n", \
+ ++check_count__, #actual, expect, actual); \
+ return (-1); \
+ } \
+ printf ("ok %i - %s evaluates to %d\n", ++check_count__, #actual, expect); \
+} while (0)
+
+#define DBLEQ(expect, actual) do { \
+ double e = (expect); double a = (actual); \
+ if (isnan (e) && !isnan (a)) { \
+ printf ("not ok %i - %s incorrect: expected %.15g, got %.15g\n", \
+ ++check_count__, #actual, e, a); \
+ return (-1); \
+ } else if (!isnan (e) && (((e-a) < -DBL_PRECISION) || ((e-a) > DBL_PRECISION))) { \
+ printf ("not ok %i - %s incorrect: expected %.15g, got %.15g\n", \
+ ++check_count__, #actual, e, a); \
+ return (-1); \
+ } \
+ printf ("ok %i - %s evaluates to %.15g\n", ++check_count__, #actual, e); \
+} while (0)
+
#define CHECK_NOT_NULL(expr) do { \
void *ptr_; \
ptr_ = (expr); \
diff --git a/src/threshold.c b/src/threshold.c
index 8dcb711d5e6004bb82d266b8d9e950242681c50d..38c7efb016d73a1d62bd10bb3efb0e5670caf1e1 100644 (file)
--- a/src/threshold.c
+++ b/src/threshold.c
{
gauge_t value;
gauge_t sum;
- int i;
+ size_t i;
sum = 0.0;
for (i = 0; i < vl->values_len; i++)
{ /* {{{ */
int ret = -1;
int ds_index = -1;
- int i;
+ size_t i;
gauge_t values_copy[ds->ds_num];
memcpy (values_copy, values, sizeof (values_copy));
diff --git a/src/unixsock.c b/src/unixsock.c
index 664c0184a5d21a793e1fc529dcbe6fbdddfbcde8..e6c75a65644e7441425183fb1b041c9bb93274c0 100644 (file)
--- a/src/unixsock.c
+++ b/src/unixsock.c
/* Folks without pthread will need to disable this plugin. */
#include <pthread.h>
-#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
diff --git a/src/utils_cmd_flush.c b/src/utils_cmd_flush.c
index f19835ef3e4e066e9488ecfc52de95f7392fab5b..8b34a75821def8e9a24bef04475ed0758bcbf09f 100644 (file)
--- a/src/utils_cmd_flush.c
+++ b/src/utils_cmd_flush.c
for (i = 0; (i == 0) || (i < plugins_num); i++)
{
char *plugin = NULL;
- int j;
+ size_t j;
if (plugins_num != 0)
plugin = plugins[i];
diff --git a/src/utils_cmd_getval.c b/src/utils_cmd_getval.c
index 196b45e3267eca52bc7950ebac6b181aaa837d65..8cbb9b21ce6978502c0d7e06ac1cb1e445e3e0fd 100644 (file)
--- a/src/utils_cmd_getval.c
+++ b/src/utils_cmd_getval.c
return (-1);
}
- if ((size_t) ds->ds_num != values_num)
+ if (ds->ds_num != values_num)
{
- ERROR ("ds[%s]->ds_num = %i, "
- "but uc_get_rate_by_name returned %u values.",
- ds->type, ds->ds_num, (unsigned int) values_num);
+ ERROR ("ds[%s]->ds_num = %zu, "
+ "but uc_get_rate_by_name returned %zu values.",
+ ds->type, ds->ds_num, values_num);
print_to_socket (fh, "-1 Error reading value from cache.\n");
sfree (values);
sfree (identifier_copy);
return (-1);
}
- print_to_socket (fh, "%u Value%s found\n", (unsigned int) values_num,
+ print_to_socket (fh, "%zu Value%s found\n", values_num,
(values_num == 1) ? "" : "s");
for (i = 0; i < values_num; i++)
{
diff --git a/src/utils_db_query.c b/src/utils_db_query.c
index 9c84937f38845c34e2f7067fab6317f7d052c3fe..d2b811721d0d6ef2d40453854f87fde4b3c8bf4b 100644 (file)
--- a/src/utils_db_query.c
+++ b/src/utils_db_query.c
BAIL_OUT (-1);
}
- if (((size_t) prep_area->ds->ds_num) != r->values_num)
+ if (prep_area->ds->ds_num != r->values_num)
{
ERROR ("db query utils: udb_result_prepare_result: The type `%s' "
- "requires exactly %i value%s, but the configuration specifies %zu.",
+ "requires exactly %zu value%s, but the configuration specifies %zu.",
r->type,
prep_area->ds->ds_num, (prep_area->ds->ds_num == 1) ? "" : "s",
r->values_num);
diff --git a/src/utils_dns.c b/src/utils_dns.c
index 6abfde16fba0f5cd2da6e1da4f98832717f48519..4c763a1420a04a4008d0d16ce4000e1da9f3aceb 100644 (file)
--- a/src/utils_dns.c
+++ b/src/utils_dns.c
#include "plugin.h"
#include "common.h"
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-
#if HAVE_NET_IF_ARP_H
# include <net/if_arp.h>
#endif
@@ -305,7 +301,7 @@ rfc1035NameUnpack(const char *buf, size_t sz, off_t * off, char *name, size_t ns
if (ns <= 0)
return 4; /* probably compression loop */
do {
- if ((*off) >= sz)
+ if ((*off) >= ((off_t) sz))
break;
c = *(buf + (*off));
if (c > 191) {
@@ -317,11 +313,11 @@ rfc1035NameUnpack(const char *buf, size_t sz, off_t * off, char *name, size_t ns
s = ntohs(s);
(*off) += sizeof(s);
/* Sanity check */
- if ((*off) >= sz)
+ if ((*off) >= ((off_t) sz))
return 1; /* message too short */
ptr = s & 0x3FFF;
/* Make sure the pointer is inside this message */
- if (ptr >= sz)
+ if (ptr >= ((off_t) sz))
return 2; /* bad compression ptr */
if (ptr < DNS_MSG_HDR_SZ)
return 2; /* bad compression ptr */
@@ -355,7 +351,7 @@ rfc1035NameUnpack(const char *buf, size_t sz, off_t * off, char *name, size_t ns
if (no > 0)
*(name + no - 1) = '\0';
/* make sure we didn't allow someone to overflow the name buffer */
- assert(no <= ns);
+ assert(no <= ((off_t) ns));
return 0;
}
index 023f7a46a5240f7a7f52e3c9d6f237c91f932223..eb5b4b327119210c4f2c6424ae99c47b3ec1dc5a 100644 (file)
unsigned int flags)
{
int status = 0;
- int i;
+ size_t i;
int buffer_pos = 0;
gauge_t *rates = NULL;
index 10a5343f2c11bb0a1eba7454eb663a41eacd4a7a..122c7f86a73f6ddf16d04c0403581b74d9a4c03f 100644 (file)
--- a/src/utils_format_json.c
+++ b/src/utils_format_json.c
const data_set_t *ds, const value_list_t *vl, int store_rates)
{
size_t offset = 0;
- int i;
+ size_t i;
gauge_t *rates = NULL;
memset (buffer, 0, buffer_size);
const data_set_t *ds)
{
size_t offset = 0;
- int i;
+ size_t i;
memset (buffer, 0, buffer_size);
const data_set_t *ds)
{
size_t offset = 0;
- int i;
+ size_t i;
memset (buffer, 0, buffer_size);
diff --git a/src/utils_ignorelist.c b/src/utils_ignorelist.c
index 7b1c7d2547e915db1931eecdbeb9e34590e9e117..a8ca7dbb7f3aecbb2c6ea90519c2583aae0c30f5 100644 (file)
--- a/src/utils_ignorelist.c
+++ b/src/utils_ignorelist.c
@@ -89,69 +89,45 @@ static inline void ignorelist_append (ignorelist_t *il, ignorelist_item_t *item)
}
#if HAVE_REGEX_H
-static int ignorelist_append_regex(ignorelist_t *il, const char *entry)
+static int ignorelist_append_regex(ignorelist_t *il, const char *re_str)
{
- int rcompile;
- regex_t *regtemp;
- int errsize;
- char *regerr = NULL;
- ignorelist_item_t *new;
+ regex_t *re;
+ ignorelist_item_t *entry;
+ int status;
- /* create buffer */
- if ((regtemp = malloc(sizeof(regex_t))) == NULL)
+ re = malloc (sizeof (*re));
+ if (re == NULL)
{
- ERROR ("cannot allocate new config entry");
- return (1);
+ ERROR ("utils_ignorelist: malloc failed");
+ return (ENOMEM);
}
- memset (regtemp, '\0', sizeof(regex_t));
+ memset (re, 0, sizeof (*re));
- /* compile regex */
- if ((rcompile = regcomp (regtemp, entry, REG_EXTENDED)) != 0)
+ status = regcomp (re, re_str, REG_EXTENDED);
+ if (status != 0)
{
- /* prepare message buffer */
- errsize = regerror(rcompile, regtemp, NULL, 0);
- if (errsize)
- regerr = smalloc(errsize);
- /* get error message */
- if (regerror (rcompile, regtemp, regerr, errsize))
- {
- fprintf (stderr, "Cannot compile regex %s: %i/%s",
- entry, rcompile, regerr);
- ERROR ("Cannot compile regex %s: %i/%s",
- entry, rcompile, regerr);
- }
- else
- {
- fprintf (stderr, "Cannot compile regex %s: %i",
- entry, rcompile);
- ERROR ("Cannot compile regex %s: %i",
- entry, rcompile);
- }
-
- if (errsize)
- sfree (regerr);
- regfree (regtemp);
- sfree (regtemp);
- return (1);
+ char errbuf[1024] = "";
+ regerror (status, re, errbuf, sizeof (errbuf));
+ ERROR ("utils_ignorelist: regcomp failed: %s", errbuf);
+ regfree (re);
+ sfree (re);
+ return (status);
}
- DEBUG("regex compiled: %s - %i", entry, rcompile);
- /* create new entry */
- if ((new = malloc(sizeof(ignorelist_item_t))) == NULL)
+ entry = malloc (sizeof (*entry));
+ if (entry == NULL)
{
- ERROR ("cannot allocate new config entry");
- regfree (regtemp);
- sfree (regtemp);
- return (1);
+ ERROR ("utils_ignorelist: malloc failed");
+ regfree (re);
+ sfree (re);
+ return (ENOMEM);
}
- memset (new, '\0', sizeof(ignorelist_item_t));
- new->rmatch = regtemp;
-
- /* append new entry */
- ignorelist_append (il, new);
+ memset (entry, 0, sizeof (*entry));
+ entry->rmatch = re;
+ ignorelist_append (il, entry);
return (0);
-} /* int ignorelist_append_regex(ignorelist_t *il, const char *entry) */
+} /* int ignorelist_append_regex */
#endif
static int ignorelist_append_string(ignorelist_t *il, const char *entry)
/*
* append entry into ignorelist_t
- * return 1 for success
+ * return 0 for success
*/
int ignorelist_add (ignorelist_t *il, const char *entry)
{
- int ret;
size_t entry_len;
if (il == NULL)
{
char *entry_copy;
size_t entry_copy_size;
+ int status;
/* We need to copy `entry' since it's const */
entry_copy_size = entry_len - 1;
entry_copy = smalloc (entry_copy_size);
sstrncpy (entry_copy, entry + 1, entry_copy_size);
- DEBUG("I'm about to add regex entry: %s", entry_copy);
- ret = ignorelist_append_regex(il, entry_copy);
+ status = ignorelist_append_regex(il, entry_copy);
sfree (entry_copy);
+ return status;
}
- else
#endif
- {
- DEBUG("to add entry: %s", entry);
- ret = ignorelist_append_string(il, entry);
- }
- return (ret);
+ return ignorelist_append_string(il, entry);
} /* int ignorelist_add (ignorelist_t *il, const char *entry) */
/*
diff --git a/src/utils_latency_test.c b/src/utils_latency_test.c
--- /dev/null
+++ b/src/utils_latency_test.c
@@ -0,0 +1,108 @@
+/**
+ * collectd - src/utils_latency_test.c
+ * Copyright (C) 2015 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>
+ */
+
+#define DBL_PRECISION 1e-9
+
+#include "testing.h"
+#include "collectd.h"
+#include "common.h" /* for STATIC_ARRAY_SIZE */
+#include "utils_time.h"
+#include "utils_latency.h"
+
+DEF_TEST(simple)
+{
+ struct {
+ double val;
+ double min;
+ double max;
+ double sum;
+ double avg;
+ } cases[] = {
+ /* val min max sum avg */
+ {0.5, 0.5, 0.5, 0.5, 0.5},
+ {0.3, 0.3, 0.5, 0.8, 0.4},
+ {0.7, 0.3, 0.7, 1.5, 0.5},
+ {2.5, 0.3, 2.5, 4.0, 1.0},
+ { 99, 0.3, 99, 103, 20.6},
+ /* { -1, 0.3, 99, 103, 20.6}, see issue #1139 */
+ };
+ size_t i;
+ latency_counter_t *l;
+
+ CHECK_NOT_NULL (l = latency_counter_create ());
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ printf ("# case %zu: DOUBLE_TO_CDTIME_T(%g) = %"PRIu64"\n",
+ i, cases[i].val, DOUBLE_TO_CDTIME_T (cases[i].val));
+ latency_counter_add (l, DOUBLE_TO_CDTIME_T (cases[i].val));
+
+ DBLEQ (cases[i].min, CDTIME_T_TO_DOUBLE (latency_counter_get_min (l)));
+ DBLEQ (cases[i].max, CDTIME_T_TO_DOUBLE (latency_counter_get_max (l)));
+ DBLEQ (cases[i].sum, CDTIME_T_TO_DOUBLE (latency_counter_get_sum (l)));
+ DBLEQ (cases[i].avg, CDTIME_T_TO_DOUBLE (latency_counter_get_average (l)));
+ }
+
+ latency_counter_destroy (l);
+ return 0;
+}
+
+DEF_TEST(percentile)
+{
+ size_t i;
+ latency_counter_t *l;
+
+ CHECK_NOT_NULL (l = latency_counter_create ());
+
+ for (i = 0; i < 100; i++) {
+ latency_counter_add (l, TIME_T_TO_CDTIME_T (((time_t) i) + 1));
+ }
+
+ DBLEQ ( 1.0, CDTIME_T_TO_DOUBLE (latency_counter_get_min (l)));
+ DBLEQ (100.0, CDTIME_T_TO_DOUBLE (latency_counter_get_max (l)));
+ DBLEQ (100.0 * 101.0 / 2.0, CDTIME_T_TO_DOUBLE (latency_counter_get_sum (l)));
+ DBLEQ ( 50.5, CDTIME_T_TO_DOUBLE (latency_counter_get_average (l)));
+
+ DBLEQ (50.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 50.0)));
+ DBLEQ (80.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 80.0)));
+ DBLEQ (95.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 95.0)));
+ DBLEQ (99.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 99.0)));
+
+ CHECK_ZERO (latency_counter_get_percentile (l, -1.0));
+ CHECK_ZERO (latency_counter_get_percentile (l, 101.0));
+
+ latency_counter_destroy (l);
+ return 0;
+}
+
+int main (void)
+{
+ RUN_TEST(simple);
+ RUN_TEST(percentile);
+
+ END_TEST;
+}
+
+/* vim: set sw=2 sts=2 et : */
diff --git a/src/utils_rrdcreate.c b/src/utils_rrdcreate.c
index 5add32373cd3d91f861265df88dc459d4bb57c99..39f42b205a2c5e22510445dfcea84c107ed29748 100644 (file)
--- a/src/utils_rrdcreate.c
+++ b/src/utils_rrdcreate.c
const rrdcreate_config_t *cfg)
{
char **ds_def;
- int ds_num;
+ size_t ds_num;
char min[32];
char max[32];
index 6a2676a89e1d8ccee1cddc6735d2f5e7d9335ff7..41cc0a41af3a26c2ac7841178ca88289cd284f01 100644 (file)
identifier_t *class = user_class;
identifier_t *obj;
- OK(expect_new_obj);
+ assert (expect_new_obj);
memcpy (&last_class_ident, class, sizeof (last_class_ident));
return ((void *) obj);
}
-static void checked_lookup_add (lookup_t *obj, /* {{{ */
+static int checked_lookup_add (lookup_t *obj, /* {{{ */
char const *host,
char const *plugin, char const *plugin_instance,
char const *type, char const *type_instance,
memmove (user_class, &ident, sizeof (ident));
OK(lookup_add (obj, &ident, group_by, user_class) == 0);
-} /* }}} void test_add */
+ return 0;
+} /* }}} int checked_lookup_add */
static int checked_lookup_search (lookup_t *obj,
char const *host,
return (status);
}
-static lookup_t *checked_lookup_create (void)
-{
- lookup_t *obj = lookup_create (
- lookup_class_callback,
- lookup_obj_callback,
- (void *) free,
- (void *) free);
- OK(obj != NULL);
- return (obj);
-}
-
DEF_TEST(group_by_specific_host)
{
- lookup_t *obj = checked_lookup_create ();
+ lookup_t *obj;
+ CHECK_NOT_NULL (obj = lookup_create (
+ lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free));
checked_lookup_add (obj, "/.*/", "test", "", "test", "/.*/", LU_GROUP_BY_HOST);
checked_lookup_search (obj, "host0", "test", "", "test", "0",
DEF_TEST(group_by_any_host)
{
- lookup_t *obj = checked_lookup_create ();
+ lookup_t *obj;
+ CHECK_NOT_NULL (obj = lookup_create (
+ lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free));
checked_lookup_add (obj, "/.*/", "/.*/", "/.*/", "test", "/.*/", LU_GROUP_BY_HOST);
checked_lookup_search (obj, "host0", "plugin0", "", "test", "0",
DEF_TEST(multiple_lookups)
{
- lookup_t *obj = checked_lookup_create ();
+ lookup_t *obj;
int status;
+ CHECK_NOT_NULL (obj = lookup_create (
+ lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free));
+
checked_lookup_add (obj, "/.*/", "plugin0", "", "test", "/.*/", LU_GROUP_BY_HOST);
checked_lookup_add (obj, "/.*/", "/.*/", "", "test", "ti0", LU_GROUP_BY_HOST);
DEF_TEST(regex)
{
- lookup_t *obj = checked_lookup_create ();
+ lookup_t *obj;
+ CHECK_NOT_NULL (obj = lookup_create (
+ lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free));
checked_lookup_add (obj, "/^db[0-9]\\./", "cpu", "/.*/", "cpu", "/.*/",
LU_GROUP_BY_TYPE_INSTANCE);
diff --git a/src/varnish.c b/src/varnish.c
index 1089222327ac8a61f540f4a27d333ed1455c6a66..c6c4df05d413b97fe2ee1de80d81b3c42f29e2e1 100644 (file)
--- a/src/varnish.c
+++ b/src/varnish.c
plugin_register_complex_read (/* group = */ "varnish",
/* name = */ "varnish/localhost",
/* callback = */ varnish_read,
- /* interval = */ NULL,
+ /* interval = */ 0,
/* user data = */ &ud);
return (0);
plugin_register_complex_read (/* group = */ "varnish",
/* name = */ callback_name,
/* callback = */ varnish_read,
- /* interval = */ NULL,
+ /* interval = */ 0,
/* user data = */ &ud);
have_instance = 1;
diff --git a/src/write_graphite.c b/src/write_graphite.c
index 41451a8cee8f8d0bab4dda5d81361b3efd30a229..7fc9eb9f90921d1c1887295fd912dfd659b01b32 100644 (file)
--- a/src/write_graphite.c
+++ b/src/write_graphite.c
/* Folks without pthread will need to disable this plugin. */
#include <pthread.h>
-#include <sys/socket.h>
#include <netdb.h>
-#ifndef WG_DEFAULT_NODE
-# define WG_DEFAULT_NODE "localhost"
-#endif
-
-#ifndef WG_DEFAULT_SERVICE
-# define WG_DEFAULT_SERVICE "2003"
-#endif
-
-#ifndef WG_DEFAULT_PROTOCOL
-# define WG_DEFAULT_PROTOCOL "tcp"
-#endif
-
-#ifndef WG_DEFAULT_LOG_SEND_ERRORS
-# define WG_DEFAULT_LOG_SEND_ERRORS 1
-#endif
-
-#ifndef WG_DEFAULT_ESCAPE
-# define WG_DEFAULT_ESCAPE '_'
-#endif
+#define WG_DEFAULT_NODE "localhost"
+#define WG_DEFAULT_SERVICE "2003"
+#define WG_DEFAULT_PROTOCOL "tcp"
+#define WG_DEFAULT_LOG_SEND_ERRORS 1
+#define WG_DEFAULT_ESCAPE '_'
/* Ethernet - (IPv6 + TCP) = 1500 - (40 + 32) = 1428 */
-#ifndef WG_SEND_BUF_SIZE
-# define WG_SEND_BUF_SIZE 1428
-#endif
+#define WG_SEND_BUF_SIZE 1428
-#ifndef WG_MIN_RECONNECT_INTERVAL
-# define WG_MIN_RECONNECT_INTERVAL TIME_T_TO_CDTIME_T (1)
-#endif
+#define WG_MIN_RECONNECT_INTERVAL TIME_T_TO_CDTIME_T (1)
/*
* Private variables
status = swrite (cb->sock_fd, cb->send_buf, strlen (cb->send_buf));
if (status < 0)
{
- const char *protocol = cb->protocol ? cb->protocol : WG_DEFAULT_PROTOCOL;
-
if (cb->log_send_errors)
{
char errbuf[1024];
ERROR ("write_graphite plugin: send to %s:%s (%s) failed with status %zi (%s)",
- cb->node, cb->service, protocol,
+ cb->node, cb->service, cb->protocol,
status, sstrerror (errno, errbuf, sizeof (errbuf)));
}
cdtime_t now;
int status;
- const char *node = cb->node ? cb->node : WG_DEFAULT_NODE;
- const char *service = cb->service ? cb->service : WG_DEFAULT_SERVICE;
- const char *protocol = cb->protocol ? cb->protocol : WG_DEFAULT_PROTOCOL;
-
char connerr[1024] = "";
if (cb->sock_fd > 0)
#endif
ai_hints.ai_family = AF_UNSPEC;
- if (0 == strcasecmp ("tcp", protocol))
+ if (0 == strcasecmp ("tcp", cb->protocol))
ai_hints.ai_socktype = SOCK_STREAM;
else
ai_hints.ai_socktype = SOCK_DGRAM;
ai_list = NULL;
- status = getaddrinfo (node, service, &ai_hints, &ai_list);
+ status = getaddrinfo (cb->node, cb->service, &ai_hints, &ai_list);
if (status != 0)
{
ERROR ("write_graphite plugin: getaddrinfo (%s, %s, %s) failed: %s",
- node, service, protocol, gai_strerror (status));
+ cb->node, cb->service, cb->protocol, gai_strerror (status));
return (-1);
}
sstrerror (errno, connerr, sizeof (connerr));
c_complain (LOG_ERR, &cb->init_complaint,
"write_graphite plugin: Connecting to %s:%s via %s failed. "
- "The last error was: %s", node, service, protocol, connerr);
+ "The last error was: %s", cb->node, cb->service, cb->protocol, connerr);
return (-1);
}
else
{
c_release (LOG_INFO, &cb->init_complaint,
"write_graphite plugin: Successfully connected to %s:%s via %s.",
- node, service, protocol);
+ cb->node, cb->service, cb->protocol);
}
wg_reset_buffer (cb);
cb->send_buf_free -= message_len;
DEBUG ("write_graphite plugin: [%s]:%s (%s) buf %zu/%zu (%.1f %%) \"%s\"",
- cb->node,
- cb->service,
- cb->protocol,
+ cb->node, cb->service, cb->protocol,
cb->send_buf_fill, sizeof (cb->send_buf),
100.0 * ((double) cb->send_buf_fill) / ((double) sizeof (cb->send_buf)),
message);
memset (cb, 0, sizeof (*cb));
cb->sock_fd = -1;
cb->name = NULL;
- cb->node = NULL;
- cb->service = NULL;
- cb->protocol = NULL;
+ cb->node = strdup (WG_DEFAULT_NODE);
+ cb->service = strdup (WG_DEFAULT_SERVICE);
+ cb->protocol = strdup (WG_DEFAULT_PROTOCOL);
cb->log_send_errors = WG_DEFAULT_LOG_SEND_ERRORS;
cb->prefix = NULL;
cb->postfix = NULL;
/* FIXME: Legacy configuration syntax. */
if (cb->name == NULL)
ssnprintf (callback_name, sizeof (callback_name), "write_graphite/%s/%s/%s",
- cb->node != NULL ? cb->node : WG_DEFAULT_NODE,
- cb->service != NULL ? cb->service : WG_DEFAULT_SERVICE,
- cb->protocol != NULL ? cb->protocol : WG_DEFAULT_PROTOCOL);
+ cb->node, cb->service, cb->protocol);
else
ssnprintf (callback_name, sizeof (callback_name), "write_graphite/%s",
cb->name);
diff --git a/src/write_log.c b/src/write_log.c
index e37aae9fd594fcce3ecd6d5abac7a6fb33adf32c..ebf0e12445cc9e9e3900a8416c3cedcf6db1a9eb 100644 (file)
--- a/src/write_log.c
+++ b/src/write_log.c
/* Folks without pthread will need to disable this plugin. */
#include <pthread.h>
-#include <sys/socket.h>
#include <netdb.h>
#define WL_BUF_SIZE 8192
diff --git a/src/write_redis.c b/src/write_redis.c
index 2a6f9124aee0f9a66e3c6a004d8456442d7a067b..7ba476c92fa2164322c4d3ad5ba73b64ea67e322 100644 (file)
--- a/src/write_redis.c
+++ b/src/write_redis.c
/**
* collectd - src/write_redis.c
- * Copyright (C) 2010 Florian Forster
+ * Copyright (C) 2010-2015 Florian Forster
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
#include <sys/time.h>
#include <hiredis/hiredis.h>
+#ifndef REDIS_DEFAULT_PREFIX
+# define REDIS_DEFAULT_PREFIX "collectd/"
+#endif
+
struct wr_node_s
{
char name[DATA_MAX_NAME_LEN];
char *host;
int port;
struct timeval timeout;
+ char *prefix;
+ int database;
redisContext *conn;
pthread_mutex_t lock;
status = FORMAT_VL (ident, sizeof (ident), vl);
if (status != 0)
return (status);
- ssnprintf (key, sizeof (key), "collectd/%s", ident);
+ 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));
memset (value, 0, sizeof (value));
pthread_mutex_unlock (&node->lock);
return (-1);
}
+
+ rr = redisCommand(node->conn, "SELECT %d", node->database);
+ if (rr == NULL)
+ WARNING("SELECT command error. database:%d message:%s", node->database, node->conn->errstr);
+ else
+ freeReplyObject (rr);
}
rr = redisCommand (node->conn, "ZADD %s %s %s", key, time, value);
/* 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. */
- rr = redisCommand (node->conn, "SADD collectd/values %s", ident);
+ rr = redisCommand (node->conn, "SADD %svalues %s",
+ (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX,
+ ident);
if (rr==NULL)
WARNING("SADD command error. ident:%s message:%s", ident, node->conn->errstr);
else
node->timeout.tv_sec = 0;
node->timeout.tv_usec = 1000;
node->conn = NULL;
+ node->prefix = NULL;
+ node->database = 0;
pthread_mutex_init (&node->lock, /* attr = */ NULL);
status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name));
status = cf_util_get_int (child, &timeout);
if (status == 0) node->timeout.tv_usec = timeout;
}
+ else if (strcasecmp ("Prefix", child->key) == 0) {
+ status = cf_util_get_string (child, &node->prefix);
+ }
+ else if (strcasecmp ("Database", child->key) == 0) {
+ status = cf_util_get_int (child, &node->database);
+ }
else
WARNING ("write_redis plugin: Ignoring unknown config option \"%s\".",
child->key);
diff --git a/src/write_riemann.c b/src/write_riemann.c
index a09c72361f910ac8615a219fd9187da36e77a819..73d202c42fe8f228aaea46279dd12827a16d0371 100644 (file)
--- a/src/write_riemann.c
+++ b/src/write_riemann.c
#include "utils_cache.h"
#include "riemann.pb-c.h"
-#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
@@ -365,7 +364,7 @@ static Msg *riemann_notification_to_protobuf(struct riemann_host *host, /* {{{ *
char service_buffer[6 * DATA_MAX_NAME_LEN];
char const *severity;
notification_meta_t *meta;
- int i;
+ size_t i;
msg = malloc (sizeof (*msg));
if (msg == NULL)
char name_buffer[5 * DATA_MAX_NAME_LEN];
char service_buffer[6 * DATA_MAX_NAME_LEN];
double ttl;
- int i;
+ size_t i;
event = malloc (sizeof (*event));
if (event == NULL)
msg__init (msg);
/* Set up events. First, the list of pointers. */
- msg->n_events = (size_t) vl->values_len;
+ msg->n_events = vl->values_len;
msg->events = calloc (msg->n_events, sizeof (*msg->events));
if (msg->events == NULL)
{
len = msg__get_packed_size(host->batch_msg);
ret = 0;
- if (len >= host->batch_max) {
- ret = riemann_batch_flush_nolock(0, host);
+ if ((host->batch_max < 0) || (((size_t) host->batch_max) <= len)) {
+ ret = riemann_batch_flush_nolock(0, host);
}
pthread_mutex_unlock(&host->lock);
@@ -778,35 +777,35 @@ static int riemann_notification(const notification_t *n, user_data_t *ud) /* {{{
} /* }}} int riemann_notification */
static int riemann_write(const data_set_t *ds, /* {{{ */
- const value_list_t *vl,
- user_data_t *ud)
+ const value_list_t *vl,
+ user_data_t *ud)
{
int status = 0;
int statuses[vl->values_len];
struct riemann_host *host = ud->data;
- Msg *msg;
-
- if (host->check_thresholds)
- write_riemann_threshold_check(ds, vl, statuses);
-
- if (host->use_tcp == 1 && host->batch_mode) {
-
- riemann_batch_add_value_list (host, ds, vl, statuses);
+ if (host->check_thresholds) {
+ status = write_riemann_threshold_check(ds, vl, statuses);
+ if (status != 0)
+ return status;
+ } else {
+ memset (statuses, 0, sizeof (statuses));
+ }
- } else {
+ if (host->use_tcp == 1 && host->batch_mode) {
+ riemann_batch_add_value_list (host, ds, vl, statuses);
+ } else {
+ Msg *msg = riemann_value_list_to_protobuf (host, ds, vl, statuses);
+ if (msg == NULL)
+ return (-1);
- msg = riemann_value_list_to_protobuf (host, ds, vl, statuses);
- if (msg == NULL)
- return (-1);
+ status = riemann_send (host, msg);
+ if (status != 0)
+ ERROR ("write_riemann plugin: riemann_send failed with status %i", status);
- status = riemann_send (host, msg);
- if (status != 0)
- ERROR ("write_riemann plugin: riemann_send failed with status %i",
- status);
+ riemann_msg_protobuf_free (msg);
+ }
- riemann_msg_protobuf_free (msg);
- }
return status;
} /* }}} int riemann_write */
index 6d5af032565b909f8448811cc0aa8dc6167265d9..5c8559eb7b157414cd86df73a07ae25ab4e6927b 100644 (file)
int *statuses)
{ /* {{{ */
int ret = -1;
- int i;
+ size_t i;
int status;
gauge_t values_copy[ds->ds_num];
@@ -202,7 +202,9 @@ int write_riemann_threshold_check (const data_set_t *ds, const value_list_t *vl,
gauge_t *values;
int status;
+ assert (vl->values_len > 0);
memset(statuses, 0, vl->values_len * sizeof(*statuses));
+
if (threshold_tree == NULL)
return 0;
diff --git a/src/write_sensu.c b/src/write_sensu.c
index f7803e86a24cf1194dd7ee2d1651b1a4d8628694..67c04969227302c4f7f81dc0bafa2016587bd32a 100644 (file)
--- a/src/write_sensu.c
+++ b/src/write_sensu.c
#include "common.h"
#include "configfile.h"
#include "utils_cache.h"
-#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
{
char name_buffer[5 * DATA_MAX_NAME_LEN];
char service_buffer[6 * DATA_MAX_NAME_LEN];
- int i;
+ size_t i;
char *ret_str;
char *temp_str;
char *value_str;
char *ret_str;
char *temp_str;
int status;
- int i;
+ size_t i;
int res;
// add the severity/status
switch (n->severity) {
int statuses[vl->values_len];
struct sensu_host *host = ud->data;
gauge_t *rates = NULL;
- int i;
+ size_t i;
char *msg;
pthread_mutex_lock(&host->lock);
return -1;
}
}
- for (i = 0; i < (size_t) vl->values_len; i++) {
+ for (i = 0; i < vl->values_len; i++) {
msg = sensu_value_to_json(host, ds, vl, (int) i, rates, statuses[i]);
if (msg == NULL) {
sfree(rates);
diff --git a/src/write_tsdb.c b/src/write_tsdb.c
index 27ea4738051c9d6f6192b5cb76149816a5831c8a..4a626144f60498c2cd3a83fafba728c8b82b9b1b 100644 (file)
--- a/src/write_tsdb.c
+++ b/src/write_tsdb.c
#include "utils_cache.h"
#include <pthread.h>
-#include <sys/socket.h>
#include <netdb.h>
#ifndef WT_DEFAULT_NODE
const char* host, meta_data_t *md)
{
int status;
- int message_len;
+ size_t message_len;
char *temp = NULL;
char *tags = "";
char message[1024];
}
}
- message_len = ssnprintf (message,
+ status = ssnprintf (message,
sizeof(message),
"put %s %.0f %s fqdn=%s %s %s\r\n",
key,
host,
tags,
host_tags);
-
sfree(temp);
+ if (status < 0)
+ return -1;
+ message_len = (size_t) status;
if (message_len >= sizeof(message)) {
ERROR("write_tsdb plugin: message buffer too small: "
- "Need %d bytes.", message_len + 1);
+ "Need %zu bytes.", message_len + 1);
return -1;
}
char key[10*DATA_MAX_NAME_LEN];
char values[512];
- int status, i;
+ int status;
+ size_t i;
if (0 != strcmp(ds->type, vl->type))
{
diff --git a/src/zone.c b/src/zone.c
--- /dev/null
+++ b/src/zone.c
@@ -0,0 +1,214 @@
+/**
+ * collectd - src/zone.c
+ * Copyright (C) 2011 Mathijs Mohlmann
+ *
+ * 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:
+ * Mathijs Mohlmann
+ * Dagobert Michelsen (forward-porting)
+ **/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+# undef HAVE_CONFIG_H
+#endif
+/* avoid procfs.h error "Cannot use procfs in the large file compilation environment" */
+#if !defined(_LP64) && _FILE_OFFSET_BITS == 64
+# undef _FILE_OFFSET_BITS
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+#include <sys/types.h>
+#include <sys/vm_usage.h>
+#include <procfs.h>
+#include <zone.h>
+
+#include "utils_avltree.h"
+
+#define MAX_PROCFS_PATH 40
+#define FRC2PCT(pp)(((float)(pp))/0x8000*100)
+
+typedef struct zone_stats {
+ ushort_t pctcpu;
+ ushort_t pctmem;
+} zone_stats_t;
+
+static long pagesize;
+
+static int zone_init (void)
+{
+ pagesize = sysconf(_SC_PAGESIZE);
+ return (0);
+}
+
+static int
+zone_compare(const zoneid_t *a, const zoneid_t *b)
+{
+ if (*a == *b)
+ return(0);
+ if (*a < *b)
+ return(-1);
+ return(1);
+}
+
+static int
+zone_read_procfile(char const *pidstr, char const *name, void *buf, size_t bufsize)
+{
+ int fd;
+
+ char procfile[MAX_PROCFS_PATH];
+ (void)snprintf(procfile, sizeof(procfile), "/proc/%s/%s", pidstr, name);
+ if ((fd = open(procfile, O_RDONLY)) == -1) {
+ return (1);
+ }
+
+ if (sread(fd, buf, bufsize) != 0) {
+ char errbuf[1024];
+ ERROR ("zone plugin: Reading \"%s\" failed: %s", procfile,
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ close(fd);
+ return (1);
+ }
+
+ close(fd);
+ return (0);
+}
+
+static int
+zone_submit_value(char *zone, gauge_t value)
+{
+ value_list_t vl = VALUE_LIST_INIT;
+ value_t values[1];
+
+ values[0].gauge = value;
+
+ vl.values = values;
+ vl.values_len = 1; /*STATIC_ARRAY_SIZE (values);*/
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "zone", sizeof (vl.plugin));
+ sstrncpy (vl.type, "percent", sizeof (vl.type));
+ sstrncpy (vl.type_instance, zone, sizeof (vl.type_instance));
+
+ return(plugin_dispatch_values (&vl));
+}
+
+static zone_stats_t *
+zone_find_stats(c_avl_tree_t *tree, zoneid_t zoneid)
+{
+ zone_stats_t *ret = NULL;
+ zoneid_t *key = NULL;
+
+ if (c_avl_get(tree, (void **)&zoneid, (void **)&ret)) {
+ if (!(ret = malloc(sizeof(zone_stats_t)))) {
+ WARNING("zone plugin: no memory");
+ return(NULL);
+ }
+ if (!(key = malloc(sizeof(zoneid_t)))) {
+ WARNING("zone plugin: no memory");
+ return(NULL);
+ }
+ *key = zoneid;
+ if (c_avl_insert(tree, key, ret)) {
+ WARNING("zone plugin: error inserting into tree");
+ return(NULL);
+ }
+ }
+ return(ret);
+}
+
+static void
+zone_submit_values(c_avl_tree_t *tree)
+{
+ char zonename[ZONENAME_MAX];
+ zoneid_t *zoneid = NULL;
+ zone_stats_t *stats = NULL;
+
+ while (c_avl_pick (tree, (void **)&zoneid, (void **)&stats) == 0)
+ {
+ if (getzonenamebyid(*zoneid, zonename, sizeof( zonename )) == -1) {
+ WARNING("zone plugin: error retreiving zonename");
+ } else {
+ zone_submit_value(zonename, (gauge_t)FRC2PCT(stats->pctcpu));
+ }
+ free(stats);
+ free(zoneid);
+ }
+ c_avl_destroy(tree);
+}
+
+static c_avl_tree_t *
+zone_scandir(DIR *procdir)
+{
+ pid_t pid;
+ dirent_t *direntp;
+ psinfo_t psinfo;
+ c_avl_tree_t *tree;
+ zone_stats_t *stats;
+
+ if (!(tree=c_avl_create((void *) zone_compare))) {
+ WARNING("zone plugin: Failed to create tree");
+ return(NULL);
+ }
+
+ rewinddir(procdir);
+ while ((direntp = readdir(procdir))) {
+ char const *pidstr = direntp->d_name;
+ if (pidstr[0] == '.') /* skip "." and ".." */
+ continue;
+
+ pid = atoi(pidstr);
+ if (pid == 0 || pid == 2 || pid == 3)
+ continue; /* skip sched, pageout and fsflush */
+
+ if (zone_read_procfile(pidstr, "psinfo", &psinfo, sizeof(psinfo_t)) != 0)
+ continue;
+
+ stats = zone_find_stats(tree, psinfo.pr_zoneid);
+ if( stats ) {
+ stats->pctcpu += psinfo.pr_pctcpu;
+ stats->pctmem += psinfo.pr_pctmem;
+ }
+ }
+ return(tree);
+}
+
+static int zone_read (void)
+{
+ DIR *procdir;
+ c_avl_tree_t *tree;
+
+ if ((procdir = opendir("/proc")) == NULL) {
+ ERROR("zone plugin: cannot open /proc directory\n");
+ return (-1);
+ }
+
+ tree=zone_scandir(procdir);
+ closedir(procdir);
+ if (tree == NULL) {
+ return (-1);
+ }
+ zone_submit_values(tree); /* this also frees tree */
+ return (0);
+}
+
+void module_register (void)
+{
+ plugin_register_init ("zone", zone_init);
+ plugin_register_read ("zone", zone_read);
+} /* void module_register */
diff --git a/src/zookeeper.c b/src/zookeeper.c
index 63ee6c90040596ec54198ee2a11909611dc04ad0..abdbf20f3361d257165d4697346e98213caeca11 100644 (file)
--- a/src/zookeeper.c
+++ b/src/zookeeper.c
#include "plugin.h"
#include <netdb.h>
-#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/tcp.h>