AC_DEFINE([KERNEL_SOLARIS], [1], [True if program is to be compiled for a Solaris kernel])
ac_system="Solaris"
;;
+ *mingw32*)
+ AC_DEFINE([KERNEL_WIN32], [1], [True if program is to be compiled for a Windows kernel])
+ ac_system="Windows"
+ ;;
*)
ac_system="unknown"
;;
AM_CONDITIONAL([BUILD_LINUX], [test "x$ac_system" = "xLinux"])
AM_CONDITIONAL([BUILD_OPENBSD], [test "x$ac_system" = "xOpenBSD"])
AM_CONDITIONAL([BUILD_SOLARIS], [test "x$ac_system" = "xSolaris"])
+AM_CONDITIONAL([BUILD_WIN32], [test "x$ac_system" = "xWindows"])
if test "x$ac_system" = "xSolaris"; then
AC_DEFINE([_POSIX_PTHREAD_SEMANTICS], [1], [Define to enforce POSIX thread semantics under Solaris.])
AC_DEFINE([HAVE_CAPABILITY], [1], [Define to 1 if you have cap_get_proc() (-lcap).])
fi
+ # For pcie_errors plugin
+ AC_CHECK_HEADERS([linux/pci_regs.h],
+ [have_pci_regs_h="yes"],
+ [have_pci_regs_h="no (linux/pci_regs.h not found)"]
+ )
+
else
have_linux_raid_md_u_h="no"
have_linux_wireless_h="no"
getaddrinfo \
getgrnam_r \
getnameinfo \
+ getpwnam \
getpwnam_r \
gettimeofday \
if_indextoname \
AC_FUNC_STRERROR_R
SAVE_CFLAGS="$CFLAGS"
-# Emulate behavior of src/Makefile.am
-if test "x$GCC" = "xyes"; then
- CFLAGS="$CFLAGS -Wall -Werror"
+CFLAGS="-Wall -Werror"
+SAVE_LDFLAGS="$LDFLAGS"
+LDFLAGS=""
+if test "x$ac_system" = "xWindows"; then
+ # This is exported from build.sh
+ LDFLAGS="$LDFLAGS -L${GNULIB_DIR}"
fi
AC_CACHE_CHECK([for strtok_r],
fi
CFLAGS="$SAVE_CFLAGS"
+LDFLAGS="$SAVE_LDFLAGS"
if test "x$c_cv_have_strtok_r_reentrant" = "xyes"; then
CFLAGS="$CFLAGS -D_REENTRANT=1"
fi
[
AC_CHECK_LIB([socket], [socket],
[socket_needs_socket="yes"],
- [AC_MSG_ERROR([cannot find socket() in libsocket])]
+ [
+ AC_CHECK_LIB([gnu], [rpl_socket],
+ [socket_needs_gnulib="yes"],
+ [AC_MSG_ERROR([cannot find socket() in libsocket])]
+ )
+ ]
)
]
)
AM_CONDITIONAL([BUILD_WITH_LIBSOCKET], [test "x$socket_needs_socket" = "xyes"])
+AM_CONDITIONAL([BUILD_WITH_GNULIB], [test "x$socket_needs_gnulib" = "xyes"])
clock_gettime_needs_posix4="no"
AC_CHECK_FUNCS([clock_gettime],
struct mntent *me;
fh = setmntent ("/etc/mtab", "r");
me = getmntent (fh);
- return(me->mnt_passno);
+ return me->mnt_passno;
]]
)
],
int status;
fh = fopen ("/etc/mnttab", "r");
status = getmntent (fh, &mt);
- return(status);
+ return status;
]]
)
],
# libi2c-dev
if test "x$ac_system" = "xLinux"; then
+ with_libi2c_libs=""
+ AC_CHECK_HEADERS([i2c/smbus.h],
+ [with_libi2c_libs="-li2c"]
+ )
AC_CHECK_DECL([i2c_smbus_read_i2c_block_data],
[with_libi2c="yes"],
[with_libi2c="no (symbol i2c_smbus_read_i2c_block_data not found - have you installed libi2c-dev ?)"],
[[
#include <stdlib.h>
#include <linux/i2c-dev.h>
+ #if HAVE_I2C_SMBUS_H
+ # include <i2c/smbus.h>
+ #endif
]]
)
+ BUILD_WITH_LIBI2C_LIBS="$with_libi2c_libs"
+ AC_SUBST([BUILD_WITH_LIBI2C_LIBS])
else
with_libi2c="no (Linux only)"
fi
AC_SUBST(BUILD_WITH_LIBCURL_CFLAGS)
AC_SUBST(BUILD_WITH_LIBCURL_LIBS)
+
+AM_CONDITIONAL([BUILD_WITH_LIBCURL], [test "x$with_libcurl" = "xyes"])
# }}}
# --with-libdbi {{{
if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
with_libgrpcpp_cppflags="-I$withval/include"
with_libgrpcpp_ldflags="-L$withval/lib"
+ with_libgrpcpp_bin="$withval/bin"
with_libgrpcpp="yes"
fi
if test "x$withval" = "xno"; then
# }}}
AC_ARG_VAR([GRPC_CPP_PLUGIN], [path to the grpc_cpp_plugin binary])
-AC_PATH_PROG([GRPC_CPP_PLUGIN], [grpc_cpp_plugin])
+if test "x$with_libgrpcpp_bin" = "x"; then
+ AC_PATH_PROG([GRPC_CPP_PLUGIN], [grpc_cpp_plugin])
+else
+ AC_PATH_PROG([GRPC_CPP_PLUGIN], [grpc_cpp_plugin], [], "$with_libgrpcpp_bin:$PATH")
+fi
AM_CONDITIONAL([HAVE_GRPC_CPP], [test "x$GRPC_CPP_PLUGIN" != "x"])
# --with-libiptc {{{
PKG_CHECK_MODULES([LUA], [lua5.3],
[with_liblua="yes"],
[
- PKG_CHECK_MODULES([LUA], [lua-5.2],
+ PKG_CHECK_MODULES([LUA], [lua53],
[with_liblua="yes"],
[
- PKG_CHECK_MODULES([LUA], [lua5.2],
+ PKG_CHECK_MODULES([LUA], [lua-5.2],
[with_liblua="yes"],
[
- PKG_CHECK_MODULES([LUA], [lua-5.1],
+ PKG_CHECK_MODULES([LUA], [lua5.2],
[with_liblua="yes"],
[
- PKG_CHECK_MODULES([LUA], [lua5.1],
+ PKG_CHECK_MODULES([LUA], [lua52],
[with_liblua="yes"],
- [with_liblua="no (pkg-config cannot find liblua)"]
+ [
+ PKG_CHECK_MODULES([LUA], [lua-5.1],
+ [with_liblua="yes"],
+ [
+ PKG_CHECK_MODULES([LUA], [lua5.1],
+ [with_liblua="yes"],
+ [
+ PKG_CHECK_MODULES([LUA], [lua51],
+ [with_liblua="yes"],
+ [with_liblua="no (pkg-config cannot find liblua)"]
+ )
+ ]
+ )
+ ]
+ )
+ ]
)
]
)
[[#include <linux/if_link.h>]]
)
+ AC_CHECK_MEMBERS([struct rtnl_link_stats.rx_nohandler],
+ [],
+ [],
+ [[#include <linux/if_link.h>]]
+ )
+
+ AC_CHECK_MEMBERS([struct rtnl_link_stats64.rx_nohandler],
+ [],
+ [],
+ [[#include <linux/if_link.h>]]
+ )
+
AC_CHECK_LIB([mnl], [mnl_nlmsg_get_payload],
[with_libmnl="yes"],
[with_libmnl="no (symbol 'mnl_nlmsg_get_payload' not found)"],
fi
AC_SUBST([BUILD_WITH_LIBMNL_CFLAGS])
AC_SUBST([BUILD_WITH_LIBMNL_LIBS])
+AM_CONDITIONAL([HAVE_LIBMNL], [test "x$with_libmnl" = "xyes"])
# }}}
# --with-libnetapp {{{
LDFLAGS="$LDFLAGS $with_libnetsnmp_ldflags"
AC_CHECK_LIB([netsnmp], [init_snmp],
- [with_libnetsmp="yes"],
+ [with_libnetsnmp="yes"],
[with_libnetsnmp="no (libnetsnmp not found)"]
)
fi
if test "x$with_libnetsnmp" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_libnetsnmp_ldflags"
+
+ AC_CHECK_LIB([netsnmp], [netsnmp_get_version],
+ [with_libnetsnmp="yes"],
+ [with_libnetsnmp="no (couldn't get libnetsnmp version)"]
+ )
+
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+
+if test "x$with_libnetsnmp" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+ SAVE_LIBS="$LIBS"
+ CPPFLAGS="$CPPFLAGS $with_libnetsnmp_cppflags -Wall -Werror"
+ LDFLAGS="$LDFLAGS $with_libnetsnmp_ldflags"
+ LIBS="$LIBS -lnetsnmp"
+
+ AC_CACHE_CHECK([whether netsnmp library has old API],
+ [c_cv_have_netsnmp_old_api],
+ [
+ AC_LINK_IFELSE(
+ [
+ AC_LANG_PROGRAM(
+ [[
+ #include <net-snmp/net-snmp-config.h>
+ #include <net-snmp/net-snmp-includes.h>
+ ]],
+ [[
+ netsnmp_variable_list *key = SNMP_MALLOC_TYPEDEF(netsnmp_variable_list);;
+ int val;
+ u_char type = ASN_INTEGER;
+ snmp_set_var_value(key, &val, sizeof(val));
+ snmp_set_var_typed_value(key, type, &val, sizeof(val));
+ return 0;
+ ]]
+ )
+ ],
+ [c_cv_have_netsnmp_old_api="no"],
+ [c_cv_have_netsnmp_old_api="yes"]
+ )
+ ]
+ )
+
+ if test "x$c_cv_have_netsnmp_old_api" = "xyes"; then
+ AC_DEFINE([HAVE_NETSNMP_OLD_API], [1],
+ ["Define 1 if you have old netsnmp API]")
+ fi
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+ LIBS="$SAVE_LIBS"
+fi
+
+if test "x$with_libnetsnmp" = "xyes"; then
BUILD_WITH_LIBNETSNMP_CPPFLAGS="$with_libnetsnmp_cppflags"
BUILD_WITH_LIBNETSNMP_LDFLAGS="$with_libnetsnmp_ldflags"
BUILD_WITH_LIBNETSNMP_LIBS="-lnetsnmp"
AC_SUBST([BUILD_WITH_LIBNETSNMP_LIBS])
# }}}
-# --with-libnetsmpagent {{{
+# --with-libnetsnmpagent {{{
AC_ARG_WITH([libnetsnmpagent],
[AS_HELP_STRING([--with-libnetsnmpagent@<:@=PREFIX@:>@], [Path to libnetsnmpagent.])],
[
[[#include <pcap.h>]],
[[
int val = PCAP_ERROR_IFACE_NOT_UP;
- return(val);
+ return val;
]]
)
],
fi
# }}} --with-libpython
+# --with-libqpid_proton {{{
+AC_ARG_WITH([libqpid_proton],
+ [AS_HELP_STRING([--with-libqpid_proton@<:@=PREFIX@:>@], [Path to libqpid_proton.])],
+ [
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+ with_libqpid_proton_cppflags="-I$withval/include"
+ with_libqpid_proton_ldflags="-L$withval/lib"
+ with_libqpid_proton="yes"
+ else
+ with_libqpid_proton="$withval"
+ fi
+ ],
+ [with_libqpid_proton="yes"]
+)
+
+if test "x$with_libqpid_proton" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libqpid_proton_cppflags"
+
+ AC_CHECK_HEADERS([proton/proactor.h],
+ [with_libqpid_proton="yes"],
+ [with_libqpid_proton="no (proton/proactor.h not found)"]
+ )
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+
+if test "x$with_libqpid_proton" = "xyes"; then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $with_libqpid_proton_ldflags"
+
+ AC_CHECK_LIB([qpid-proton], [pn_connection],
+ [with_libqpid_proton="yes"],
+ [with_libqpid_proton="no (Symbol 'pn_connection' not found)"])
+
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+
+if test "x$with_libqpid_proton" = "xyes"; then
+ BUILD_WITH_LIBQPIDPROTON_CPPFLAGS="$with_libqpid_proton_cppflags"
+ BUILD_WITH_LIBQPIDPROTON_LDFLAGS="$with_libqpid_proton_ldflags"
+ BUILD_WITH_LIBQPIDPROTON_LIBS="-lqpid-proton"
+fi
+
+AC_SUBST(BUILD_WITH_LIBQPIDPROTON_CPPFLAGS)
+AC_SUBST(BUILD_WITH_LIBQPIDPROTON_LDFLAGS)
+AC_SUBST(BUILD_WITH_LIBQPIDPROTON_LIBS)
+
+# }}}
+
# --with-librabbitmq {{{
AC_ARG_WITH([librabbitmq],
[AS_HELP_STRING([--with-librabbitmq@<:@=PREFIX@:>@], [Path to librabbitmq.])],
)
# }}}
+# --with-libssl {{{
+with_libssl_cflags=""
+with_libssl_ldflags=""
+AC_ARG_WITH([libssl], [AS_HELP_STRING([--with-libssl@<:@=PREFIX@:>@], [Path to libssl.])],
+[
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"; then
+ with_libssl_cppflags="-I$withval/include"
+ with_libssl_ldflags="-L$withval/lib"
+ with_libssl="yes"
+ else
+ with_libssl="$withval"
+ fi
+],
+[
+ with_libssl="yes"
+])
+if test "x$with_libssl" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libssl_cppflags"
+
+ AC_CHECK_HEADERS([openssl/sha.h openssl/blowfish.h openssl/rand.h],
+ [with_libssl="yes"],
+ [with_libssl="no (ssl header not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libssl" = "xyes"; then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libssl_cppflags"
+ LDFLAGS="$LDFLAGS $with_libssl_ldflags"
+
+ AC_CHECK_LIB([ssl], [OPENSSL_init_ssl], [with_libssl="yes"], [with_libssl="no (Symbol 'SSL_library_init' not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+if test "x$with_libssl" = "xyes"; then
+ BUILD_WITH_LIBSSL_CFLAGS="$with_libssl_cflags"
+ BUILD_WITH_LIBSSL_LDFLAGS="$with_libssl_ldflags"
+ BUILD_WITH_LIBSSL_LIBS="-lssl -lcrypto"
+ AC_SUBST([BUILD_WITH_LIBSSL_CFLAGS])
+ AC_SUBST([BUILD_WITH_LIBSSL_LDFLAGS])
+ AC_SUBST([BUILD_WITH_LIBSSL_LIBS])
+ AC_DEFINE([HAVE_LIBSSL], [1], [Define if libssl is present and usable.])
+fi
+AM_CONDITIONAL(BUILD_WITH_LIBSSL, test "x$with_libssl" = "xyes")
+# }}}
+
# --with-libstatgrab {{{
AC_ARG_WITH([libstatgrab],
[AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [Path to libstatgrab.])],
fi
if test "x$with_libxmms" = "xyes"; then
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$with_xmms_cflags"
+ SAVE_CPPFLAGS="$CFLAGS"
+ CPPFLAGS="$with_xmms_cflags"
AC_CHECK_HEADER([xmmsctrl.h],
[with_libxmms="yes"],
[with_libxmms="no"],
)
- CFLAGS="$SAVE_CFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
if test "x$with_libxmms" = "xyes"; then
AC_SUBST([BUILD_WITH_LIBYAJL_LIBS])
AM_CONDITIONAL([BUILD_WITH_LIBYAJL], [test "x$with_libyajl" = "xyes"])
+AM_CONDITIONAL([BUILD_WITH_LIBYAJL2], [test "x$with_libyajl$with_libyajl2" = "xyesyes"])
# }}}
# --with-mic {{{
AC_SUBST([BUILD_WITH_LIBVARNISH_LIBS])
# }}}
-# pkg-config --exists 'libxml-2.0'; pkg-config --exists libvirt {{{
-$PKG_CONFIG --exists 'libxml-2.0' 2>/dev/null
-if test $? -eq 0; then
- with_libxml2="yes"
-else
- with_libxml2="no (pkg-config doesn't know libxml-2.0)"
-fi
-
-$PKG_CONFIG --exists libvirt 2>/dev/null
-if test $? = 0; then
- with_libvirt="yes"
-else
- with_libvirt="no (pkg-config doesn't know libvirt)"
-fi
-
-if test "x$with_libxml2" = "xyes"; then
- with_libxml2_cflags="`$PKG_CONFIG --cflags libxml-2.0`"
- if test $? -ne 0; then
- with_libxml2="no"
- fi
-
- with_libxml2_ldflags="`$PKG_CONFIG --libs libxml-2.0`"
- if test $? -ne 0; then
- with_libxml2="no"
- fi
-fi
+# --with-libxml2 {{{
+AC_ARG_WITH(libxml2,
+ [AS_HELP_STRING([--with-libxml2@<:@=PREFIX@:>@], [Path to libxml2.])],
+ [
+ if test "x$withval" = "xno"; then
+ with_libxml2="no"
+ else if test "x$withval" = "xyes"; then
+ $PKG_CONFIG --exists 'libxml-2.0' 2>/dev/null
+ if test $? -eq 0; then
+ with_libxml2="yes"
+ with_libxml2_cflags="`$PKG_CONFIG --cflags libxml-2.0`"
+ with_libxml2_ldflags="`$PKG_CONFIG --libs libxml-2.0`"
+ else
+ with_libxml2="no (pkg-config doesn't know libxml-2.0)"
+ fi
+ else
+ with_libxml2="yes"
+ with_libxml2_cflags="-I$withval/include"
+ with_libxml2_ldflags="-L$withval/lib"
+ fi; fi
+ ],
+ dnl if no argument --with-libxml2 was passed, find the library locations
+ dnl with pkg-config just like above, when --with-libxml2=yes.
+ [
+ with_libxml2="yes"
+ $PKG_CONFIG --exists 'libxml-2.0' 2>/dev/null
+ if test $? -eq 0; then
+ with_libxml2="yes"
+ with_libxml2_cflags="`$PKG_CONFIG --cflags libxml-2.0`"
+ with_libxml2_ldflags="`$PKG_CONFIG --libs libxml-2.0`"
+ else
+ with_libxml2="no (pkg-config doesn't know libxml-2.0)"
+ fi
+ ]
+)
if test "x$with_libxml2" = "xyes"; then
SAVE_CPPFLAGS="$CPPFLAGS"
AC_SUBST([BUILD_WITH_LIBXML2_CFLAGS])
AC_SUBST([BUILD_WITH_LIBXML2_LIBS])
+# }}}
+
+# pkg-config --exists libvirt {{{
+$PKG_CONFIG --exists libvirt 2>/dev/null
+if test $? = 0; then
+ with_libvirt="yes"
+else
+ with_libvirt="no (pkg-config doesn't know libvirt)"
+fi
if test "x$with_libvirt" = "xyes"; then
with_libvirt_cflags="`$PKG_CONFIG --cflags libvirt`"
plugin_numa="no"
plugin_ovs_events="no"
plugin_ovs_stats="no"
+plugin_pcie_errors="no"
plugin_perl="no"
plugin_pinba="no"
plugin_processes="no"
plugin_vserver="no"
plugin_wireless="no"
plugin_write_prometheus="no"
+plugin_write_stackdriver="no"
plugin_xencpu="no"
plugin_zfs_arc="no"
plugin_zone="no"
plugin_ovs_events="yes"
plugin_ovs_stats="yes"
fi
+
+ if test "x$have_pci_regs_h" = "xyes"; then
+ plugin_pcie_errors="yes"
+ fi
fi
if test "x$ac_system" = "xOpenBSD"; then
plugin_curl_json="yes"
fi
+if test "x$with_libcurl" = "xyes" && test "x$with_libssl" = "xyes" && test "x$with_libyajl" = "xyes" && test "x$with_libyajl2" = "xyes"; then
+ plugin_write_stackdriver="yes"
+fi
+
if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"; then
plugin_curl_xml="yes"
fi
plugin_gps="yes"
fi
-if test "x$with_libgrpcpp" = "xyes" && test "x$with_libprotobuf" = "xyes" && test "x$have_protoc3" = "xyes" && test "x$GRPC_CPP_PLUGIN" != "x"; then
- plugin_grpc="yes"
+plugin_grpc="yes"
+if test "x$GRPC_CPP_PLUGIN" = "x"; then
+ plugin_grpc="no (grpc_cpp_plugin not found)"
+fi
+if test "x$have_protoc3" != "xyes"; then
+ plugin_grpc="no (protoc3 not found)"
+fi
+if test "x$with_libprotobuf" != "xyes"; then
+ plugin_grpc="no (libprotobuf not found)"
+fi
+if test "x$with_libgrpcpp" != "xyes"; then
+ plugin_grpc="no (libgrpc++ not found)"
fi
if test "x$have_getifaddrs" = "xyes"; then
m4_divert_once([HELP_ENABLE], [])
-AC_PLUGIN([aggregation], [yes], [Aggregation plugin])
-AC_PLUGIN([amqp], [$with_librabbitmq], [AMQP output plugin])
-AC_PLUGIN([apache], [$with_libcurl], [Apache httpd statistics])
-AC_PLUGIN([apcups], [yes], [Statistics of UPSes by APC])
-AC_PLUGIN([apple_sensors], [$with_libiokit], [Apple hardware sensors])
-AC_PLUGIN([aquaero], [$with_libaquaero5], [Aquaero hardware sensors])
-AC_PLUGIN([ascent], [$plugin_ascent], [AscentEmu player statistics])
-AC_PLUGIN([barometer], [$plugin_barometer], [Barometer sensor on I2C])
-AC_PLUGIN([battery], [$plugin_battery], [Battery statistics])
-AC_PLUGIN([bind], [$plugin_bind], [ISC Bind nameserver statistics])
-AC_PLUGIN([ceph], [$plugin_ceph], [Ceph daemon statistics])
-AC_PLUGIN([cgroups], [$plugin_cgroups], [CGroups CPU usage accounting])
-AC_PLUGIN([chrony], [yes], [Chrony statistics])
-AC_PLUGIN([conntrack], [$plugin_conntrack], [nf_conntrack statistics])
-AC_PLUGIN([contextswitch], [$plugin_contextswitch], [context switch statistics])
-AC_PLUGIN([cpu], [$plugin_cpu], [CPU usage statistics])
-AC_PLUGIN([cpufreq], [$plugin_cpufreq], [CPU frequency statistics])
-AC_PLUGIN([cpusleep], [$plugin_cpusleep], [CPU sleep statistics])
-AC_PLUGIN([csv], [yes], [CSV output plugin])
-AC_PLUGIN([curl], [$with_libcurl], [CURL generic web statistics])
-AC_PLUGIN([curl_json], [$plugin_curl_json], [CouchDB statistics])
-AC_PLUGIN([curl_xml], [$plugin_curl_xml], [CURL generic xml statistics])
-AC_PLUGIN([dbi], [$with_libdbi], [General database statistics])
-AC_PLUGIN([df], [$plugin_df], [Filesystem usage statistics])
-AC_PLUGIN([disk], [$plugin_disk], [Disk usage statistics])
-AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis])
-AC_PLUGIN([dpdkevents], [$plugin_dpdkevents], [Events from DPDK])
-AC_PLUGIN([dpdkstat], [$plugin_dpdkstat], [Stats from DPDK])
-AC_PLUGIN([drbd], [$plugin_drbd], [DRBD statistics])
-AC_PLUGIN([email], [yes], [EMail statistics])
-AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics])
-AC_PLUGIN([ethstat], [$plugin_ethstat], [Stats from NIC driver])
-AC_PLUGIN([exec], [yes], [Execution of external programs])
-AC_PLUGIN([fhcount], [$plugin_fhcount], [File handles statistics])
-AC_PLUGIN([filecount], [yes], [Count files in directories])
-AC_PLUGIN([fscache], [$plugin_fscache], [fscache statistics])
-AC_PLUGIN([gmond], [$with_libganglia], [Ganglia plugin])
-AC_PLUGIN([gps], [$plugin_gps], [GPS plugin])
-AC_PLUGIN([grpc], [$plugin_grpc], [gRPC plugin])
-AC_PLUGIN([hddtemp], [yes], [Query hddtempd])
-AC_PLUGIN([hugepages], [$plugin_hugepages], [Hugepages statistics])
-AC_PLUGIN([intel_pmu], [$with_libjevents], [Intel performance monitor plugin])
-AC_PLUGIN([intel_rdt], [$with_libpqos], [Intel RDT monitor plugin])
-AC_PLUGIN([interface], [$plugin_interface], [Interface traffic statistics])
-AC_PLUGIN([ipc], [$plugin_ipc], [IPC statistics])
-AC_PLUGIN([ipmi], [$plugin_ipmi], [IPMI sensor statistics])
-AC_PLUGIN([iptables], [$with_libiptc], [IPTables rule counters])
-AC_PLUGIN([ipvs], [$plugin_ipvs], [IPVS connection statistics])
-AC_PLUGIN([irq], [$plugin_irq], [IRQ statistics])
-AC_PLUGIN([java], [$with_java], [Embed the Java Virtual Machine])
-AC_PLUGIN([load], [$plugin_load], [System load])
-AC_PLUGIN([log_logstash], [$plugin_log_logstash], [Logstash json_event compatible logging])
-AC_PLUGIN([logfile], [yes], [File logging plugin])
-AC_PLUGIN([lpar], [$with_perfstat], [AIX logical partitions statistics])
-AC_PLUGIN([lua], [$with_liblua], [Lua plugin])
-AC_PLUGIN([lvm], [$with_liblvm2app], [LVM statistics])
-AC_PLUGIN([madwifi], [$have_linux_wireless_h], [Madwifi wireless statistics])
-AC_PLUGIN([match_empty_counter], [yes], [The empty counter match])
-AC_PLUGIN([match_hashed], [yes], [The hashed match])
-AC_PLUGIN([match_regex], [yes], [The regex match])
-AC_PLUGIN([match_timediff], [yes], [The timediff match])
-AC_PLUGIN([match_value], [yes], [The value match])
-AC_PLUGIN([mbmon], [yes], [Query mbmond])
-AC_PLUGIN([mcelog], [$plugin_mcelog], [Machine Check Exceptions notifications])
-AC_PLUGIN([md], [$have_linux_raid_md_u_h], [md (Linux software RAID) devices])
-AC_PLUGIN([memcachec], [$with_libmemcached], [memcachec statistics])
-AC_PLUGIN([memcached], [yes], [memcached statistics])
-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([netlink], [$with_libmnl], [Enhanced Linux network statistics])
-AC_PLUGIN([network], [yes], [Network communication plugin])
-AC_PLUGIN([nfs], [$plugin_nfs], [NFS statistics])
-AC_PLUGIN([nginx], [$with_libcurl], [nginx statistics])
-AC_PLUGIN([notify_desktop], [$with_libnotify], [Desktop notifications])
-AC_PLUGIN([notify_email], [$with_libesmtp], [Email notifier])
-AC_PLUGIN([notify_nagios], [yes], [Nagios notification plugin])
-AC_PLUGIN([ntpd], [yes], [NTPd statistics])
-AC_PLUGIN([numa], [$plugin_numa], [NUMA virtual memory statistics])
-AC_PLUGIN([nut], [$with_libupsclient], [Network UPS tools statistics])
-AC_PLUGIN([olsrd], [yes], [olsrd statistics])
-AC_PLUGIN([onewire], [$with_libowcapi], [OneWire sensor statistics])
-AC_PLUGIN([openldap], [$with_libldap], [OpenLDAP statistics])
-AC_PLUGIN([openvpn], [yes], [OpenVPN client statistics])
-AC_PLUGIN([oracle], [$with_oracle], [Oracle plugin])
-AC_PLUGIN([ovs_events], [$plugin_ovs_events], [OVS events plugin])
-AC_PLUGIN([ovs_stats], [$plugin_ovs_stats], [OVS statistics plugin])
-AC_PLUGIN([perl], [$plugin_perl], [Embed a Perl interpreter])
-AC_PLUGIN([pf], [$have_net_pfvar_h], [BSD packet filter (PF) statistics])
+AC_PLUGIN([aggregation], [yes], [Aggregation plugin])
+AC_PLUGIN([amqp], [$with_librabbitmq], [AMQP output plugin])
+AC_PLUGIN([amqp1], [$with_libqpid_proton], [AMQP 1.0 output plugin])
+AC_PLUGIN([apache], [$with_libcurl], [Apache httpd statistics])
+AC_PLUGIN([apcups], [yes], [Statistics of UPSes by APC])
+AC_PLUGIN([apple_sensors], [$with_libiokit], [Apple hardware sensors])
+AC_PLUGIN([aquaero], [$with_libaquaero5], [Aquaero hardware sensors])
+AC_PLUGIN([ascent], [$plugin_ascent], [AscentEmu player statistics])
+AC_PLUGIN([barometer], [$plugin_barometer], [Barometer sensor on I2C])
+AC_PLUGIN([battery], [$plugin_battery], [Battery statistics])
+AC_PLUGIN([bind], [$plugin_bind], [ISC Bind nameserver statistics])
+AC_PLUGIN([ceph], [$plugin_ceph], [Ceph daemon statistics])
+AC_PLUGIN([cgroups], [$plugin_cgroups], [CGroups CPU usage accounting])
+AC_PLUGIN([chrony], [yes], [Chrony statistics])
+AC_PLUGIN([conntrack], [$plugin_conntrack], [nf_conntrack statistics])
+AC_PLUGIN([contextswitch], [$plugin_contextswitch], [context switch statistics])
+AC_PLUGIN([cpu], [$plugin_cpu], [CPU usage statistics])
+AC_PLUGIN([cpufreq], [$plugin_cpufreq], [CPU frequency statistics])
+AC_PLUGIN([cpusleep], [$plugin_cpusleep], [CPU sleep statistics])
+AC_PLUGIN([csv], [yes], [CSV output plugin])
+AC_PLUGIN([curl], [$with_libcurl], [CURL generic web statistics])
+AC_PLUGIN([curl_json], [$plugin_curl_json], [CouchDB statistics])
+AC_PLUGIN([curl_xml], [$plugin_curl_xml], [CURL generic xml statistics])
+AC_PLUGIN([dbi], [$with_libdbi], [General database statistics])
+AC_PLUGIN([df], [$plugin_df], [Filesystem usage statistics])
+AC_PLUGIN([disk], [$plugin_disk], [Disk usage statistics])
+AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis])
+AC_PLUGIN([dpdkevents], [$plugin_dpdkevents], [Events from DPDK])
+AC_PLUGIN([dpdkstat], [$plugin_dpdkstat], [Stats from DPDK])
+AC_PLUGIN([drbd], [$plugin_drbd], [DRBD statistics])
+AC_PLUGIN([email], [yes], [EMail statistics])
+AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics])
+AC_PLUGIN([ethstat], [$plugin_ethstat], [Stats from NIC driver])
+AC_PLUGIN([exec], [yes], [Execution of external programs])
+AC_PLUGIN([fhcount], [$plugin_fhcount], [File handles statistics])
+AC_PLUGIN([filecount], [yes], [Count files in directories])
+AC_PLUGIN([fscache], [$plugin_fscache], [fscache statistics])
+AC_PLUGIN([gmond], [$with_libganglia], [Ganglia plugin])
+AC_PLUGIN([gps], [$plugin_gps], [GPS plugin])
+AC_PLUGIN([grpc], [$plugin_grpc], [gRPC plugin])
+AC_PLUGIN([hddtemp], [yes], [Query hddtempd])
+AC_PLUGIN([hugepages], [$plugin_hugepages], [Hugepages statistics])
+AC_PLUGIN([intel_pmu], [$with_libjevents], [Intel performance monitor plugin])
+AC_PLUGIN([intel_rdt], [$with_libpqos], [Intel RDT monitor plugin])
+AC_PLUGIN([interface], [$plugin_interface], [Interface traffic statistics])
+AC_PLUGIN([ipc], [$plugin_ipc], [IPC statistics])
+AC_PLUGIN([ipmi], [$plugin_ipmi], [IPMI sensor statistics])
+AC_PLUGIN([iptables], [$with_libiptc], [IPTables rule counters])
+AC_PLUGIN([ipvs], [$plugin_ipvs], [IPVS connection statistics])
+AC_PLUGIN([irq], [$plugin_irq], [IRQ statistics])
+AC_PLUGIN([java], [$with_java], [Embed the Java Virtual Machine])
+AC_PLUGIN([load], [$plugin_load], [System load])
+AC_PLUGIN([log_logstash], [$plugin_log_logstash], [Logstash json_event compatible logging])
+AC_PLUGIN([logfile], [yes], [File logging plugin])
+AC_PLUGIN([lpar], [$with_perfstat], [AIX logical partitions statistics])
+AC_PLUGIN([lua], [$with_liblua], [Lua plugin])
+AC_PLUGIN([lvm], [$with_liblvm2app], [LVM statistics])
+AC_PLUGIN([madwifi], [$have_linux_wireless_h], [Madwifi wireless statistics])
+AC_PLUGIN([match_empty_counter], [yes], [The empty counter match])
+AC_PLUGIN([match_hashed], [yes], [The hashed match])
+AC_PLUGIN([match_regex], [yes], [The regex match])
+AC_PLUGIN([match_timediff], [yes], [The timediff match])
+AC_PLUGIN([match_value], [yes], [The value match])
+AC_PLUGIN([mbmon], [yes], [Query mbmond])
+AC_PLUGIN([mcelog], [$plugin_mcelog], [Machine Check Exceptions notifications])
+AC_PLUGIN([md], [$have_linux_raid_md_u_h], [md (Linux software RAID) devices])
+AC_PLUGIN([memcachec], [$with_libmemcached], [memcachec statistics])
+AC_PLUGIN([memcached], [yes], [memcached statistics])
+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([netlink], [$with_libmnl], [Enhanced Linux network statistics])
+AC_PLUGIN([network], [yes], [Network communication plugin])
+AC_PLUGIN([nfs], [$plugin_nfs], [NFS statistics])
+AC_PLUGIN([nginx], [$with_libcurl], [nginx statistics])
+AC_PLUGIN([notify_desktop], [$with_libnotify], [Desktop notifications])
+AC_PLUGIN([notify_email], [$with_libesmtp], [Email notifier])
+AC_PLUGIN([notify_nagios], [yes], [Nagios notification plugin])
+AC_PLUGIN([ntpd], [yes], [NTPd statistics])
+AC_PLUGIN([numa], [$plugin_numa], [NUMA virtual memory statistics])
+AC_PLUGIN([nut], [$with_libupsclient], [Network UPS tools statistics])
+AC_PLUGIN([olsrd], [yes], [olsrd statistics])
+AC_PLUGIN([onewire], [$with_libowcapi], [OneWire sensor statistics])
+AC_PLUGIN([openldap], [$with_libldap], [OpenLDAP statistics])
+AC_PLUGIN([openvpn], [yes], [OpenVPN client statistics])
+AC_PLUGIN([oracle], [$with_oracle], [Oracle plugin])
+AC_PLUGIN([ovs_events], [$plugin_ovs_events], [OVS events plugin])
+AC_PLUGIN([ovs_stats], [$plugin_ovs_stats], [OVS statistics plugin])
+AC_PLUGIN([pcie_errors], [$plugin_pcie_errors], [PCIe errors plugin])
+AC_PLUGIN([perl], [$plugin_perl], [Embed a Perl interpreter])
+AC_PLUGIN([pf], [$have_net_pfvar_h], [BSD packet filter (PF) statistics])
# FIXME: Check for libevent, too.
-AC_PLUGIN([pinba], [$plugin_pinba], [Pinba statistics])
-AC_PLUGIN([ping], [$with_liboping], [Network latency statistics])
-AC_PLUGIN([postgresql], [$with_libpq], [PostgreSQL database statistics])
-AC_PLUGIN([powerdns], [yes], [PowerDNS statistics])
-AC_PLUGIN([processes], [$plugin_processes], [Process statistics])
-AC_PLUGIN([protocols], [$plugin_protocols], [Protocol (IP, TCP, ...) statistics])
-AC_PLUGIN([python], [$plugin_python], [Embed a Python interpreter])
-AC_PLUGIN([redis], [$with_libhiredis], [Redis plugin])
-AC_PLUGIN([routeros], [$with_librouteros], [RouterOS plugin])
-AC_PLUGIN([rrdcached], [$librrd_rrdc_update], [RRDTool output plugin])
-AC_PLUGIN([rrdtool], [$with_librrd], [RRDTool output plugin])
-AC_PLUGIN([sensors], [$with_libsensors], [lm_sensors statistics])
-AC_PLUGIN([serial], [$plugin_serial], [serial port traffic])
-AC_PLUGIN([sigrok], [$with_libsigrok], [sigrok acquisition sources])
-AC_PLUGIN([smart], [$plugin_smart], [SMART statistics])
-AC_PLUGIN([snmp], [$with_libnetsnmp], [SNMP querying plugin])
-AC_PLUGIN([snmp_agent], [$with_libnetsnmpagent], [SNMP agent plugin])
-AC_PLUGIN([statsd], [yes], [StatsD plugin])
-AC_PLUGIN([swap], [$plugin_swap], [Swap usage statistics])
-AC_PLUGIN([synproxy], [$plugin_synproxy], [Synproxy stats plugin])
-AC_PLUGIN([syslog], [$have_syslog], [Syslog logging plugin])
-AC_PLUGIN([table], [yes], [Parsing of tabular data])
-AC_PLUGIN([tail], [yes], [Parsing of logfiles])
-AC_PLUGIN([tail_csv], [yes], [Parsing of CSV files])
-AC_PLUGIN([tape], [$plugin_tape], [Tape drive statistics])
-AC_PLUGIN([target_notification], [yes], [The notification target])
-AC_PLUGIN([target_replace], [yes], [The replace target])
-AC_PLUGIN([target_scale], [yes], [The scale target])
-AC_PLUGIN([target_set], [yes], [The set target])
-AC_PLUGIN([target_v5upgrade], [yes], [The v5upgrade target])
-AC_PLUGIN([tcpconns], [$plugin_tcpconns], [TCP connection statistics])
-AC_PLUGIN([teamspeak2], [yes], [TeamSpeak2 server statistics])
-AC_PLUGIN([ted], [$plugin_ted], [Read The Energy Detective values])
-AC_PLUGIN([thermal], [$plugin_thermal], [Linux ACPI thermal zone statistics])
-AC_PLUGIN([threshold], [yes], [Threshold checking plugin])
-AC_PLUGIN([tokyotyrant], [$with_libtokyotyrant], [TokyoTyrant database statistics])
-AC_PLUGIN([turbostat], [$plugin_turbostat], [Advanced statistic on Intel cpu states])
-AC_PLUGIN([unixsock], [yes], [Unixsock communication plugin])
-AC_PLUGIN([uptime], [$plugin_uptime], [Uptime statistics])
-AC_PLUGIN([users], [$plugin_users], [User statistics])
-AC_PLUGIN([uuid], [yes], [UUID as hostname plugin])
-AC_PLUGIN([varnish], [$with_libvarnish], [Varnish cache statistics])
-AC_PLUGIN([virt], [$plugin_virt], [Virtual machine statistics])
-AC_PLUGIN([vmem], [$plugin_vmem], [Virtual memory statistics])
-AC_PLUGIN([vserver], [$plugin_vserver], [Linux VServer statistics])
-AC_PLUGIN([wireless], [$plugin_wireless], [Wireless statistics])
-AC_PLUGIN([write_graphite], [yes], [Graphite / Carbon output plugin])
-AC_PLUGIN([write_http], [$with_libcurl], [HTTP output plugin])
-AC_PLUGIN([write_kafka], [$with_librdkafka], [Kafka output plugin])
-AC_PLUGIN([write_log], [yes], [Log output plugin])
-AC_PLUGIN([write_mongodb], [$with_libmongoc], [MongoDB output plugin])
-AC_PLUGIN([write_prometheus], [$plugin_write_prometheus], [Prometheus write plugin])
-AC_PLUGIN([write_redis], [$with_libhiredis], [Redis output plugin])
-AC_PLUGIN([write_riemann], [$with_libriemann_client], [Riemann output plugin])
-AC_PLUGIN([write_sensu], [yes], [Sensu output plugin])
-AC_PLUGIN([write_tsdb], [yes], [TSDB output plugin])
-AC_PLUGIN([xencpu], [$plugin_xencpu], [Xen Host CPU usage])
-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])
+AC_PLUGIN([pinba], [$plugin_pinba], [Pinba statistics])
+AC_PLUGIN([ping], [$with_liboping], [Network latency statistics])
+AC_PLUGIN([postgresql], [$with_libpq], [PostgreSQL database statistics])
+AC_PLUGIN([powerdns], [yes], [PowerDNS statistics])
+AC_PLUGIN([processes], [$plugin_processes], [Process statistics])
+AC_PLUGIN([protocols], [$plugin_protocols], [Protocol (IP, TCP, ...) statistics])
+AC_PLUGIN([python], [$plugin_python], [Embed a Python interpreter])
+AC_PLUGIN([redis], [$with_libhiredis], [Redis plugin])
+AC_PLUGIN([routeros], [$with_librouteros], [RouterOS plugin])
+AC_PLUGIN([rrdcached], [$librrd_rrdc_update], [RRDTool output plugin])
+AC_PLUGIN([rrdtool], [$with_librrd], [RRDTool output plugin])
+AC_PLUGIN([sensors], [$with_libsensors], [lm_sensors statistics])
+AC_PLUGIN([serial], [$plugin_serial], [serial port traffic])
+AC_PLUGIN([sigrok], [$with_libsigrok], [sigrok acquisition sources])
+AC_PLUGIN([smart], [$plugin_smart], [SMART statistics])
+AC_PLUGIN([snmp], [$with_libnetsnmp], [SNMP querying plugin])
+AC_PLUGIN([snmp_agent], [$with_libnetsnmpagent], [SNMP agent plugin])
+AC_PLUGIN([statsd], [yes], [StatsD plugin])
+AC_PLUGIN([swap], [$plugin_swap], [Swap usage statistics])
+AC_PLUGIN([synproxy], [$plugin_synproxy], [Synproxy stats plugin])
+AC_PLUGIN([syslog], [$have_syslog], [Syslog logging plugin])
+AC_PLUGIN([table], [yes], [Parsing of tabular data])
+AC_PLUGIN([tail], [yes], [Parsing of logfiles])
+AC_PLUGIN([tail_csv], [yes], [Parsing of CSV files])
+AC_PLUGIN([tape], [$plugin_tape], [Tape drive statistics])
+AC_PLUGIN([target_notification], [yes], [The notification target])
+AC_PLUGIN([target_replace], [yes], [The replace target])
+AC_PLUGIN([target_scale], [yes], [The scale target])
+AC_PLUGIN([target_set], [yes], [The set target])
+AC_PLUGIN([target_v5upgrade], [yes], [The v5upgrade target])
+AC_PLUGIN([tcpconns], [$plugin_tcpconns], [TCP connection statistics])
+AC_PLUGIN([teamspeak2], [yes], [TeamSpeak2 server statistics])
+AC_PLUGIN([ted], [$plugin_ted], [Read The Energy Detective values])
+AC_PLUGIN([thermal], [$plugin_thermal], [Linux ACPI thermal zone statistics])
+AC_PLUGIN([threshold], [yes], [Threshold checking plugin])
+AC_PLUGIN([tokyotyrant], [$with_libtokyotyrant], [TokyoTyrant database statistics])
+AC_PLUGIN([turbostat], [$plugin_turbostat], [Advanced statistic on Intel cpu states])
+AC_PLUGIN([unixsock], [yes], [Unixsock communication plugin])
+AC_PLUGIN([uptime], [$plugin_uptime], [Uptime statistics])
+AC_PLUGIN([users], [$plugin_users], [User statistics])
+AC_PLUGIN([uuid], [yes], [UUID as hostname plugin])
+AC_PLUGIN([varnish], [$with_libvarnish], [Varnish cache statistics])
+AC_PLUGIN([virt], [$plugin_virt], [Virtual machine statistics])
+AC_PLUGIN([vmem], [$plugin_vmem], [Virtual memory statistics])
+AC_PLUGIN([vserver], [$plugin_vserver], [Linux VServer statistics])
+AC_PLUGIN([wireless], [$plugin_wireless], [Wireless statistics])
+AC_PLUGIN([write_graphite], [yes], [Graphite / Carbon output plugin])
+AC_PLUGIN([write_http], [$with_libcurl], [HTTP output plugin])
+AC_PLUGIN([write_stackdriver], [$plugin_write_stackdriver], [Google Stackdriver Monitoring output plugin])
+AC_PLUGIN([write_kafka], [$with_librdkafka], [Kafka output plugin])
+AC_PLUGIN([write_log], [yes], [Log output plugin])
+AC_PLUGIN([write_mongodb], [$with_libmongoc], [MongoDB output plugin])
+AC_PLUGIN([write_prometheus], [$plugin_write_prometheus], [Prometheus write plugin])
+AC_PLUGIN([write_redis], [$with_libhiredis], [Redis output plugin])
+AC_PLUGIN([write_riemann], [$with_libriemann_client], [Riemann output plugin])
+AC_PLUGIN([write_sensu], [yes], [Sensu output plugin])
+AC_PLUGIN([write_tsdb], [yes], [TSDB output plugin])
+AC_PLUGIN([xencpu], [$plugin_xencpu], [Xen Host CPU usage])
+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
# Load either syslog or logfile
AC_MSG_RESULT([ libprotobuf . . . . . $with_libprotobuf])
AC_MSG_RESULT([ libprotobuf-c . . . . $with_libprotobuf_c])
AC_MSG_RESULT([ libpython . . . . . . $with_libpython])
+AC_MSG_RESULT([ libqpid-proton . . . $with_libqpid_proton])
AC_MSG_RESULT([ librabbitmq . . . . . $with_librabbitmq])
AC_MSG_RESULT([ libriemann-client . . $with_libriemann_client])
AC_MSG_RESULT([ librdkafka . . . . . $with_librdkafka])
AC_MSG_RESULT([ librrd . . . . . . . $with_librrd])
AC_MSG_RESULT([ libsensors . . . . . $with_libsensors])
AC_MSG_RESULT([ libsigrok . . . . . $with_libsigrok])
+AC_MSG_RESULT([ libssl . . . . . . . $with_libssl])
AC_MSG_RESULT([ libstatgrab . . . . . $with_libstatgrab])
AC_MSG_RESULT([ libtokyotyrant . . . $with_libtokyotyrant])
AC_MSG_RESULT([ libudev . . . . . . . $with_libudev])
AC_MSG_RESULT([ Modules:])
AC_MSG_RESULT([ aggregation . . . . . $enable_aggregation])
AC_MSG_RESULT([ amqp . . . . . . . $enable_amqp])
+AC_MSG_RESULT([ amqp1 . . . . . . . $enable_amqp1])
AC_MSG_RESULT([ apache . . . . . . . $enable_apache])
AC_MSG_RESULT([ apcups . . . . . . . $enable_apcups])
AC_MSG_RESULT([ apple_sensors . . . . $enable_apple_sensors])
AC_MSG_RESULT([ oracle . . . . . . . $enable_oracle])
AC_MSG_RESULT([ ovs_events . . . . . $enable_ovs_events])
AC_MSG_RESULT([ ovs_stats . . . . . . $enable_ovs_stats])
+AC_MSG_RESULT([ pcie_errors . . . . . $enable_pcie_errors])
AC_MSG_RESULT([ perl . . . . . . . . $enable_perl])
AC_MSG_RESULT([ pf . . . . . . . . . $enable_pf])
AC_MSG_RESULT([ pinba . . . . . . . . $enable_pinba])
AC_MSG_RESULT([ write_redis . . . . . $enable_write_redis])
AC_MSG_RESULT([ write_riemann . . . . $enable_write_riemann])
AC_MSG_RESULT([ write_sensu . . . . . $enable_write_sensu])
+AC_MSG_RESULT([ write_stackdriver . . $enable_write_stackdriver])
AC_MSG_RESULT([ write_tsdb . . . . . $enable_write_tsdb])
AC_MSG_RESULT([ xencpu . . . . . . . $enable_xencpu])
AC_MSG_RESULT([ xmms . . . . . . . . $enable_xmms])
fi
# vim: set fdm=marker sw=2 sts=2 ts=2 et :
+
static mach_port_t io_master_port = MACH_PORT_NULL;
/* This defaults to false for backwards compatibility. Please fix in the next
* major version. */
-static _Bool use_bsd_name = 0;
+static bool use_bsd_name;
/* #endif HAVE_IOKIT_IOKITLIB_H */
#elif KERNEL_LINUX
derive_t avg_read_time;
derive_t avg_write_time;
- _Bool has_merged;
- _Bool has_in_progress;
- _Bool has_io_time;
+ bool has_merged;
+ bool has_in_progress;
+ bool has_io_time;
struct diskstats *next;
} diskstats_t;
#define MAX_NUMDISK 1024
extern kstat_ctl_t *kc;
static kstat_t *ksp[MAX_NUMDISK];
-static int numdisk = 0;
+static int numdisk;
/* #endif HAVE_LIBKSTAT */
#elif defined(HAVE_LIBSTATGRAB)
#if HAVE_LIBUDEV_H
#include <libudev.h>
-static char *conf_udev_name_attr = NULL;
+static char *conf_udev_name_attr;
static struct udev *handle_udev;
#endif
"UdevNameAttr"};
static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
-static ignorelist_t *ignorelist = NULL;
+static ignorelist_t *ignorelist;
static int disk_config(const char *key, const char *value) {
if (ignorelist == NULL)
ignorelist_set_invert(ignorelist, invert);
} else if (strcasecmp("UseBSDName", key) == 0) {
#if HAVE_IOKIT_IOKITLIB_H
- use_bsd_name = IS_TRUE(value) ? 1 : 0;
+ use_bsd_name = IS_TRUE(value);
#else
WARNING("disk plugin: The \"UseBSDName\" option is only supported "
"on Mach / Mac OS X and will be ignored.");
plugin_dispatch_values(&vl);
} /* void submit_io_time */
-#endif /* KERNEL_FREEBSD || KERNEL_LINUX */
-#if KERNEL_LINUX
static void submit_in_progress(char const *disk_name, gauge_t in_progress) {
value_list_t vl = VALUE_LIST_INIT;
plugin_dispatch_values(&vl);
}
+#endif /* KERNEL_FREEBSD || KERNEL_LINUX */
+#if KERNEL_LINUX
static counter_t disk_calc_time_incr(counter_t delta_time,
counter_t delta_ops) {
double interval = CDTIME_T_TO_DOUBLE(plugin_get_interval());
const char *disk_name;
long double read_time, write_time, busy_time, total_duration;
+ uint64_t queue_length;
for (retry = 0, dirty = 1; retry < 5 && dirty == 1; retry++) {
if (snap != NULL)
}
if (devstat_compute_statistics(snap_iter, NULL, 1.0, DSM_TOTAL_BUSY_TIME,
&busy_time, DSM_TOTAL_DURATION,
- &total_duration, DSM_NONE) != 0) {
+ &total_duration, DSM_QUEUE_LENGTH,
+ &queue_length, DSM_NONE) != 0) {
WARNING("%s", devstat_errbuf);
} else {
submit_io_time(disk_name, busy_time, total_duration);
+ submit_in_progress(disk_name, (gauge_t)queue_length);
}
}
geom_stats_snapshot_free(snap);
char *fields[32];
int numfields;
- int fieldshift = 0;
int minor = 0;
diskstats_t *ds, *pre_ds;
if ((fh = fopen("/proc/diskstats", "r")) == NULL) {
- fh = fopen("/proc/partitions", "r");
- if (fh == NULL) {
- ERROR("disk plugin: fopen (/proc/{diskstats,partitions}) failed.");
- return -1;
- }
-
- /* Kernel is 2.4.* */
- fieldshift = 1;
+ ERROR("disk plugin: fopen(\"/proc/diskstats\"): %s", STRERRNO);
+ return -1;
}
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
char *output_name;
numfields = strsplit(buffer, fields, 32);
- if ((numfields != 14) && (numfields != 7))
+
- /* need either 7 fields (partition)
- * or at least 14 fields (15 on Linux 2.4) */
- if ((numfields != 7) && (numfields < (14 + fieldshift)))
++ /* need either 7 fields (partition) or at least 14 fields */
++ if ((numfields != 7) && (numfields < 14))
continue;
minor = atoll(fields[1]);
- disk_name = fields[2 + fieldshift];
+ disk_name = fields[2];
for (ds = disklist, pre_ds = disklist; ds != NULL;
pre_ds = ds, ds = ds->next)
read_sectors = atoll(fields[4]);
write_ops = atoll(fields[5]);
write_sectors = atoll(fields[6]);
- } else if (numfields == 14) {
+ } else {
- assert(numfields >= (14 + fieldshift));
- read_ops = atoll(fields[3 + fieldshift]);
- write_ops = atoll(fields[7 + fieldshift]);
++ assert(numfields >= 14);
+ read_ops = atoll(fields[3]);
+ write_ops = atoll(fields[7]);
- read_sectors = atoll(fields[5 + fieldshift]);
- write_sectors = atoll(fields[9 + fieldshift]);
+ read_sectors = atoll(fields[5]);
+ write_sectors = atoll(fields[9]);
- if ((fieldshift == 0) || (minor == 0)) {
+ if (minor == 0) {
is_disk = 1;
- read_merged = atoll(fields[4 + fieldshift]);
- read_time = atoll(fields[6 + fieldshift]);
- write_merged = atoll(fields[8 + fieldshift]);
- write_time = atoll(fields[10 + fieldshift]);
+ read_merged = atoll(fields[4]);
+ read_time = atoll(fields[6]);
+ write_merged = atoll(fields[8]);
+ write_time = atoll(fields[10]);
- in_progress = atof(fields[11 + fieldshift]);
+ in_progress = atof(fields[11]);
- io_time = atof(fields[12 + fieldshift]);
- weighted_time = atof(fields[13 + fieldshift]);
+ io_time = atof(fields[12]);
+ weighted_time = atof(fields[13]);
}
- } else {
- DEBUG("numfields = %i; => unknown file format.", numfields);
- continue;
}
{
ds->write_time = write_time;
if (read_merged || write_merged)
- ds->has_merged = 1;
+ ds->has_merged = true;
if (in_progress)
- ds->has_in_progress = 1;
+ ds->has_in_progress = true;
if (io_time)
- ds->has_io_time = 1;
+ ds->has_io_time = true;
} /* if (is_disk) */
int rnumdisk;
if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0) {
- char errbuf[1024];
- WARNING("disk plugin: perfstat_disk: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ WARNING("disk plugin: perfstat_disk: %s", STRERRNO);
return -1;
}
firstpath.name[0] = '\0';
if ((rnumdisk = perfstat_disk(&firstpath, stat_disk, sizeof(perfstat_disk_t),
numdisk)) < 0) {
- char errbuf[1024];
- WARNING("disk plugin: perfstat_disk : %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ WARNING("disk plugin: perfstat_disk : %s", STRERRNO);
return -1;
}
/*
* Private variables
*/
-static program_list_t *pl_head = NULL;
+static program_list_t *pl_head;
static pthread_mutex_t pl_lock = PTHREAD_MUTEX_INITIALIZER;
/*
return 0;
} /* int exec_config }}} */
+ #if !defined(HAVE_SETENV)
+ static char env_interval[64];
+ // max hostname len is 255, so this should be enough
+ static char env_hostname[300];
+ #endif
+
static void set_environment(void) /* {{{ */
{
+ #ifdef HAVE_SETENV
char buffer[1024];
- #ifdef HAVE_SETENV
snprintf(buffer, sizeof(buffer), "%.3f",
CDTIME_T_TO_DOUBLE(plugin_get_interval()));
setenv("COLLECTD_INTERVAL", buffer, /* overwrite = */ 1);
sstrncpy(buffer, hostname_g, sizeof(buffer));
setenv("COLLECTD_HOSTNAME", buffer, /* overwrite = */ 1);
#else
- snprintf(buffer, sizeof(buffer), "COLLECTD_INTERVAL=%.3f",
+ snprintf(env_interval, sizeof(env_interval), "COLLECTD_INTERVAL=%.3f",
CDTIME_T_TO_DOUBLE(plugin_get_interval()));
- putenv(buffer);
+ putenv(env_interval);
- snprintf(buffer, sizeof(buffer), "COLLECTD_HOSTNAME=%s", hostname_g);
- putenv(buffer);
+ snprintf(env_hostname, sizeof(env_hostname), "COLLECTD_HOSTNAME=%s",
+ hostname_g);
+ putenv(env_hostname);
#endif
} /* }}} void set_environment */
+ static void unset_environment(void) /* {{{ */
+ {
+ #ifdef HAVE_SETENV
+ unsetenv("COLLECTD_INTERVAL");
+ unsetenv("COLLECTD_HOSTNAME");
+ #else
+ snprintf(env_interval, sizeof(env_interval), "COLLECTD_INTERVAL");
+ putenv(env_interval);
+ snprintf(env_hostname, sizeof(env_hostname), "COLLECTD_HOSTNAME");
+ putenv(env_hostname);
+ #endif
+ } /* }}} void unset_environment */
+
__attribute__((noreturn)) static void exec_child(program_list_t *pl, int uid,
int gid, int egid) /* {{{ */
{
int status;
- char errbuf[1024];
#if HAVE_SETGROUPS
if (getuid() == 0) {
status = setgid(gid);
if (status != 0) {
- ERROR("exec plugin: setgid (%i) failed: %s", gid,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("exec plugin: setgid (%i) failed: %s", gid, STRERRNO);
exit(-1);
}
if (egid != -1) {
status = setegid(egid);
if (status != 0) {
- ERROR("exec plugin: setegid (%i) failed: %s", egid,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("exec plugin: setegid (%i) failed: %s", egid, STRERRNO);
exit(-1);
}
}
status = setuid(uid);
if (status != 0) {
- ERROR("exec plugin: setuid (%i) failed: %s", uid,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("exec plugin: setuid (%i) failed: %s", uid, STRERRNO);
exit(-1);
}
execvp(pl->exec, pl->argv);
- ERROR("exec plugin: Failed to execute ``%s'': %s", pl->exec,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("exec plugin: Failed to execute ``%s'': %s", pl->exec, STRERRNO);
exit(-1);
} /* void exec_child }}} */
static int create_pipe(int fd_pipe[2]) /* {{{ */
{
- char errbuf[1024];
int status;
status = pipe(fd_pipe);
if (status != 0) {
- ERROR("exec plugin: pipe failed: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("exec plugin: pipe failed: %s", STRERRNO);
return -1;
}
} else if (errno == ERANGE) {
grbuf_size += grbuf_size; // increment buffer size and try again
} else {
- char errbuf[1024];
- ERROR("exec plugin: getegr_id failed %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("exec plugin: getegr_id failed %s", STRERRNO);
sfree(grbuf);
return -2;
}
ERROR("exec plugin: getegr_id Max grbuf size reached for %s", pl->group);
sfree(grbuf);
return -2;
-} /* }}} */
+}
/*
* Creates three pipes (one for reading, one for writing and one for errors),
int fd_pipe_in[2] = {-1, -1};
int fd_pipe_out[2] = {-1, -1};
int fd_pipe_err[2] = {-1, -1};
- char errbuf[1024];
int status;
int pid;
status = getpwnam_r(pl->user, &sp, nambuf, sizeof(nambuf), &sp_ptr);
if (status != 0) {
ERROR("exec plugin: Failed to get user information for user ``%s'': %s",
- pl->user, sstrerror(status, errbuf, sizeof(errbuf)));
+ pl->user, STRERROR(status));
goto failed;
}
goto failed;
}
+ /* The group configured in the configfile is set as effective group, because
+ * this way the forked process can (re-)gain the user's primary group. */
egid = getegr_id(pl, gid);
if (egid == -2) {
goto failed;
}
+ set_environment();
+
pid = fork();
if (pid < 0) {
- ERROR("exec plugin: fork failed: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("exec plugin: fork failed: %s", STRERRNO);
goto failed;
} else if (pid == 0) {
int fd_num;
close(fd_pipe_err[1]);
}
- set_environment();
-
/* Unblock all signals */
reset_signal_mask();
/* does not return */
}
+ unset_environment();
+
close(fd_pipe_in[0]);
close(fd_pipe_out[1]);
close(fd_pipe_err[1]);
return pid;
failed:
+ unset_environment();
+
close_pipe(fd_pipe_in);
close_pipe(fd_pipe_out);
close_pipe(fd_pipe_err);
fh = fdopen(fd, "w");
if (fh == NULL) {
- char errbuf[1024];
- ERROR("exec plugin: fdopen (%i) failed: %s", fd,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("exec plugin: fdopen (%i) failed: %s", fd, STRERRNO);
kill(pid, SIGTERM);
close(fd);
sfree(arg);
"IncludeUnitID"};
static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
-static _Bool do_reverse_lookups = 1;
+static bool do_reverse_lookups = true;
/* This option only exists for backward compatibility. If it is false and two
* ntpd peers use the same refclock driver, the plugin will try to write
* simultaneous measurements from both to the same type instance. */
-static _Bool include_unit_id = 0;
+static bool include_unit_id;
#define NTPD_DEFAULT_HOST "localhost"
#define NTPD_DEFAULT_PORT "123"
static int sock_descr = -1;
-static char *ntpd_host = NULL;
+static char *ntpd_host;
static char ntpd_port[16];
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
"CHRONOLOG", "DUMBCLOCK", "ULINK_M320", "PCF", /* 32-35 */
"WWV_AUDIO", "GPS_FG", "HOPF_S", "HOPF_P", /* 36-39 */
"JJY", "TT_IRIG", "GPS_ZYFER", "GPS_RIPENCC", /* 40-43 */
- "NEOCLK4X" /* 44 */
+ "NEOCLK4X", "PCI_TSYNC", "GPSD_JSON" /* 44-46 */
};
static size_t refclock_names_num = STATIC_ARRAY_SIZE(refclock_names);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
sstrncpy(ntpd_port, value, sizeof(ntpd_port));
} else if (strcasecmp(key, "ReverseLookups") == 0) {
if (IS_TRUE(value))
- do_reverse_lookups = 1;
+ do_reverse_lookups = true;
else
- do_reverse_lookups = 0;
+ do_reverse_lookups = false;
} else if (strcasecmp(key, "IncludeUnitID") == 0) {
if (IS_TRUE(value))
- include_unit_id = 1;
+ include_unit_id = true;
else
- include_unit_id = 0;
+ include_unit_id = false;
} else {
return -1;
}
.ai_socktype = SOCK_DGRAM};
if ((status = getaddrinfo(host, port, &ai_hints, &ai_list)) != 0) {
- char errbuf[1024];
ERROR("ntpd plugin: getaddrinfo (%s, %s): %s", host, port,
- (status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
- : gai_strerror(status));
+ (status == EAI_SYSTEM) ? STRERRNO : gai_strerror(status));
return -1;
}
*res_data = NULL;
if (gettimeofday(&time_end, NULL) < 0) {
- char errbuf[1024];
- ERROR("ntpd plugin: gettimeofday failed: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("ntpd plugin: gettimeofday failed: %s", STRERRNO);
return -1;
}
time_end.tv_sec++; /* wait for a most one second */
struct timeval time_left;
if (gettimeofday(&time_now, NULL) < 0) {
- char errbuf[1024];
- ERROR("ntpd plugin: gettimeofday failed: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("ntpd plugin: gettimeofday failed: %s", STRERRNO);
return -1;
}
continue;
if (status < 0) {
- char errbuf[1024];
- ERROR("ntpd plugin: poll failed: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("ntpd plugin: poll failed: %s", STRERRNO);
return -1;
}
continue;
if (status < 0) {
- char errbuf[1024];
- INFO("recv(2) failed: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
+ INFO("recv(2) failed: %s", STRERRNO);
DEBUG("Closing socket #%i", sd);
close(sd);
sock_descr = sd = -1;
* Enough with the checks. Copy the data now.
* We start by allocating some more memory.
*/
- DEBUG("realloc (%p, %zu)", (void *)*res_data,
+ DEBUG("realloc (%p, %" PRIsz ")", (void *)*res_data,
(items_num + pkt_item_num) * res_item_size);
items = realloc(*res_data, (items_num + pkt_item_num) * res_item_size);
if (items == NULL) {
static int ntpd_get_name_from_address(char *buffer, size_t buffer_size,
struct info_peer_summary const *peer_info,
- _Bool do_reverse_lookup) {
+ bool do_reverse_lookup) {
struct sockaddr_storage sa = {0};
socklen_t sa_len;
int flags = 0;
buffer_size, NULL, 0, /* No port name */
flags);
if (status != 0) {
- char errbuf[1024];
ERROR("ntpd plugin: getnameinfo failed: %s",
- (status == EAI_SYSTEM) ? sstrerror(errno, errbuf, sizeof(errbuf))
- : gai_strerror(status));
+ (status == EAI_SYSTEM) ? STRERRNO : gai_strerror(status));
return -1;
}
return 0;
} /* int ntpd_get_name_refclock */
-static int ntpd_get_name(char *buffer, size_t buffer_size,
- struct info_peer_summary const *peer_info) {
- uint32_t addr = ntohl(peer_info->srcadr);
-
- if (!peer_info->v6_flag && ((addr & REFCLOCK_MASK) == REFCLOCK_ADDR))
- return ntpd_get_name_refclock(buffer, buffer_size, peer_info);
- else
- return ntpd_get_name_from_address(buffer, buffer_size, peer_info,
- do_reverse_lookups);
-} /* int ntpd_addr_to_name */
-
static int ntpd_read(void) {
struct info_kernel *ik;
int ik_num;
if (status != 0) {
ERROR("ntpd plugin: ntpd_do_query (REQ_GET_KERNEL) failed with status %i",
status);
+ free(ik);
return status;
} else if ((ik == NULL) || (ik_num == 0) || (ik_size == 0)) {
ERROR("ntpd plugin: ntpd_do_query returned unexpected data. "
"(ik = %p; ik_num = %i; ik_size = %i)",
(void *)ik, ik_num, ik_size);
+ free(ik);
return -1;
}
ERROR(
"ntpd plugin: ntpd_do_query (REQ_PEER_LIST_SUM) failed with status %i",
status);
+ free(ps);
return status;
} else if ((ps == NULL) || (ps_num == 0) || (ps_size == 0)) {
ERROR("ntpd plugin: ntpd_do_query returned unexpected data. "
"(ps = %p; ps_num = %i; ps_size = %i)",
(void *)ps, ps_num, ps_size);
+ free(ps);
return -1;
}
ptr = ps + i;
- status = ntpd_get_name(peername, sizeof(peername), ptr);
+ int is_refclock = !ptr->v6_flag &&
+ ((ntohl(ptr->srcadr) & REFCLOCK_MASK) == REFCLOCK_ADDR);
+
+ if (is_refclock)
+ status = ntpd_get_name_refclock(peername, sizeof(peername), ptr);
+ else
+ status = ntpd_get_name_from_address(peername, sizeof(peername), ptr,
+ do_reverse_lookups);
+
if (status != 0) {
ERROR("ntpd plugin: Determining name of peer failed.");
continue;
}
+ // `0.0.0.0` hosts are caused by POOL servers
+ // see https://github.com/collectd/collectd/issues/2358
+ if (strcmp(peername, "0.0.0.0") == 0) {
+ continue;
+ }
+
refclock_id = ntpd_get_refclock_id(ptr);
/* Convert the `long floating point' offset value to double */
M_LFPTOD(ntohl(ptr->offset_int), ntohl(ptr->offset_frc), offset);
DEBUG("peer %i:\n"
+ " is_refclock= %d\n"
+ " refclock_id= %d\n"
" peername = %s\n"
" srcadr = 0x%08x\n"
" reach = 0%03o\n"
" offset_frc = %i\n"
" offset = %f\n"
" dispersion = %f\n",
- i, peername, ntohl(ptr->srcadr), ptr->reach, ntpd_read_fp(ptr->delay),
+ i, is_refclock, (is_refclock > 0) ? refclock_id : 0, peername,
+ ntohl(ptr->srcadr), ptr->reach, ntpd_read_fp(ptr->delay),
ntohl(ptr->offset_int), ntohl(ptr->offset_frc), offset,
ntpd_read_fp(ptr->dispersion));
- if (refclock_id !=
- 1) /* not the system clock (offset will always be zero.. */
- ntpd_submit_reach("time_offset", peername, ptr->reach, offset);
ntpd_submit_reach("time_dispersion", peername, ptr->reach,
ntpd_read_fp(ptr->dispersion));
- if (refclock_id == 0) /* not a reference clock */
+
+ /* not the system clock (offset will always be zero) */
+ if (!(is_refclock && refclock_id == 1))
+ ntpd_submit_reach("time_offset", peername, ptr->reach, offset);
+
+ if (!is_refclock) /* not a reference clock */
ntpd_submit_reach("delay", peername, ptr->reach,
ntpd_read_fp(ptr->delay));
}
#endif
#define FUNC_ERROR(func) \
do { \
- char errbuf[1024]; \
- ERROR("powerdns plugin: %s failed: %s", func, \
- sstrerror(errno, errbuf, sizeof(errbuf))); \
+ ERROR("powerdns plugin: %s failed: %s", func, STRERRNO); \
} while (0)
#define SOCK_ERROR(func, sockpath) \
do { \
- char errbuf[1024]; \
ERROR("powerdns plugin: Socket `%s` %s failed: %s", sockpath, func, \
- sstrerror(errno, errbuf, sizeof(errbuf))); \
+ STRERRNO); \
} while (0)
#define SERVER_SOCKET LOCALSTATEDIR "/run/pdns.controlsocket"
{"ipv6-questions", "dns_question", "incoming-ipv6"},
{"malloc-bytes", "gauge", "malloc_bytes"},
{"max-mthread-stack", "gauge", "max_mthread_stack"},
- {"no-packet-error", "gauge", "no_packet_error"},
+ {"no-packet-error", "errors", "no_packet_error"},
{"noedns-outqueries", "dns_question", "outgoing-noedns"},
{"noping-outqueries", "dns_question", "outgoing-noping"},
{"over-capacity-drops", "dns_question", "incoming-over_capacity"},
{"uptime", "uptime", NULL}}; /* }}} */
static int lookup_table_length = STATIC_ARRAY_SIZE(lookup_table);
-static llist_t *list = NULL;
+static llist_t *list;
#define PDNS_LOCAL_SOCKPATH LOCALSTATEDIR "/run/" PACKAGE_NAME "-powerdns"
-static char *local_sockpath = NULL;
+static char *local_sockpath;
/* TODO: Do this before 4.4:
* - Update the collectd.conf(5) manpage.
}
if (ds->ds_num != 1) {
- ERROR("powerdns plugin: type `%s' has %zu data sources, "
+ ERROR("powerdns plugin: type `%s' has %" PRIsz " data sources, "
"but I can only handle one.",
type, ds->ds_num);
return;
}
if (0 != parse_value(value_str, &value, ds->ds[0].type)) {
- ERROR("powerdns plugin: Cannot convert `%s' "
- "to a number.",
- value_str);
return;
}
struct tabmntent *mntlist;
if (listmntent(&mntlist, COLLECTD_MNTTAB, NULL, NULL) < 0) {
#if COLLECT_DEBUG
- char errbuf[1024];
- DEBUG("utils_mount: calling listmntent() failed: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ DEBUG("utils_mount: calling listmntent() failed: %s", STRERRNO);
#endif /* COLLECT_DEBUG */
}
/* Get the number of mounted file systems */
if ((bufsize = CMD_STATFS(NULL, 0, FLAGS_STATFS)) < 1) {
#if COLLECT_DEBUG
- char errbuf[1024];
- DEBUG("utils_mount: getv?fsstat failed: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ DEBUG("utils_mount: getv?fsstat failed: %s", STRERRNO);
#endif /* COLLECT_DEBUG */
return NULL;
}
if ((num = CMD_STATFS(buf, bufsize * sizeof(STRUCT_STATFS), FLAGS_STATFS)) <
1) {
#if COLLECT_DEBUG
- char errbuf[1024];
- DEBUG("utils_mount: getv?fsstat failed: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ DEBUG("utils_mount: getv?fsstat failed: %s", STRERRNO);
#endif /* COLLECT_DEBUG */
free(buf);
return NULL;
DEBUG("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB);
if ((fp = fopen(COLLECTD_MNTTAB, "r")) == NULL) {
- char errbuf[1024];
- ERROR("fopen (%s): %s", COLLECTD_MNTTAB,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("fopen (%s): %s", COLLECTD_MNTTAB, STRERRNO);
return NULL;
}
return first;
} /* static cu_mount_t *cu_mount_gen_getmntent (void) */
- /* #endif HAVE_TWO_GETMNTENT || HAVE_GEN_GETMNTENT || HAVE_SUN_GETMNTENT */
#elif HAVE_SEQ_GETMNTENT
#warn "This version of `getmntent' hat not yet been implemented!"
DEBUG("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB);
if ((fp = setmntent(COLLECTD_MNTTAB, "r")) == NULL) {
- char errbuf[1024];
- ERROR("setmntent (%s): %s", COLLECTD_MNTTAB,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("setmntent (%s): %s", COLLECTD_MNTTAB, STRERRNO);
return NULL;
}
DEBUG("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB);
if ((fp = setmntent(COLLECTD_MNTTAB, "r")) == NULL) {
- char errbuf[1024];
- ERROR("setmntent (%s): %s", COLLECTD_MNTTAB,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("setmntent (%s): %s", COLLECTD_MNTTAB, STRERRNO);
return NULL;
}
new = cu_mount_gen_getmntent();
#elif HAVE_SEQ_GETMNTENT
#error "This version of `getmntent' hat not yet been implemented!"
+ #elif HAVE_GETMNTENT_R
+ new = cu_mount_getmntent();
#elif HAVE_ONE_GETMNTENT
new = cu_mount_getmntent();
#else
char *cu_mount_checkoption(char *line, const char *keyword, int full) {
char *line2, *l2, *p1, *p2;
- int l;
+ size_t l;
if (line == NULL || keyword == NULL) {
return NULL;
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
+#include <stdbool.h>
/* Plugin name */
#define PLUGIN_NAME "virt"
+/* Secure strcat macro assuring null termination. Parameter (n) is the size of
+ buffer (d), allowing this macro to be safe for static and dynamic buffers */
+#define SSTRNCAT(d, s, n) \
+ do { \
+ size_t _l = strlen(d); \
+ sstrncpy((d) + _l, (s), (n)-_l); \
+ } while (0)
+
#ifdef LIBVIR_CHECK_VERSION
#if LIBVIR_CHECK_VERSION(0, 9, 2)
#define HAVE_DOM_REASON_RUNNING_WAKEUP 1
#endif
+/*
+ virConnectListAllDomains() appeared in 0.10.2
+ Note that LIBVIR_CHECK_VERSION appeared a year later, so
+ in some systems which actually have virConnectListAllDomains()
+ we can't detect this.
+ */
+#if LIBVIR_CHECK_VERSION(0, 10, 2)
+#define HAVE_LIST_ALL_DOMAINS 1
+#endif
+
#if LIBVIR_CHECK_VERSION(1, 0, 1)
#define HAVE_DOM_REASON_PAUSED_SNAPSHOT 1
#endif
#endif /* LIBVIR_CHECK_VERSION */
+/* structure used for aggregating notification-thread data*/
+typedef struct virt_notif_thread_s {
+ pthread_t event_loop_tid;
+ int domain_event_cb_id;
+ pthread_mutex_t active_mutex; /* protects 'is_active' member access*/
+ bool is_active;
+} virt_notif_thread_t;
+
static const char *config_keys[] = {"Connection",
"RefreshInterval",
"Instances",
"ExtraStats",
+ "PersistentNotification",
NULL};
+/* PersistentNotification is false by default */
+static bool persistent_notification = false;
+
+/* Thread used for handling libvirt notifications events */
+static virt_notif_thread_t notif_thread;
+
const char *domain_states[] = {
[VIR_DOMAIN_NOSTATE] = "no state",
[VIR_DOMAIN_RUNNING] = "the domain is running",
#endif
};
+static int map_domain_event_to_state(int event) {
+ int ret;
+ switch (event) {
+ case VIR_DOMAIN_EVENT_STARTED:
+ ret = VIR_DOMAIN_RUNNING;
+ break;
+ case VIR_DOMAIN_EVENT_SUSPENDED:
+ ret = VIR_DOMAIN_PAUSED;
+ break;
+ case VIR_DOMAIN_EVENT_RESUMED:
+ ret = VIR_DOMAIN_RUNNING;
+ break;
+ case VIR_DOMAIN_EVENT_STOPPED:
+ ret = VIR_DOMAIN_SHUTOFF;
+ break;
+ case VIR_DOMAIN_EVENT_SHUTDOWN:
+ ret = VIR_DOMAIN_SHUTDOWN;
+ break;
+#ifdef HAVE_DOM_STATE_PMSUSPENDED
+ case VIR_DOMAIN_EVENT_PMSUSPENDED:
+ ret = VIR_DOMAIN_PMSUSPENDED;
+ break;
+#endif
+#ifdef HAVE_DOM_REASON_CRASHED
+ case VIR_DOMAIN_EVENT_CRASHED:
+ ret = VIR_DOMAIN_CRASHED;
+ break;
+#endif
+ default:
+ ret = VIR_DOMAIN_NOSTATE;
+ }
+ return ret;
+}
+
#ifdef HAVE_DOM_REASON
+static int map_domain_event_detail_to_reason(int event, int detail) {
+ int ret;
+ switch (event) {
+ case VIR_DOMAIN_EVENT_STARTED:
+ switch (detail) {
+ case VIR_DOMAIN_EVENT_STARTED_BOOTED: /* Normal startup from boot */
+ ret = VIR_DOMAIN_RUNNING_BOOTED;
+ break;
+ case VIR_DOMAIN_EVENT_STARTED_MIGRATED: /* Incoming migration from another
+ host */
+ ret = VIR_DOMAIN_RUNNING_MIGRATED;
+ break;
+ case VIR_DOMAIN_EVENT_STARTED_RESTORED: /* Restored from a state file */
+ ret = VIR_DOMAIN_RUNNING_RESTORED;
+ break;
+ case VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT: /* Restored from snapshot */
+ ret = VIR_DOMAIN_RUNNING_FROM_SNAPSHOT;
+ break;
+#ifdef HAVE_DOM_REASON_RUNNING_WAKEUP
+ case VIR_DOMAIN_EVENT_STARTED_WAKEUP: /* Started due to wakeup event */
+ ret = VIR_DOMAIN_RUNNING_WAKEUP;
+ break;
+#endif
+ default:
+ ret = VIR_DOMAIN_RUNNING_UNKNOWN;
+ }
+ break;
+ case VIR_DOMAIN_EVENT_SUSPENDED:
+ switch (detail) {
+ case VIR_DOMAIN_EVENT_SUSPENDED_PAUSED: /* Normal suspend due to admin
+ pause */
+ ret = VIR_DOMAIN_PAUSED_USER;
+ break;
+ case VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED: /* Suspended for offline
+ migration */
+ ret = VIR_DOMAIN_PAUSED_MIGRATION;
+ break;
+ case VIR_DOMAIN_EVENT_SUSPENDED_IOERROR: /* Suspended due to a disk I/O
+ error */
+ ret = VIR_DOMAIN_PAUSED_IOERROR;
+ break;
+ case VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG: /* Suspended due to a watchdog
+ firing */
+ ret = VIR_DOMAIN_PAUSED_WATCHDOG;
+ break;
+ case VIR_DOMAIN_EVENT_SUSPENDED_RESTORED: /* Restored from paused state
+ file */
+ ret = VIR_DOMAIN_PAUSED_UNKNOWN;
+ break;
+ case VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT: /* Restored from paused
+ snapshot */
+ ret = VIR_DOMAIN_PAUSED_FROM_SNAPSHOT;
+ break;
+ case VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR: /* Suspended after failure during
+ libvirt API call */
+ ret = VIR_DOMAIN_PAUSED_UNKNOWN;
+ break;
+#ifdef HAVE_DOM_REASON_POSTCOPY
+ case VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY: /* Suspended for post-copy
+ migration */
+ ret = VIR_DOMAIN_PAUSED_POSTCOPY;
+ break;
+ case VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY_FAILED: /* Suspended after failed
+ post-copy */
+ ret = VIR_DOMAIN_PAUSED_POSTCOPY_FAILED;
+ break;
+#endif
+ default:
+ ret = VIR_DOMAIN_PAUSED_UNKNOWN;
+ }
+ break;
+ case VIR_DOMAIN_EVENT_RESUMED:
+ switch (detail) {
+ case VIR_DOMAIN_EVENT_RESUMED_UNPAUSED: /* Normal resume due to admin
+ unpause */
+ ret = VIR_DOMAIN_RUNNING_UNPAUSED;
+ break;
+ case VIR_DOMAIN_EVENT_RESUMED_MIGRATED: /* Resumed for completion of
+ migration */
+ ret = VIR_DOMAIN_RUNNING_MIGRATED;
+ break;
+ case VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT: /* Resumed from snapshot */
+ ret = VIR_DOMAIN_RUNNING_FROM_SNAPSHOT;
+ break;
+#ifdef HAVE_DOM_REASON_POSTCOPY
+ case VIR_DOMAIN_EVENT_RESUMED_POSTCOPY: /* Resumed, but migration is still
+ running in post-copy mode */
+ ret = VIR_DOMAIN_RUNNING_POSTCOPY;
+ break;
+#endif
+ default:
+ ret = VIR_DOMAIN_RUNNING_UNKNOWN;
+ }
+ break;
+ case VIR_DOMAIN_EVENT_STOPPED:
+ switch (detail) {
+ case VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN: /* Normal shutdown */
+ ret = VIR_DOMAIN_SHUTOFF_SHUTDOWN;
+ break;
+ case VIR_DOMAIN_EVENT_STOPPED_DESTROYED: /* Forced poweroff from host */
+ ret = VIR_DOMAIN_SHUTOFF_DESTROYED;
+ break;
+ case VIR_DOMAIN_EVENT_STOPPED_CRASHED: /* Guest crashed */
+ ret = VIR_DOMAIN_SHUTOFF_CRASHED;
+ break;
+ case VIR_DOMAIN_EVENT_STOPPED_MIGRATED: /* Migrated off to another host */
+ ret = VIR_DOMAIN_SHUTOFF_MIGRATED;
+ break;
+ case VIR_DOMAIN_EVENT_STOPPED_SAVED: /* Saved to a state file */
+ ret = VIR_DOMAIN_SHUTOFF_SAVED;
+ break;
+ case VIR_DOMAIN_EVENT_STOPPED_FAILED: /* Host emulator/mgmt failed */
+ ret = VIR_DOMAIN_SHUTOFF_FAILED;
+ break;
+ case VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT: /* Offline snapshot loaded */
+ ret = VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT;
+ break;
+ default:
+ ret = VIR_DOMAIN_SHUTOFF_UNKNOWN;
+ }
+ break;
+ case VIR_DOMAIN_EVENT_SHUTDOWN:
+ switch (detail) {
+ case VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED: /* Guest finished shutdown
+ sequence */
+ ret = VIR_DOMAIN_SHUTDOWN_USER;
+ break;
+ default:
+ ret = VIR_DOMAIN_SHUTDOWN_UNKNOWN;
+ }
+ break;
+#ifdef HAVE_DOM_STATE_PMSUSPENDED
+ case VIR_DOMAIN_EVENT_PMSUSPENDED:
+ switch (detail) {
+ case VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY: /* Guest was PM suspended to
+ memory */
+ ret = VIR_DOMAIN_PMSUSPENDED_UNKNOWN;
+ break;
+ case VIR_DOMAIN_EVENT_PMSUSPENDED_DISK: /* Guest was PM suspended to disk */
+ ret = VIR_DOMAIN_PMSUSPENDED_DISK_UNKNOWN;
+ break;
+ default:
+ ret = VIR_DOMAIN_PMSUSPENDED_UNKNOWN;
+ }
+ break;
+#endif
+ case VIR_DOMAIN_EVENT_CRASHED:
+ switch (detail) {
+ case VIR_DOMAIN_EVENT_CRASHED_PANICKED: /* Guest was panicked */
+ ret = VIR_DOMAIN_CRASHED_PANICKED;
+ break;
+ default:
+ ret = VIR_DOMAIN_CRASHED_UNKNOWN;
+ }
+ break;
+ default:
+ ret = VIR_DOMAIN_NOSTATE_UNKNOWN;
+ }
+ return ret;
+}
+
#define DOMAIN_STATE_REASON_MAX_SIZE 20
const char *domain_reasons[][DOMAIN_STATE_REASON_MAX_SIZE] = {
[VIR_DOMAIN_NOSTATE][VIR_DOMAIN_NOSTATE_UNKNOWN] =
[VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_POSTCOPY] =
"running in post-copy migration mode",
#endif
-
[VIR_DOMAIN_BLOCKED][VIR_DOMAIN_BLOCKED_UNKNOWN] =
"the reason is unknown",
[VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_POSTCOPY_FAILED] =
"paused after failed post-copy",
#endif
-
[VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_UNKNOWN] =
"the reason is unknown",
[VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_USER] =
} while (0)
/* Connection. */
-static virConnectPtr conn = 0;
-static char *conn_string = NULL;
+static virConnectPtr conn;
+static char *conn_string;
static c_complain_t conn_complain = C_COMPLAIN_INIT_STATIC;
/* Node information required for %CPU */
static int interval = 60;
/* List of domains, if specified. */
-static ignorelist_t *il_domains = NULL;
+static ignorelist_t *il_domains;
/* List of block devices, if specified. */
-static ignorelist_t *il_block_devices = NULL;
+static ignorelist_t *il_block_devices;
/* List of network interface devices, if specified. */
-static ignorelist_t *il_interface_devices = NULL;
+static ignorelist_t *il_interface_devices;
static int ignore_device_match(ignorelist_t *, const char *domname,
const char *devpath);
typedef struct domain_s {
virDomainPtr ptr;
virDomainInfo info;
+ bool active;
} domain_t;
struct lv_read_state {
};
static void free_domains(struct lv_read_state *state);
-static int add_domain(struct lv_read_state *state, virDomainPtr dom);
+static int add_domain(struct lv_read_state *state, virDomainPtr dom,
+ bool active);
static void free_block_devices(struct lv_read_state *state);
static int add_block_device(struct lv_read_state *state, virDomainPtr dom,
};
/* BlockDeviceFormatBasename */
-_Bool blockdevice_format_basename = 0;
+static bool blockdevice_format_basename;
static enum bd_field blockdevice_format = target;
static enum if_field interface_format = if_name;
static int refresh_lists(struct lv_read_instance *inst);
- struct lv_info {
- virDomainInfo di;
- unsigned long long total_user_cpu_time;
- unsigned long long total_syst_cpu_time;
- };
-
struct lv_block_info {
virDomainBlockStatsStruct bi;
virErrorPtr err; \
err = (conn) ? virConnGetLastError((conn)) : virGetLastError(); \
if (err) \
- ERROR("%s: %s", (s), err->message); \
+ ERROR(PLUGIN_NAME " plugin: %s failed: %s", (s), err->message); \
} while (0)
- static void init_lv_info(struct lv_info *info) {
- if (info != NULL)
- memset(info, 0, sizeof(*info));
- }
-
- static int lv_domain_info(virDomainPtr dom, struct lv_info *info) {
- #ifdef HAVE_CPU_STATS
- virTypedParameterPtr param = NULL;
- int nparams = 0;
- #endif /* HAVE_CPU_STATS */
- int ret = virDomainGetInfo(dom, &(info->di));
- if (ret != 0) {
- return ret;
- }
-
- #ifdef HAVE_CPU_STATS
- nparams = virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0);
- if (nparams < 0) {
- VIRT_ERROR(conn, "getting the CPU params count");
- return -1;
- }
-
- param = calloc(nparams, sizeof(virTypedParameter));
- if (param == NULL) {
- ERROR("virt plugin: alloc(%i) for cpu parameters failed.", nparams);
- return -1;
- }
-
- ret = virDomainGetCPUStats(dom, param, nparams, -1, 1, 0); // total stats.
- if (ret < 0) {
- virTypedParamsClear(param, nparams);
- sfree(param);
- VIRT_ERROR(conn, "getting the disk params values");
- return -1;
- }
-
- for (int i = 0; i < nparams; ++i) {
- if (!strcmp(param[i].field, "user_time"))
- info->total_user_cpu_time = param[i].value.ul;
- else if (!strcmp(param[i].field, "system_time"))
- info->total_syst_cpu_time = param[i].value.ul;
- }
-
- virTypedParamsClear(param, nparams);
- sfree(param);
- #endif /* HAVE_CPU_STATS */
-
- return 0;
- }
-
static void init_value_list(value_list_t *vl, virDomainPtr dom) {
- int n;
const char *name;
char uuid[VIR_UUID_STRING_BUFLEN];
if (hostname_format[i] == hf_none)
continue;
- n = DATA_MAX_NAME_LEN - strlen(vl->host) - 2;
-
- if (i > 0 && n >= 1) {
- strncat(vl->host, ":", 1);
- n--;
- }
+ if (i > 0)
+ SSTRNCAT(vl->host, ":", sizeof(vl->host));
switch (hostname_format[i]) {
case hf_none:
break;
case hf_hostname:
- strncat(vl->host, hostname_g, n);
+ SSTRNCAT(vl->host, hostname_g, sizeof(vl->host));
break;
case hf_name:
name = virDomainGetName(dom);
if (name)
- strncat(vl->host, name, n);
+ SSTRNCAT(vl->host, name, sizeof(vl->host));
break;
case hf_uuid:
if (virDomainGetUUIDString(dom, uuid) == 0)
- strncat(vl->host, uuid, n);
+ SSTRNCAT(vl->host, uuid, sizeof(vl->host));
break;
}
}
- vl->host[sizeof(vl->host) - 1] = '\0';
-
/* Construct the plugin instance field according to PluginInstanceFormat. */
for (int i = 0; i < PLGINST_MAX_FIELDS; ++i) {
if (plugin_instance_format[i] == plginst_none)
continue;
- n = sizeof(vl->plugin_instance) - strlen(vl->plugin_instance) - 2;
-
- if (i > 0 && n >= 1) {
- strncat(vl->plugin_instance, ":", 1);
- n--;
- }
+ if (i > 0)
+ SSTRNCAT(vl->plugin_instance, ":", sizeof(vl->plugin_instance));
switch (plugin_instance_format[i]) {
case plginst_none:
case plginst_name:
name = virDomainGetName(dom);
if (name)
- strncat(vl->plugin_instance, name, n);
+ SSTRNCAT(vl->plugin_instance, name, sizeof(vl->plugin_instance));
break;
case plginst_uuid:
if (virDomainGetUUIDString(dom, uuid) == 0)
- strncat(vl->plugin_instance, uuid, n);
+ SSTRNCAT(vl->plugin_instance, uuid, sizeof(vl->plugin_instance));
break;
}
}
- vl->plugin_instance[sizeof(vl->plugin_instance) - 1] = '\0';
-
} /* void init_value_list */
static int init_notif(notification_t *notif, const virDomainPtr domain,
submit(dom, type, devname, values, STATIC_ARRAY_SIZE(values));
} /* void submit_derive2 */
- static void pcpu_submit(virDomainPtr dom, struct lv_info *info) {
- #ifdef HAVE_CPU_STATS
- if (extra_stats & ex_stats_pcpu)
- submit_derive2("ps_cputime", info->total_user_cpu_time,
- info->total_syst_cpu_time, dom, NULL);
- #endif /* HAVE_CPU_STATS */
- }
-
static double cpu_ns_to_percent(unsigned int node_cpus,
unsigned long long cpu_time_old,
unsigned long long cpu_time_new) {
(time_diff_sec * node_cpus * NANOSEC_IN_SEC);
}
- DEBUG(PLUGIN_NAME ": node_cpus=%u cpu_time_old=%llu cpu_time_new=%llu"
- "cpu_time_diff=%llu time_diff_sec=%f percent=%f",
- node_cpus, cpu_time_old, cpu_time_new, cpu_time_diff, time_diff_sec,
- percent);
+ DEBUG(PLUGIN_NAME ": node_cpus=%u cpu_time_old=%" PRIu64
+ " cpu_time_new=%" PRIu64 "cpu_time_diff=%" PRIu64
+ " time_diff_sec=%f percent=%f",
+ node_cpus, (uint64_t)cpu_time_old, (uint64_t)cpu_time_new,
+ (uint64_t)cpu_time_diff, time_diff_sec, percent);
return percent;
}
return ex_stats_flags;
}
-static void domain_state_submit(virDomainPtr dom, int state, int reason) {
-
- if ((state < 0) || (state >= STATIC_ARRAY_SIZE(domain_states))) {
+static void domain_state_submit_notif(virDomainPtr dom, int state, int reason) {
+ if ((state < 0) || ((size_t)state >= STATIC_ARRAY_SIZE(domain_states))) {
ERROR(PLUGIN_NAME ": Array index out of bounds: state=%d", state);
return;
}
char msg[DATA_MAX_NAME_LEN];
const char *state_str = domain_states[state];
#ifdef HAVE_DOM_REASON
- if ((reason < 0) || (reason >= STATIC_ARRAY_SIZE(domain_reasons[0]))) {
+ if ((reason < 0) ||
+ ((size_t)reason >= STATIC_ARRAY_SIZE(domain_reasons[0]))) {
ERROR(PLUGIN_NAME ": Array index out of bounds: reason=%d", reason);
return;
}
return 0;
}
if (strcasecmp(key, "BlockDeviceFormatBasename") == 0) {
- blockdevice_format_basename = IS_TRUE(value);
+ blockdevice_format_basename = IS_TRUE(value) ? true : false;
return 0;
}
if (strcasecmp(key, "InterfaceDevice") == 0) {
}
}
+ if (strcasecmp(key, "PersistentNotification") == 0) {
+ persistent_notification = IS_TRUE(value);
+ return 0;
+ }
+
/* Unrecognised option. */
return -1;
}
unsigned char *cpu_maps, int cpu_map_len) {
for (int cpu = 0; cpu < max_cpus; ++cpu) {
char type_instance[DATA_MAX_NAME_LEN];
- _Bool is_set = VIR_CPU_USABLE(cpu_maps, cpu_map_len, vcpu, cpu) ? 1 : 0;
+ bool is_set = VIR_CPU_USABLE(cpu_maps, cpu_map_len, vcpu, cpu);
snprintf(type_instance, sizeof(type_instance), "vcpu_%d-cpu_%d", vcpu, cpu);
submit(dom, "cpu_affinity", type_instance, &(value_t){.gauge = is_set}, 1);
virVcpuInfoPtr vinfo = calloc(nr_virt_cpu, sizeof(vinfo[0]));
if (vinfo == NULL) {
- ERROR(PLUGIN_NAME " plugin: malloc failed.");
+ ERROR(PLUGIN_NAME " plugin: calloc failed.");
return -1;
}
unsigned char *cpumaps = calloc(nr_virt_cpu, cpu_map_len);
if (cpumaps == NULL) {
- ERROR(PLUGIN_NAME " plugin: malloc failed.");
+ ERROR(PLUGIN_NAME " plugin: calloc failed.");
sfree(vinfo);
return -1;
}
return 0;
}
+ #ifdef HAVE_CPU_STATS
+ static int get_pcpu_stats(virDomainPtr dom) {
+ int nparams = virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0);
+ if (nparams < 0) {
+ VIRT_ERROR(conn, "getting the CPU params count");
+ return -1;
+ }
+
+ virTypedParameterPtr param = calloc(nparams, sizeof(virTypedParameter));
+ if (param == NULL) {
+ ERROR(PLUGIN_NAME " plugin: alloc(%i) for cpu parameters failed.", nparams);
+ return -1;
+ }
+
+ int ret = virDomainGetCPUStats(dom, param, nparams, -1, 1, 0); // total stats.
+ if (ret < 0) {
+ virTypedParamsClear(param, nparams);
+ sfree(param);
+ VIRT_ERROR(conn, "getting the CPU params values");
+ return -1;
+ }
+
+ unsigned long long total_user_cpu_time = 0;
+ unsigned long long total_syst_cpu_time = 0;
+
+ for (int i = 0; i < nparams; ++i) {
+ if (!strcmp(param[i].field, "user_time"))
+ total_user_cpu_time = param[i].value.ul;
+ else if (!strcmp(param[i].field, "system_time"))
+ total_syst_cpu_time = param[i].value.ul;
+ }
+
+ if (total_user_cpu_time > 0 || total_syst_cpu_time > 0)
+ submit_derive2("ps_cputime", total_user_cpu_time, total_syst_cpu_time, dom,
+ NULL);
+
+ virTypedParamsClear(param, nparams);
+ sfree(param);
+
+ return 0;
+ }
+ #endif /* HAVE_CPU_STATS */
+
#ifdef HAVE_DOM_REASON
+
+static void domain_state_submit(virDomainPtr dom, int state, int reason) {
+ value_t values[] = {
+ {.gauge = (gauge_t)state}, {.gauge = (gauge_t)reason},
+ };
+
+ submit(dom, "domain_state", NULL, values, STATIC_ARRAY_SIZE(values));
+}
+
static int get_domain_state(virDomainPtr domain) {
int domain_state = 0;
int domain_reason = 0;
}
domain_state_submit(domain, domain_state, domain_reason);
+
return status;
}
+
+#ifdef HAVE_LIST_ALL_DOMAINS
+static int get_domain_state_notify(virDomainPtr domain) {
+ int domain_state = 0;
+ int domain_reason = 0;
+
+ int status = virDomainGetState(domain, &domain_state, &domain_reason, 0);
+ if (status != 0) {
+ ERROR(PLUGIN_NAME " plugin: virDomainGetState failed with status %i.",
+ status);
+ return status;
+ }
+
+ if (persistent_notification)
+ domain_state_submit_notif(domain, domain_state, domain_reason);
+
+ return status;
+}
+#endif /* HAVE_LIST_ALL_DOMAINS */
#endif /* HAVE_DOM_REASON */
static int get_memory_stats(virDomainPtr domain) {
#define NM_ADD_STR_ITEMS(_items, _size) \
do { \
- for (int _i = 0; _i < _size; ++_i) { \
+ for (size_t _i = 0; _i < _size; ++_i) { \
DEBUG(PLUGIN_NAME \
" plugin: Adding notification metadata name=%s value=%s", \
_items[_i].name, _items[_i].value); \
{.name = "name", .value = fs_info->name},
{.name = "fstype", .value = fs_info->fstype}};
- for (int i = 0; i < fs_info->ndevAlias; ++i) {
+ for (size_t i = 0; i < fs_info->ndevAlias; ++i) {
fs_dev_alias[i].name = "devAlias";
fs_dev_alias[i].value = fs_info->devAlias[i];
}
#endif /* HAVE_JOB_STATS */
static int get_domain_metrics(domain_t *domain) {
- struct lv_info info;
-
if (!domain || !domain->ptr) {
- ERROR(PLUGIN_NAME ": get_domain_metrics: NULL pointer");
+ ERROR(PLUGIN_NAME "plugin: get_domain_metrics: NULL pointer");
return -1;
}
- init_lv_info(&info);
- int status = lv_domain_info(domain->ptr, &info);
+ virDomainInfo info;
+ int status = virDomainGetInfo(domain->ptr, &info);
if (status != 0) {
ERROR(PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.",
status);
* We need to get it from virDomainGetState.
*/
GET_STATS(get_domain_state, "domain reason", domain->ptr);
-#else
- /* virDomainGetState is not available. Submit 0, which corresponds to
- * unknown reason. */
- domain_state_submit(domain->ptr, info.state, 0);
#endif
}
/* Gather remaining stats only for running domains */
- if (info.di.state != VIR_DOMAIN_RUNNING)
+ if (info.state != VIR_DOMAIN_RUNNING)
return 0;
- pcpu_submit(domain->ptr, &info);
- cpu_submit(domain, info.di.cpuTime);
+ #ifdef HAVE_CPU_STATS
+ if (extra_stats & ex_stats_pcpu)
+ get_pcpu_stats(domain->ptr);
+ #endif
+
+ cpu_submit(domain, info.cpuTime);
- memory_submit(domain->ptr, (gauge_t)info.di.memory * 1024);
+ memory_submit(domain->ptr, (gauge_t)info.memory * 1024);
- GET_STATS(get_vcpu_stats, "vcpu stats", domain->ptr, info.di.nrVirtCpu);
+ GET_STATS(get_vcpu_stats, "vcpu stats", domain->ptr, info.nrVirtCpu);
GET_STATS(get_memory_stats, "memory stats", domain->ptr);
#ifdef HAVE_PERF_STATS
#endif
/* Update cached virDomainInfo. It has to be done after cpu_submit */
- memcpy(&domain->info, &info.di, sizeof(domain->info));
+ memcpy(&domain->info, &info, sizeof(domain->info));
+
return 0;
}
return 0;
}
+static int domain_lifecycle_event_cb(__attribute__((unused)) virConnectPtr con_,
+ virDomainPtr dom, int event, int detail,
+ __attribute__((unused)) void *opaque) {
+ int domain_state = map_domain_event_to_state(event);
+ int domain_reason = 0; /* 0 means UNKNOWN reason for any state */
+#ifdef HAVE_DOM_REASON
+ domain_reason = map_domain_event_detail_to_reason(event, detail);
+#endif
+ domain_state_submit_notif(dom, domain_state, domain_reason);
+
+ return 0;
+}
+
+static int register_event_impl(void) {
+ if (virEventRegisterDefaultImpl() < 0) {
+ virErrorPtr err = virGetLastError();
+ ERROR(PLUGIN_NAME
+ " plugin: error while event implementation registering: %s",
+ err && err->message ? err->message : "Unknown error");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void virt_notif_thread_set_active(virt_notif_thread_t *thread_data,
+ const bool active) {
+ assert(thread_data != NULL);
+ pthread_mutex_lock(&thread_data->active_mutex);
+ thread_data->is_active = active;
+ pthread_mutex_unlock(&thread_data->active_mutex);
+}
+
+static bool virt_notif_thread_is_active(virt_notif_thread_t *thread_data) {
+ bool active = false;
+
+ assert(thread_data != NULL);
+ pthread_mutex_lock(&thread_data->active_mutex);
+ active = thread_data->is_active;
+ pthread_mutex_unlock(&thread_data->active_mutex);
+
+ return active;
+}
+
+/* worker function running default event implementation */
+static void *event_loop_worker(void *arg) {
+ virt_notif_thread_t *thread_data = (virt_notif_thread_t *)arg;
+
+ while (virt_notif_thread_is_active(thread_data)) {
+ if (virEventRunDefaultImpl() < 0) {
+ virErrorPtr err = virGetLastError();
+ ERROR(PLUGIN_NAME " plugin: failed to run event loop: %s\n",
+ err && err->message ? err->message : "Unknown error");
+ }
+ }
+
+ return NULL;
+}
+
+static int virt_notif_thread_init(virt_notif_thread_t *thread_data) {
+ int ret;
+
+ assert(thread_data != NULL);
+ ret = pthread_mutex_init(&thread_data->active_mutex, NULL);
+ if (ret != 0) {
+ ERROR(PLUGIN_NAME ": Failed to initialize mutex, err %u", ret);
+ return ret;
+ }
+
+ /**
+ * '0' and positive integers are meaningful ID's, therefore setting
+ * domain_event_cb_id to '-1'
+ */
+ thread_data->domain_event_cb_id = -1;
+ pthread_mutex_lock(&thread_data->active_mutex);
+ thread_data->is_active = false;
+ pthread_mutex_unlock(&thread_data->active_mutex);
+
+ return 0;
+}
+
+/* register domain event callback and start event loop thread */
+static int start_event_loop(virt_notif_thread_t *thread_data) {
+ assert(thread_data != NULL);
+ thread_data->domain_event_cb_id = virConnectDomainEventRegisterAny(
+ conn, NULL, VIR_DOMAIN_EVENT_ID_LIFECYCLE,
+ VIR_DOMAIN_EVENT_CALLBACK(domain_lifecycle_event_cb), NULL, NULL);
+ if (thread_data->domain_event_cb_id == -1) {
+ ERROR(PLUGIN_NAME " plugin: error while callback registering");
+ return -1;
+ }
+
+ virt_notif_thread_set_active(thread_data, 1);
+ if (pthread_create(&thread_data->event_loop_tid, NULL, event_loop_worker,
+ thread_data)) {
+ ERROR(PLUGIN_NAME " plugin: failed event loop thread creation");
+ virConnectDomainEventDeregisterAny(conn, thread_data->domain_event_cb_id);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* stop event loop thread and deregister callback */
+static void stop_event_loop(virt_notif_thread_t *thread_data) {
+ /* stopping loop and de-registering event handler*/
+ virt_notif_thread_set_active(thread_data, 0);
+ if (conn != NULL && thread_data->domain_event_cb_id != -1)
+ virConnectDomainEventDeregisterAny(conn, thread_data->domain_event_cb_id);
+
+ if (pthread_join(notif_thread.event_loop_tid, NULL) != 0)
+ ERROR(PLUGIN_NAME " plugin: stopping notification thread failed");
+}
+
+static int persistent_domains_state_notification(void) {
+ int status = 0;
+ int n;
+#ifdef HAVE_LIST_ALL_DOMAINS
+ virDomainPtr *domains = NULL;
+ n = virConnectListAllDomains(conn, &domains,
+ VIR_CONNECT_LIST_DOMAINS_PERSISTENT);
+ if (n < 0) {
+ VIRT_ERROR(conn, "reading list of persistent domains");
+ status = -1;
+ } else {
+ DEBUG(PLUGIN_NAME " plugin: getting state of %i persistent domains", n);
+ /* Fetch each persistent domain's state and notify it */
+ int n_notified = n;
+ for (int i = 0; i < n; ++i) {
+ status = get_domain_state_notify(domains[i]);
+ if (status != 0) {
+ n_notified--;
+ ERROR(PLUGIN_NAME " plugin: could not notify state of domain %s",
+ virDomainGetName(domains[i]));
+ }
+ virDomainFree(domains[i]);
+ }
+
+ sfree(domains);
+ DEBUG(PLUGIN_NAME " plugin: notified state of %i persistent domains",
+ n_notified);
+ }
+#else
+ n = virConnectNumOfDomains(conn);
+ if (n > 0) {
+ int *domids;
+ /* Get list of domains. */
+ domids = calloc(n, sizeof(*domids));
+ if (domids == NULL) {
+ ERROR(PLUGIN_NAME " plugin: calloc failed.");
+ return -1;
+ }
+ n = virConnectListDomains(conn, domids, n);
+ if (n < 0) {
+ VIRT_ERROR(conn, "reading list of domains");
+ sfree(domids);
+ return -1;
+ }
+ /* Fetch info of each active domain and notify it */
+ for (int i = 0; i < n; ++i) {
+ virDomainInfo info;
+ virDomainPtr dom = NULL;
+ dom = virDomainLookupByID(conn, domids[i]);
+ if (dom == NULL) {
+ VIRT_ERROR(conn, "virDomainLookupByID");
+ /* Could be that the domain went away -- ignore it anyway. */
+ continue;
+ }
+ status = virDomainGetInfo(dom, &info);
+ if (status == 0)
+ /* virDomainGetState is not available. Submit 0, which corresponds to
+ * unknown reason. */
+ domain_state_submit_notif(dom, info.state, 0);
+ else
+ ERROR(PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.",
+ status);
+
+ virDomainFree(dom);
+ }
+ sfree(domids);
+ }
+#endif
+
+ return status;
+}
+
static int lv_read(user_data_t *ud) {
time_t t;
struct lv_read_instance *inst = NULL;
inst = ud->data;
state = &inst->read_state;
+ bool reconnect = conn == NULL ? true : false;
+ /* event implementation must be registered before connection is opened */
if (inst->id == 0) {
+ if (!persistent_notification && reconnect)
+ if (register_event_impl() != 0)
+ return -1;
+
if (lv_connect() < 0)
return -1;
+
+ if (!persistent_notification && reconnect && conn != NULL)
+ if (start_event_loop(¬if_thread) != 0)
+ return -1;
}
time(&t);
if ((last_refresh == (time_t)0) ||
((interval > 0) && ((last_refresh + interval) <= t))) {
if (refresh_lists(inst) != 0) {
- if (inst->id == 0)
+ if (inst->id == 0) {
+ if (!persistent_notification)
+ stop_event_loop(¬if_thread);
lv_disconnect();
+ }
return -1;
}
last_refresh = t;
}
-#if 0
- for (int i = 0; i < nr_domains; ++i)
- fprintf (stderr, "domain %s\n", virDomainGetName (state->domains[i].ptr));
- for (int i = 0; i < nr_block_devices; ++i)
- fprintf (stderr, "block device %d %s:%s\n",
- i, virDomainGetName (block_devices[i].dom),
- block_devices[i].path);
- for (int i = 0; i < nr_interface_devices; ++i)
- fprintf (stderr, "interface device %d %s:%s\n",
- i, virDomainGetName (interface_devices[i].dom),
- interface_devices[i].path);
+ /* persistent domains state notifications are handled by instance 0 */
+ if (inst->id == 0 && persistent_notification) {
+ int status = persistent_domains_state_notification();
+ if (status != 0)
+ DEBUG(PLUGIN_NAME " plugin: persistent_domains_state_notifications "
+ "returned with status %i",
+ status);
+ }
+
+#if COLLECT_DEBUG
+ for (int i = 0; i < state->nr_domains; ++i)
+ DEBUG(PLUGIN_NAME " plugin: domain %s",
+ virDomainGetName(state->domains[i].ptr));
+ for (int i = 0; i < state->nr_block_devices; ++i)
+ DEBUG(PLUGIN_NAME " plugin: block device %d %s:%s", i,
+ virDomainGetName(state->block_devices[i].dom),
+ state->block_devices[i].path);
+ for (int i = 0; i < state->nr_interface_devices; ++i)
+ DEBUG(PLUGIN_NAME " plugin: interface device %d %s:%s", i,
+ virDomainGetName(state->interface_devices[i].dom),
+ state->interface_devices[i].path);
#endif
/* Get domains' metrics */
for (int i = 0; i < state->nr_domains; ++i) {
- int status = get_domain_metrics(&state->domains[i]);
+ domain_t *dom = &state->domains[i];
+ int status = 0;
+ if (dom->active)
+ status = get_domain_metrics(dom);
+#ifdef HAVE_DOM_REASON
+ else
+ status = get_domain_state(dom->ptr);
+#endif
+
if (status != 0)
ERROR(PLUGIN_NAME " failed to get metrics for domain=%s",
- virDomainGetName(state->domains[i].ptr));
+ virDomainGetName(dom->ptr));
}
/* Get block device stats for each domain. */
memset(lv_ud, 0, sizeof(*lv_ud));
- snprintf(inst->tag, sizeof(inst->tag), "%s-%zu", PLUGIN_NAME, i);
+ snprintf(inst->tag, sizeof(inst->tag), "%s-%" PRIsz, PLUGIN_NAME, i);
inst->id = i;
user_data_t *ud = &(lv_ud->ud);
ud->free_func = NULL;
INFO(PLUGIN_NAME " plugin: reader %s initialized", inst->tag);
+
return plugin_register_complex_read(NULL, inst->tag, callback, 0, ud);
}
struct lv_read_state *state = &(inst->read_state);
lv_clean_read_state(state);
+
INFO(PLUGIN_NAME " plugin: reader %s finalized", inst->tag);
}
if (virInitialize() != 0)
return -1;
+ /* event implementation must be registered before connection is opened */
+ if (!persistent_notification)
+ if (register_event_impl() != 0)
+ return -1;
+
if (lv_connect() != 0)
return -1;
+ DEBUG(PLUGIN_NAME " plugin: starting event loop");
+
+ if (!persistent_notification) {
+ virt_notif_thread_init(¬if_thread);
+ if (start_event_loop(¬if_thread) != 0)
+ return -1;
+ }
+
DEBUG(PLUGIN_NAME " plugin: starting %i instances", nr_instances);
for (int i = 0; i < nr_instances; ++i)
- lv_init_instance(i, lv_read);
+ if (lv_init_instance(i, lv_read) != 0)
+ return -1;
return 0;
}
return 0;
}
-/*
- virConnectListAllDomains() appeared in 0.10.2
- Note that LIBVIR_CHECK_VERSION appeared a year later, so
- in some systems which actually have virConnectListAllDomains()
- we can't detect this.
- */
-#ifdef LIBVIR_CHECK_VERSION
-#if LIBVIR_CHECK_VERSION(0, 10, 2)
-#define HAVE_LIST_ALL_DOMAINS 1
-#endif
-#endif
-
static int refresh_lists(struct lv_read_instance *inst) {
struct lv_read_state *state = &inst->read_state;
int n;
+#ifndef HAVE_LIST_ALL_DOMAINS
n = virConnectNumOfDomains(conn);
if (n < 0) {
VIRT_ERROR(conn, "reading number of domains");
return -1;
}
+#endif
lv_clean_read_state(state);
- if (n > 0) {
+#ifndef HAVE_LIST_ALL_DOMAINS
+ if (n == 0)
+ goto end;
+#endif
+
#ifdef HAVE_LIST_ALL_DOMAINS
- virDomainPtr *domains;
- n = virConnectListAllDomains(conn, &domains,
- VIR_CONNECT_LIST_DOMAINS_ACTIVE);
+ virDomainPtr *domains, *domains_inactive;
+ int m = virConnectListAllDomains(conn, &domains_inactive,
+ VIR_CONNECT_LIST_DOMAINS_INACTIVE);
+ n = virConnectListAllDomains(conn, &domains, VIR_CONNECT_LIST_DOMAINS_ACTIVE);
#else
- int *domids;
+ int *domids;
- /* Get list of domains. */
- domids = malloc(sizeof(*domids) * n);
- if (domids == NULL) {
- ERROR(PLUGIN_NAME " plugin: malloc failed.");
- return -1;
- }
+ /* Get list of domains. */
+ domids = calloc(n, sizeof(*domids));
+ if (domids == NULL) {
+ ERROR(PLUGIN_NAME " plugin: calloc failed.");
+ return -1;
+ }
- n = virConnectListDomains(conn, domids, n);
+ n = virConnectListDomains(conn, domids, n);
#endif
- if (n < 0) {
- VIRT_ERROR(conn, "reading list of domains");
+ if (n < 0) {
+ VIRT_ERROR(conn, "reading list of domains");
#ifndef HAVE_LIST_ALL_DOMAINS
- sfree(domids);
+ sfree(domids);
+#else
+ for (int i = 0; i < m; ++i)
+ virDomainFree(domains_inactive[i]);
+ sfree(domains_inactive);
#endif
- return -1;
+ return -1;
+ }
+
+#ifdef HAVE_LIST_ALL_DOMAINS
+ for (int i = 0; i < m; ++i)
+ if (add_domain(state, domains_inactive[i], 0) < 0) {
+ ERROR(PLUGIN_NAME " plugin: malloc failed.");
+ virDomainFree(domains_inactive[i]);
+ domains_inactive[i] = NULL;
+ continue;
}
+#endif
- /* Fetch each domain and add it to the list, unless ignore. */
- for (int i = 0; i < n; ++i) {
- const char *name;
- char *xml = NULL;
- xmlDocPtr xml_doc = NULL;
- xmlXPathContextPtr xpath_ctx = NULL;
- xmlXPathObjectPtr xpath_obj = NULL;
- char tag[PARTITION_TAG_MAX_LEN] = {'\0'};
- virDomainInfo info;
- int status;
+ /* Fetch each domain and add it to the list, unless ignore. */
+ for (int i = 0; i < n; ++i) {
+ const char *name;
+ char *xml = NULL;
+ xmlDocPtr xml_doc = NULL;
+ xmlXPathContextPtr xpath_ctx = NULL;
+ xmlXPathObjectPtr xpath_obj = NULL;
+ char tag[PARTITION_TAG_MAX_LEN] = {'\0'};
+ virDomainInfo info;
+ int status;
#ifdef HAVE_LIST_ALL_DOMAINS
- virDomainPtr dom = domains[i];
+ virDomainPtr dom = domains[i];
#else
- virDomainPtr dom = NULL;
- dom = virDomainLookupByID(conn, domids[i]);
- if (dom == NULL) {
- VIRT_ERROR(conn, "virDomainLookupByID");
- /* Could be that the domain went away -- ignore it anyway. */
- continue;
- }
+ virDomainPtr dom = NULL;
+ dom = virDomainLookupByID(conn, domids[i]);
+ if (dom == NULL) {
+ VIRT_ERROR(conn, "virDomainLookupByID");
+ /* Could be that the domain went away -- ignore it anyway. */
+ continue;
+ }
#endif
- name = virDomainGetName(dom);
- if (name == NULL) {
- VIRT_ERROR(conn, "virDomainGetName");
- goto cont;
- }
+ if (add_domain(state, dom, 1) < 0) {
+ /*
+ * When domain is already tracked, then there is
+ * no problem with memory handling (will be freed
+ * with the rest of domains cached data)
+ * But in case of error like this (error occurred
+ * before adding domain to track) we have to take
+ * care it ourselves and call virDomainFree
+ */
+ ERROR(PLUGIN_NAME " plugin: malloc failed.");
+ virDomainFree(dom);
+ goto cont;
+ }
- status = virDomainGetInfo(dom, &info);
- if (status != 0) {
- ERROR(PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.",
- status);
- continue;
- }
+ name = virDomainGetName(dom);
+ if (name == NULL) {
+ VIRT_ERROR(conn, "virDomainGetName");
+ goto cont;
+ }
- if (info.state != VIR_DOMAIN_RUNNING) {
- DEBUG(PLUGIN_NAME " plugin: skipping inactive domain %s", name);
- continue;
- }
+ status = virDomainGetInfo(dom, &info);
+ if (status != 0) {
+ ERROR(PLUGIN_NAME " plugin: virDomainGetInfo failed with status %i.",
+ status);
+ continue;
+ }
- if (il_domains && ignorelist_match(il_domains, name) != 0)
- goto cont;
+ if (info.state != VIR_DOMAIN_RUNNING) {
+ DEBUG(PLUGIN_NAME " plugin: skipping inactive domain %s", name);
+ continue;
+ }
- /* Get a list of devices for this domain. */
- xml = virDomainGetXMLDesc(dom, 0);
- if (!xml) {
- VIRT_ERROR(conn, "virDomainGetXMLDesc");
- goto cont;
- }
+ if (il_domains && ignorelist_match(il_domains, name) != 0)
+ goto cont;
- /* Yuck, XML. Parse out the devices. */
- xml_doc = xmlReadDoc((xmlChar *)xml, NULL, NULL, XML_PARSE_NONET);
- if (xml_doc == NULL) {
- VIRT_ERROR(conn, "xmlReadDoc");
- goto cont;
- }
+ /* Get a list of devices for this domain. */
+ xml = virDomainGetXMLDesc(dom, 0);
+ if (!xml) {
+ VIRT_ERROR(conn, "virDomainGetXMLDesc");
+ goto cont;
+ }
- xpath_ctx = xmlXPathNewContext(xml_doc);
+ /* Yuck, XML. Parse out the devices. */
+ xml_doc = xmlReadDoc((xmlChar *)xml, NULL, NULL, XML_PARSE_NONET);
+ if (xml_doc == NULL) {
+ VIRT_ERROR(conn, "xmlReadDoc");
+ goto cont;
+ }
- if (lv_domain_get_tag(xpath_ctx, name, tag) < 0) {
- ERROR(PLUGIN_NAME " plugin: lv_domain_get_tag failed.");
- goto cont;
- }
+ xpath_ctx = xmlXPathNewContext(xml_doc);
- if (!lv_instance_include_domain(inst, name, tag))
- goto cont;
+ if (lv_domain_get_tag(xpath_ctx, name, tag) < 0) {
+ ERROR(PLUGIN_NAME " plugin: lv_domain_get_tag failed.");
+ goto cont;
+ }
- if (add_domain(state, dom) < 0) {
- ERROR(PLUGIN_NAME " plugin: malloc failed.");
- goto cont;
- }
+ if (!lv_instance_include_domain(inst, name, tag))
+ goto cont;
- /* Block devices. */
- const char *bd_xmlpath = "/domain/devices/disk/target[@dev]";
- if (blockdevice_format == source)
- bd_xmlpath = "/domain/devices/disk/source[@dev]";
- xpath_obj = xmlXPathEval((const xmlChar *)bd_xmlpath, xpath_ctx);
+ /* Block devices. */
+ const char *bd_xmlpath = "/domain/devices/disk/target[@dev]";
+ if (blockdevice_format == source)
+ bd_xmlpath = "/domain/devices/disk/source[@dev]";
+ xpath_obj = xmlXPathEval((const xmlChar *)bd_xmlpath, xpath_ctx);
- if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET ||
- xpath_obj->nodesetval == NULL)
- goto cont;
+ if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET ||
+ xpath_obj->nodesetval == NULL)
+ goto cont;
- for (int j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) {
- xmlNodePtr node;
- char *path = NULL;
+ for (int j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) {
+ xmlNodePtr node;
+ char *path = NULL;
- node = xpath_obj->nodesetval->nodeTab[j];
- if (!node)
- continue;
- path = (char *)xmlGetProp(node, (xmlChar *)"dev");
- if (!path)
- continue;
+ node = xpath_obj->nodesetval->nodeTab[j];
+ if (!node)
+ continue;
+ path = (char *)xmlGetProp(node, (xmlChar *)"dev");
+ if (!path)
+ continue;
- if (il_block_devices &&
- ignore_device_match(il_block_devices, name, path) != 0)
- goto cont2;
+ if (il_block_devices &&
+ ignore_device_match(il_block_devices, name, path) != 0)
+ goto cont2;
- add_block_device(state, dom, path);
- cont2:
- if (path)
- xmlFree(path);
- }
- xmlXPathFreeObject(xpath_obj);
+ add_block_device(state, dom, path);
+ cont2:
+ if (path)
+ xmlFree(path);
+ }
+ xmlXPathFreeObject(xpath_obj);
+
+ /* Network interfaces. */
+ xpath_obj = xmlXPathEval(
+ (xmlChar *)"/domain/devices/interface[target[@dev]]", xpath_ctx);
+ if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET ||
+ xpath_obj->nodesetval == NULL)
+ goto cont;
- /* Network interfaces. */
- xpath_obj = xmlXPathEval(
- (xmlChar *)"/domain/devices/interface[target[@dev]]", xpath_ctx);
- if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET ||
- xpath_obj->nodesetval == NULL)
- goto cont;
+ xmlNodeSetPtr xml_interfaces = xpath_obj->nodesetval;
- xmlNodeSetPtr xml_interfaces = xpath_obj->nodesetval;
+ for (int j = 0; j < xml_interfaces->nodeNr; ++j) {
+ char *path = NULL;
+ char *address = NULL;
+ xmlNodePtr xml_interface;
- for (int j = 0; j < xml_interfaces->nodeNr; ++j) {
- char *path = NULL;
- char *address = NULL;
- xmlNodePtr xml_interface;
+ xml_interface = xml_interfaces->nodeTab[j];
+ if (!xml_interface)
+ continue;
- xml_interface = xml_interfaces->nodeTab[j];
- if (!xml_interface)
+ for (xmlNodePtr child = xml_interface->children; child;
+ child = child->next) {
+ if (child->type != XML_ELEMENT_NODE)
continue;
- for (xmlNodePtr child = xml_interface->children; child;
- child = child->next) {
- if (child->type != XML_ELEMENT_NODE)
+ if (xmlStrEqual(child->name, (const xmlChar *)"target")) {
+ path = (char *)xmlGetProp(child, (const xmlChar *)"dev");
+ if (!path)
+ continue;
+ } else if (xmlStrEqual(child->name, (const xmlChar *)"mac")) {
+ address = (char *)xmlGetProp(child, (const xmlChar *)"address");
+ if (!address)
continue;
-
- if (xmlStrEqual(child->name, (const xmlChar *)"target")) {
- path = (char *)xmlGetProp(child, (const xmlChar *)"dev");
- if (!path)
- continue;
- } else if (xmlStrEqual(child->name, (const xmlChar *)"mac")) {
- address = (char *)xmlGetProp(child, (const xmlChar *)"address");
- if (!address)
- continue;
- }
}
-
- if (il_interface_devices &&
- (ignore_device_match(il_interface_devices, name, path) != 0 ||
- ignore_device_match(il_interface_devices, name, address) != 0))
- goto cont3;
-
- add_interface_device(state, dom, path, address, j + 1);
- cont3:
- if (path)
- xmlFree(path);
- if (address)
- xmlFree(address);
}
- cont:
- if (xpath_obj)
- xmlXPathFreeObject(xpath_obj);
- if (xpath_ctx)
- xmlXPathFreeContext(xpath_ctx);
- if (xml_doc)
- xmlFreeDoc(xml_doc);
- sfree(xml);
+ if (il_interface_devices &&
+ (ignore_device_match(il_interface_devices, name, path) != 0 ||
+ ignore_device_match(il_interface_devices, name, address) != 0))
+ goto cont3;
+
+ add_interface_device(state, dom, path, address, j + 1);
+ cont3:
+ if (path)
+ xmlFree(path);
+ if (address)
+ xmlFree(address);
}
+ cont:
+ if (xpath_obj)
+ xmlXPathFreeObject(xpath_obj);
+ if (xpath_ctx)
+ xmlXPathFreeContext(xpath_ctx);
+ if (xml_doc)
+ xmlFreeDoc(xml_doc);
+ sfree(xml);
+ }
+
#ifdef HAVE_LIST_ALL_DOMAINS
- sfree(domains);
+ /* NOTE: domains_active and domains_inactive data will be cleared during
+ refresh of all domains (inside lv_clean_read_state function) so we need
+ to free here only allocated arrays */
+ sfree(domains);
+ sfree(domains_inactive);
#else
- sfree(domids);
+ sfree(domids);
+
+end:
#endif
- }
DEBUG(PLUGIN_NAME " plugin#%s: refreshing"
" domains=%i block_devices=%i iface_devices=%i",
state->nr_domains = 0;
}
-static int add_domain(struct lv_read_state *state, virDomainPtr dom) {
+static int add_domain(struct lv_read_state *state, virDomainPtr dom,
+ bool active) {
domain_t *new_ptr;
int new_size = sizeof(state->domains[0]) * (state->nr_domains + 1);
state->domains = new_ptr;
state->domains[state->nr_domains].ptr = dom;
+ state->domains[state->nr_domains].active = active;
memset(&state->domains[state->nr_domains].info, 0,
sizeof(state->domains[state->nr_domains].info));
struct interface_device *new_ptr;
int new_size =
sizeof(state->interface_devices[0]) * (state->nr_interface_devices + 1);
- char *path_copy, *address_copy, number_string[15];
+ char *path_copy, *address_copy, number_string[21];
if ((path == NULL) || (address == NULL))
return EINVAL;
static int ignore_device_match(ignorelist_t *il, const char *domname,
const char *devpath) {
char *name;
- int n, r;
+ int r;
if ((domname == NULL) || (devpath == NULL))
return 0;
- n = strlen(domname) + strlen(devpath) + 2;
+ size_t n = strlen(domname) + strlen(devpath) + 2;
name = malloc(n);
if (name == NULL) {
ERROR(PLUGIN_NAME " plugin: malloc failed.");
lv_fini_instance(i);
}
+ DEBUG(PLUGIN_NAME " plugin: stopping event loop");
+
+ if (!persistent_notification)
+ stop_event_loop(¬if_thread);
+
lv_disconnect();
ignorelist_free(il_domains);
fh = fopen(ZOL_ARCSTATS_FILE, "r");
if (fh == NULL) {
- char errbuf[1024];
ERROR("zfs_arc plugin: Opening \"%s\" failed: %s", ZOL_ARCSTATS_FILE,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ STRERRNO);
return -1;
}
return -1;
}
+ // Ignore the first two lines because they contain information about
+ // the rest of the file.
+ // See kstat_seq_show_headers module/spl/spl-kstat.c of the spl kernel
+ // module.
+ if (fgets(buffer, sizeof(buffer), fh) == NULL) {
+ ERROR("zfs_arc plugin: \"%s\" does not contain a single line.",
+ ZOL_ARCSTATS_FILE);
+ fclose(fh);
+ return (-1);
+ }
+ if (fgets(buffer, sizeof(buffer), fh) == NULL) {
+ ERROR("zfs_arc plugin: \"%s\" does not contain at least two lines.",
+ ZOL_ARCSTATS_FILE);
+ fclose(fh);
+ return (-1);
+ }
+
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
char *fields[3];
value_t v;