Merge remote-tracking branch 'github/pr/1366'
authorFlorian Forster <octo@collectd.org>
Sat, 28 Nov 2015 06:56:14 +0000 (07:56 +0100)
committerFlorian Forster <octo@collectd.org>
Sat, 28 Nov 2015 06:56:14 +0000 (07:56 +0100)
42 files changed:
bindings/perl/lib/Collectd/Unixsock.pm
configure.ac
contrib/systemd.collectd.service
src/Makefile.am
src/apache.c
src/apcups.c
src/collectd-exec.pod
src/collectd-tg.c
src/collectd.conf.in
src/collectd.conf.pod
src/daemon/Makefile.am
src/daemon/collectd.c
src/daemon/common.c
src/daemon/common_test.c
src/daemon/meta_data.c
src/daemon/plugin.c
src/daemon/utils_avltree.c
src/daemon/utils_avltree_test.c
src/daemon/utils_ignorelist.c [new file with mode: 0644]
src/daemon/utils_ignorelist.h [new file with mode: 0644]
src/daemon/utils_subst_test.c
src/daemon/utils_time.h
src/dbi.c
src/libcollectdclient/Makefile.am
src/log_logstash.c
src/memory.c
src/mqtt.c
src/processes.c
src/python.c
src/snmp.c
src/statsd.c
src/table.c
src/types.db
src/utils_ignorelist.c [deleted file]
src/utils_ignorelist.h [deleted file]
src/utils_mount.c
src/utils_mount_test.c
src/utils_vl_lookup.c
src/virt.c
src/write_http.c
src/write_redis.c
src/zfs_arc.c

index 69c755b..d927d13 100644 (file)
@@ -262,10 +262,11 @@ sub getthreshold # {{{
     $self->_socket_chat($msg, sub {
             local $_ = shift;
             my $ret = shift;
-                   /^\s*([^:]+):\s*(.*)/ and do {
-                           $1 =~ s/\s*$//;
-                           $ret->{$1} = $2;
-                   };
+            my ( $key, $val );
+            ( $key, $val ) = /^\s*([^:]+):\s*(.*)/ and do {
+                  $key =~ s/\s*$//;
+                  $ret->{$key} = $val;
+            };
         }, $ret
     );
        return $ret;
index 6f65df1..606c4ef 100644 (file)
@@ -1254,6 +1254,8 @@ have_getvfsstat="no"
 AC_CHECK_FUNCS(getvfsstat, [have_getvfsstat="yes"])
 have_listmntent="no"
 AC_CHECK_FUNCS(listmntent, [have_listmntent="yes"])
+have_getmntent_r="no"
+AC_CHECK_FUNCS(getmntent_r, [have_getmntent_r="yes"])
 
 have_getmntent="no"
 AC_CHECK_FUNCS(getmntent, [have_getmntent="c"])
@@ -1925,30 +1927,33 @@ AC_ARG_WITH(libganglia, [AS_HELP_STRING([--with-libganglia@<:@=PREFIX@:>@], [Pat
         GANGLIA_LDFLAGS="-L$withval/lib"
         with_libganglia="yes"
  else
-        with_libganglia_config="ganglia-config"
         with_libganglia="$withval"
  fi; fi; fi
 ],
 [
- with_libganglia_config="ganglia-config"
  with_libganglia="yes"
 ])
 
-if test "x$with_libganglia" = "xyes" && test "x$with_libganglia_config" != "x"
+if test "x$with_libganglia" = "xyes"
 then
-       if test "x$GANGLIA_CPPFLAGS" = "x"
+       if test "x$with_libganglia_config" != "x"
        then
-               GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null`
-       fi
+               if test "x$GANGLIA_CPPFLAGS" = "x"
+               then
+                       GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null`
+               fi
 
-       if test "x$GANGLIA_LDFLAGS" = "x"
-       then
-               GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null`
-       fi
+               if test "x$GANGLIA_LDFLAGS" = "x"
+               then
+                       GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null`
+               fi
 
-       if test "x$GANGLIA_LIBS" = "x"
-       then
-               GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null`
+               if test "x$GANGLIA_LIBS" = "x"
+               then
+                       GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null`
+               fi
+       else
+               GANGLIA_LIBS="-lganglia"
        fi
 fi
 
@@ -2738,7 +2743,7 @@ AC_ARG_WITH(libmysql, [AS_HELP_STRING([--with-libmysql@<:@=PREFIX@:>@], [Path to
 ])
 if test "x$with_libmysql" = "xyes"
 then
-       with_mysql_cflags=`$with_mysql_config --cflags 2>/dev/null`
+       with_mysql_cflags=`$with_mysql_config --include 2>/dev/null`
        mysql_config_status=$?
 
        if test $mysql_config_status -ne 0
@@ -2774,15 +2779,17 @@ then
        then
                with_libmysql="no ($with_mysql_config failed)"
        else
-               AC_CHECK_LIB(mysqlclient, mysql_init,
-                [with_libmysql="yes"],
-                [with_libmysql="no (symbol 'mysql_init' not found)"],
-                [$with_mysql_libs])
-
-               AC_CHECK_LIB(mysqlclient, mysql_get_server_version,
+               SAVE_CPPFLAGS="$CPPFLAGS"
+               CPPFLAGS="$CPPFLAGS $with_mysql_cflags"
+               SAVE_LIBS="$LIBS"
+               LIBS="$with_mysql_libs"
+               AC_SEARCH_LIBS([mysql_get_server_version],
+                [],
                 [with_libmysql="yes"],
                 [with_libmysql="no (symbol 'mysql_get_server_version' not found)"],
-                [$with_mysql_libs])
+                [])
+               CPPFLAGS="$SAVE_CPPFLAGS"
+               LIBS="$SAVE_LIBS"
        fi
 fi
 if test "x$with_libmysql" = "xyes"
@@ -5246,6 +5253,7 @@ collectd features:])
 AC_COLLECTD([debug],     [enable],  [feature], [debugging])
 AC_COLLECTD([daemon],    [disable], [feature], [daemon mode])
 AC_COLLECTD([getifaddrs],[enable],  [feature], [getifaddrs under Linux])
+AC_COLLECTD([werror],    [disable], [feature], [building with -Werror])
 
 dependency_warning="no"
 dependency_error="no"
@@ -5509,6 +5517,11 @@ then
        plugin_df="yes"
 fi
 
+if test "x$c_cv_have_getmntent_r" = "xyes"
+then
+       plugin_df="yes"
+fi
+
 # Df plugin: Check if we have either `statfs' or `statvfs' second.
 if test "x$plugin_df" = "xyes"
 then
@@ -5915,6 +5928,13 @@ AC_SUBST(LCC_VERSION_STRING)
 
 AC_CONFIG_FILES(src/libcollectdclient/collectd/lcc_features.h)
 
+AM_CFLAGS="-Wall"
+if test "x$enable_werror" != "xno"
+then
+        AM_CFLAGS="$AM_CFLAGS -Werror"
+fi
+AC_SUBST([AM_CFLAGS])
+
 AC_CONFIG_FILES([Makefile src/Makefile src/daemon/Makefile src/collectd.conf src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile])
 AC_OUTPUT
 
@@ -5945,6 +5965,17 @@ fi
 cat <<EOF;
 
 Configuration:
+  Build:
+    Platform  . . . . . . $ac_system
+    CC  . . . . . . . . . $CC
+    CFLAGS  . . . . . . . $AM_CFLAGS $CFLAGS
+    CPP . . . . . . . . . $CPP
+    CPPFLAGS  . . . . . . $CPPFLAGS
+    LD  . . . . . . . . . $LD
+    LDFLAGS . . . . . . . $LDFLAGS
+    YACC  . . . . . . . . $YACC
+    YFLAGS  . . . . . . . $YFLAGS
+
   Libraries:
     intel mic . . . . . . $with_mic
     libaquaero5 . . . . . $with_libaquaero5
index 96df8a5..0e758e4 100644 (file)
@@ -7,19 +7,24 @@ Requires=local-fs.target network.target
 ExecStart=/usr/sbin/collectd
 EnvironmentFile=-/etc/sysconfig/collectd
 EnvironmentFile=-/etc/default/collectd
+ProtectSystem=full
+ProtectHome=true
+
+# drop all capabilities:
+CapabilityBoundingSet=
+# use this instead if you use the dns or ping plugin
+#CapabilityBoundingSet=CAP_NET_RAW
+# turn this on if you use the iptables next to the dns or ping plugin
+#CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN
+
+NoNewPrivileges=true
 
 # Tell systemd it will receive a notification from collectd over it's control
 # socket once the daemon is ready. See systemd.service(5) for more details.
 Type=notify
-NotifyAccess=main
 
 # Restart the collectd daemon after a 10 seconds delay, in case it crashes.
-Restart=always
-RestartSec=10
-
-# Send all console messages to syslog.
-StandardOutput=syslog
-StandardError=syslog
+Restart=on-failure
 
 [Install]
 WantedBy=multi-user.target
index 9493c24..199adcf 100644 (file)
@@ -6,10 +6,6 @@ SUBDIRS += daemon
 
 PLUGIN_LDFLAGS = -module -avoid-version -export-symbols-regex '\<module_register\>'
 
-if COMPILER_IS_GCC
-AM_CFLAGS = -Wall -Werror
-endif
-
 AM_CPPFLAGS = -I$(srcdir)/daemon
 AM_CPPFLAGS += -DPREFIX='"${prefix}"'
 AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"'
@@ -41,6 +37,9 @@ check_PROGRAMS += test_utils_vl_lookup
 TESTS += test_utils_vl_lookup
 test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h
 test_utils_vl_lookup_LDADD = liblookup.la daemon/libcommon.la daemon/libplugin_mock.la
+if BUILD_WITH_LIBKSTAT
+test_utils_vl_lookup_LDADD += -lkstat
+endif
 
 noinst_LTLIBRARIES += libmount.la
 libmount_la_SOURCES = utils_mount.c utils_mount.h
@@ -48,7 +47,9 @@ check_PROGRAMS += test_utils_mount
 TESTS += test_utils_mount
 test_utils_mount_SOURCES = utils_mount_test.c testing.h
 test_utils_mount_LDADD = libmount.la daemon/libcommon.la daemon/libplugin_mock.la
-
+if BUILD_WITH_LIBKSTAT
+test_utils_mount_LDADD += -lkstat
+endif
 
 sbin_PROGRAMS = collectdmon
 bin_PROGRAMS = collectd-nagios collectdctl collectd-tg
@@ -210,8 +211,7 @@ endif
 
 if BUILD_PLUGIN_CGROUPS
 pkglib_LTLIBRARIES += cgroups.la
-cgroups_la_SOURCES = cgroups.c \
-                    utils_ignorelist.c utils_ignorelist.h
+cgroups_la_SOURCES = cgroups.c
 cgroups_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 cgroups_la_LIBADD = libmount.la
 endif
@@ -310,16 +310,14 @@ endif
 
 if BUILD_PLUGIN_DF
 pkglib_LTLIBRARIES += df.la
-df_la_SOURCES = df.c \
-               utils_ignorelist.c utils_ignorelist.h
+df_la_SOURCES = df.c
 df_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 df_la_LIBADD = libmount.la
 endif
 
 if BUILD_PLUGIN_DISK
 pkglib_LTLIBRARIES += disk.la
-disk_la_SOURCES = disk.c \
-                 utils_ignorelist.c utils_ignorelist.h
+disk_la_SOURCES = disk.c
 disk_la_CFLAGS = $(AM_CFLAGS)
 disk_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 disk_la_LIBADD =
@@ -422,8 +420,7 @@ endif
 
 if BUILD_PLUGIN_INTERFACE
 pkglib_LTLIBRARIES += interface.la
-interface_la_SOURCES = interface.c \
-                      utils_ignorelist.c utils_ignorelist.h
+interface_la_SOURCES = interface.c
 interface_la_CFLAGS = $(AM_CFLAGS)
 interface_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 interface_la_LIBADD =
@@ -460,8 +457,7 @@ endif
 
 if BUILD_PLUGIN_IPMI
 pkglib_LTLIBRARIES += ipmi.la
-ipmi_la_SOURCES = ipmi.c \
-                 utils_ignorelist.c utils_ignorelist.h
+ipmi_la_SOURCES = ipmi.c
 ipmi_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_OPENIPMI_CFLAGS)
 ipmi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 ipmi_la_LIBADD = $(BUILD_WITH_OPENIPMI_LIBS)
@@ -480,8 +476,7 @@ endif
 
 if BUILD_PLUGIN_IRQ
 pkglib_LTLIBRARIES += irq.la
-irq_la_SOURCES = irq.c \
-                utils_ignorelist.c utils_ignorelist.h
+irq_la_SOURCES = irq.c
 irq_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
@@ -540,8 +535,7 @@ endif
 
 if BUILD_PLUGIN_MADWIFI
 pkglib_LTLIBRARIES += madwifi.la
-madwifi_la_SOURCES = madwifi.c madwifi.h \
-                    utils_ignorelist.c utils_ignorelist.h
+madwifi_la_SOURCES = madwifi.c madwifi.h
 madwifi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
@@ -587,8 +581,7 @@ endif
 
 if BUILD_PLUGIN_MD
 pkglib_LTLIBRARIES += md.la
-md_la_SOURCES = md.c \
-               utils_ignorelist.c utils_ignorelist.h
+md_la_SOURCES = md.c
 md_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
@@ -633,8 +626,7 @@ endif
 
 if BUILD_PLUGIN_MIC
 pkglib_LTLIBRARIES += mic.la
-mic_la_SOURCES = mic.c \
-                utils_ignorelist.c utils_ignorelist.h
+mic_la_SOURCES = mic.c
 mic_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_MIC_LIBPATH)
 mic_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_MIC_CPPFLAGS)
 mic_la_LIBADD = $(BUILD_WITH_MIC_LDADD)
@@ -676,8 +668,7 @@ endif
 
 if BUILD_PLUGIN_NETAPP
 pkglib_LTLIBRARIES += netapp.la
-netapp_la_SOURCES = netapp.c \
-                   utils_ignorelist.c utils_ignorelist.h
+netapp_la_SOURCES = netapp.c
 netapp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBNETAPP_CPPFLAGS)
 netapp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBNETAPP_LDFLAGS)
 netapp_la_LIBADD = $(LIBNETAPP_LIBS)
@@ -783,8 +774,7 @@ endif
 
 if BUILD_PLUGIN_ONEWIRE
 pkglib_LTLIBRARIES += onewire.la
-onewire_la_SOURCES = onewire.c \
-                    utils_ignorelist.c utils_ignorelist.h
+onewire_la_SOURCES = onewire.c
 onewire_la_CFLAGS = $(AM_CFLAGS)
 onewire_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOWCAPI_CPPFLAGS)
 onewire_la_LIBADD = $(BUILD_WITH_LIBOWCAPI_LIBS)
@@ -897,8 +887,7 @@ endif
 
 if BUILD_PLUGIN_PROTOCOLS
 pkglib_LTLIBRARIES += protocols.la
-protocols_la_SOURCES = protocols.c \
-                      utils_ignorelist.c utils_ignorelist.h
+protocols_la_SOURCES = protocols.c
 protocols_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
@@ -936,8 +925,7 @@ endif
 
 if BUILD_PLUGIN_SENSORS
 pkglib_LTLIBRARIES += sensors.la
-sensors_la_SOURCES = sensors.c \
-                    utils_ignorelist.c utils_ignorelist.h
+sensors_la_SOURCES = sensors.c
 sensors_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSENSORS_CFLAGS)
 sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBSENSORS_LDFLAGS)
 sensors_la_LIBADD = -lsensors
@@ -960,8 +948,7 @@ endif
 if BUILD_PLUGIN_SMART
 if BUILD_WITH_LIBUDEV
 pkglib_LTLIBRARIES += smart.la
-smart_la_SOURCES = smart.c \
-                  utils_ignorelist.c utils_ignorelist.h
+smart_la_SOURCES = smart.c
 smart_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBATASMART_CPPFLAGS)
 smart_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBATASMART_LDFLAGS)
 smart_la_LIBADD = $(BUILD_WITH_LIBATASMART_LIBS) -ludev
@@ -1100,8 +1087,7 @@ endif
 
 if BUILD_PLUGIN_THERMAL
 pkglib_LTLIBRARIES += thermal.la
-thermal_la_SOURCES = thermal.c \
-                    utils_ignorelist.c utils_ignorelist.h
+thermal_la_SOURCES = thermal.c
 thermal_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
@@ -1186,8 +1172,7 @@ endif
 
 if BUILD_PLUGIN_VIRT
 pkglib_LTLIBRARIES += virt.la
-virt_la_SOURCES = virt.c \
-                 utils_ignorelist.c utils_ignorelist.h
+virt_la_SOURCES = virt.c
 virt_la_CFLAGS = $(AM_CFLAGS) \
                $(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
 virt_la_LIBADD = $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
index 41b807a..b306032 100644 (file)
@@ -519,12 +519,9 @@ static void submit_scoreboard (char *buf, apache_t *st)
 
 static int apache_read_host (user_data_t *user_data) /* {{{ */
 {
-       int i;
-
        char *ptr;
        char *saveptr;
-       char *lines[16];
-       int   lines_num = 0;
+       char *line;
 
        char *fields[4];
        int   fields_num;
@@ -564,29 +561,17 @@ static int apache_read_host (user_data_t *user_data) /* {{{ */
 
        ptr = st->apache_buffer;
        saveptr = NULL;
-       while ((lines[lines_num] = strtok_r (ptr, "\n\r", &saveptr)) != NULL)
+       while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL)
        {
                ptr = NULL;
-               lines_num++;
-
-               if (lines_num >= 16)
-                       break;
-       }
-
-       for (i = 0; i < lines_num; i++)
-       {
-               fields_num = strsplit (lines[i], fields, 4);
+               fields_num = strsplit (line, fields, STATIC_ARRAY_SIZE (fields));
 
                if (fields_num == 3)
                {
-                       if ((strcmp (fields[0], "Total") == 0)
-                                       && (strcmp (fields[1], "Accesses:") == 0))
-                               submit_derive ("apache_requests", "",
-                                               atoll (fields[2]), st);
-                       else if ((strcmp (fields[0], "Total") == 0)
-                                       && (strcmp (fields[1], "kBytes:") == 0))
-                               submit_derive ("apache_bytes", "",
-                                               1024LL * atoll (fields[2]), st);
+                       if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "Accesses:") == 0))
+                               submit_derive ("apache_requests", "", atoll (fields[2]), st);
+                       else if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "kBytes:") == 0))
+                               submit_derive ("apache_bytes", "", 1024LL * atoll (fields[2]), st);
                }
                else if (fields_num == 2)
                {
index 718061a..29d58c3 100644 (file)
@@ -125,7 +125,7 @@ static int net_open (char const *node, char const *service)
        if (status != 0)
        {
                char errbuf[1024];
-               INFO ("getaddrinfo failed: %s",
+               INFO ("apcups plugin: getaddrinfo failed: %s",
                                (status == EAI_SYSTEM)
                                ? sstrerror (errno, errbuf, sizeof (errbuf))
                                : gai_strerror (status));
@@ -144,7 +144,7 @@ static int net_open (char const *node, char const *service)
 
        if (sd < 0)
        {
-               DEBUG ("Unable to open a socket");
+               DEBUG ("apcups plugin: Unable to open a socket");
                freeaddrinfo (ai_return);
                return (-1);
        }
@@ -156,13 +156,13 @@ static int net_open (char const *node, char const *service)
        if (status != 0) /* `connect(2)' failed */
        {
                char errbuf[1024];
-               INFO ("connect failed: %s",
+               INFO ("apcups plugin: connect failed: %s",
                                sstrerror (errno, errbuf, sizeof (errbuf)));
                close (sd);
                return (-1);
        }
 
-       DEBUG ("Done opening a socket %i", sd);
+       DEBUG ("apcups plugin: Done opening a socket %i", sd);
 
        return (sd);
 } /* int net_open */
@@ -455,7 +455,7 @@ static int apcups_read (void)
         */
        if (status != 0)
        {
-               DEBUG ("apc_query_server (%s, %s) = %i",
+               DEBUG ("apcups plugin: apc_query_server (%s, %s) = %i",
                                (conf_node == NULL) ? APCUPS_DEFAULT_NODE : conf_node,
                                (conf_service == NULL) ? APCUPS_DEFAULT_SERVICE : conf_service,
                                status);
index 10f9f61..0e4cd53 100644 (file)
@@ -17,7 +17,7 @@ collectd-exec - Documentation of collectd's C<exec plugin>
 
 =head1 DESCRIPTION
 
-The C<exec plugin> forks of an executable either to receive values or to
+The C<exec plugin> forks off an executable either to receive values or to
 dispatch notifications to the outside world. The syntax of the configuration is
 explained in L<collectd.conf(5)> but summarized in the above synopsis.
 
@@ -42,7 +42,7 @@ time and continuously write values to C<STDOUT>.
 See L<EXEC DATA FORMAT> below for a description of the output format expected
 from these programs.
 
-B<Warning:> If the executable only writes one value and then exits I will be
+B<Warning:> If the executable only writes one value and then exits it will be
 executed every I<Interval> seconds. If I<Interval> is short (the default is 10
 seconds) this may result in serious system load.
 
index 05cf9a7..9bd65bc 100644 (file)
@@ -40,6 +40,7 @@
 #include <signal.h>
 #include <errno.h>
 #include <math.h>
+#include <sys/time.h>
 
 #include "utils_heap.h"
 
index 1f4ccf8..30d536a 100644 (file)
 
 #<Plugin "battery">
 #  ValuesPercentage false
-#  ReportDegraded
+#  ReportDegraded false
 #</Plugin>
 
 #<Plugin "bind">
 #              Prefix "collectd"
 #              StoreRates true
 #              Retain false
+#              CACert "/etc/ssl/ca.crt"
+#              CertificateFile "/etc/ssl/client.crt"
+#              CertificateKeyFile "/etc/ssl/client.pem"
+#              TLSProtocol "tlsv1.2"
+#              CipherSuite "ciphers"
 #      </Publish>
 #      <Subscribe "name">
 #              Host "localhost"
index aaeeaf4..78a130c 100644 (file)
@@ -1827,6 +1827,7 @@ than those of other plugins. It usually looks something like this:
     </Query>
     <Database "product_information">
       Driver "mysql"
+      Interval 120
       DriverOption "host" "localhost"
       DriverOption "username" "collectd"
       DriverOption "password" "aZo6daiw"
@@ -2006,6 +2007,11 @@ the daemon. Other than that, that name is not used.
 
 =over 4
 
+=item B<Interval> I<Interval>
+
+Sets the interval (in seconds) in which the values will be collected from this
+database. By default the global B<Interval> setting will be used.
+
 =item B<Driver> I<Driver>
 
 Specifies the driver to use to connect to the database. In many cases those
@@ -3341,6 +3347,38 @@ Configures the topic(s) to subscribe to. You can use the single level C<+> and
 multi level C<#> wildcards. Defaults to B<collectd/#>, i.e. all topics beneath
 the B<collectd> branch.
 
+=item B<CACert> I<file>
+
+Path to the PEM-encoded CA certificate file. Setting this option enables TLS
+communication with the MQTT broker, and as such, B<Port> should be the TLS-enabled
+port of the MQTT broker.
+A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+
+=item B<CertificateFile> I<file>
+
+Path to the PEM-encoded certificate file to use as client certificate when
+connecting to the MQTT broker.
+A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+
+=item B<CertificateKeyFile> I<file>
+
+Path to the unencrypted PEM-encoded key file corresponding to B<CertificateFile>.
+A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+
+=item B<TLSProtocol> I<protocol>
+
+If configured, this specifies the string protocol version (e.g. C<tlsv1>,
+C<tlsv1.2>) to use for the TLS connection to the broker. If not set a default
+version is used which depends on the version of OpenSSL the Mosquitto library
+was linked against.
+
+=item B<CipherSuite> I<ciphersuite>
+
+A string describing the ciphers available for use. See L<ciphers(1)> and the
+C<openssl ciphers> utility for more information. If unset, the default ciphers
+will be used.
+
+
 =back
 
 =head2 Plugin C<mysql>
@@ -7133,14 +7171,18 @@ setting B<name>.
 B<address> means use the interface's mac address. This is useful since the
 interface path might change between reboots of a guest or across migrations.
 
-=item B<PluginInstanceFormat> B<name|uuid>
+=item B<PluginInstanceFormat> B<name|uuid|none>
 
 When the virt plugin logs data, it sets the plugin_instance of the collected
-data according to this setting. The default is to use the guest name as provided
-by the hypervisor, which is equal to setting B<name>.
+data according to this setting. The default is to not set the plugin_instance.
 
+B<name> means use the guest's name as provided by the hypervisor.
 B<uuid> means use the guest's UUID.
 
+You can also specify combinations of the B<name> and B<uuid> fields.
+For example B<name uuid> means to concatenate the guest name and UUID
+(with a literal colon character between, thus I<"foo:1234-1234-1234-1234">).
+
 =back
 
 =head2 Plugin C<vmem>
@@ -7482,6 +7524,10 @@ complete. When this limit is reached, the POST operation will be aborted, and
 all the data in the current send buffer will probably be lost. Defaults to 0,
 which means the connection never times out.
 
+=item B<LogHttpError> B<false>|B<true>
+
+Enables printing of HTTP error code to log. Turned off by default.
+
 The C<write_http> plugin regularly submits the collected values to the HTTP
 server. How frequently this happens depends on how much data you are collecting
 and the size of B<BufferSize>. The optimal value to set B<Timeout> to is
@@ -7610,6 +7656,8 @@ Synopsis:
         Timeout 1000
         Prefix "collectd/"
         Database 1
+        MaxSetSize -1
+        StoreRates true
     </Node>
   </Plugin>
 
@@ -7618,7 +7666,7 @@ the timestamp as the score. Retrieving a date range can then be done using the
 C<ZRANGEBYSCORE> I<Redis> command. Additionally, all the identifiers of these
 I<Sorted Sets> are kept in a I<Set> called C<collectd/values> (or
 C<${prefix}/values> if the B<Prefix> option was specified) and can be retrieved
-using the C<SMEMBERS> I<Redis> command. You can specify the database to use 
+using the C<SMEMBERS> I<Redis> command. You can specify the database to use
 with the B<Database> parameter (default is C<0>). See
 L<http://redis.io/commands#sorted_set> and L<http://redis.io/commands#set> for
 details.
@@ -7663,7 +7711,18 @@ is recommended but not required to include a trailing slash in I<Prefix>.
 
 =item B<Database> I<Index>
 
-This index selects the redis database to use for writing operations. Defaults to C<0>.
+This index selects the redis database to use for writing operations. Defaults
+to C<0>.
+
+=item B<MaxSetSize> I<Items>
+
+The B<MaxSetSize> option limits the number of items that the I<Sorted Sets> can
+hold. Negative values for I<Items> sets no limit, which is the default behavior.
+
+=item B<StoreRates> B<true>|B<false>
+
+If set to B<true> (the default), convert counter values to rates. If set to
+B<false> counter values are stored as is, i.e. as an increasing integer number.
 
 =back
 
@@ -7744,7 +7803,7 @@ C<ds_type:derive:rate>.
 
 =item B<AlwaysAppendDS> B<false>|B<true>
 
-If set the B<true>, append the name of the I<Data Source> (DS) to the
+If set to B<true>, append the name of the I<Data Source> (DS) to the
 "service", i.e. the field that, together with the "host" field, uniquely
 identifies a metric in I<Riemann>. If set to B<false> (the default), this is
 only done when there is more than one DS.
index cd53a7b..3d50029 100644 (file)
@@ -1,7 +1,3 @@
-if COMPILER_IS_GCC
-AM_CFLAGS = -Wall -Werror
-endif
-
 AM_CPPFLAGS = -I$(top_srcdir)/src
 AM_CPPFLAGS += -DPREFIX='"${prefix}"'
 AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"'
@@ -62,6 +58,7 @@ collectd_SOURCES = collectd.c collectd.h \
                   plugin.c plugin.h \
                   utils_cache.c utils_cache.h \
                   utils_complain.c utils_complain.h \
+                  utils_ignorelist.c utils_ignorelist.h \
                   utils_llist.c utils_llist.h \
                   utils_random.c utils_random.h \
                   utils_tail_match.c utils_tail_match.h \
index 58325b9..fc52933 100644 (file)
@@ -459,7 +459,11 @@ int notify_systemd (void)
 
     unsetenv ("NOTIFY_SOCKET");
 
+#if defined(SOCK_CLOEXEC)
+    fd = socket (AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, /* protocol = */ 0);
+#else
     fd = socket (AF_UNIX, SOCK_DGRAM, /* protocol = */ 0);
+#endif
     if (fd < 0) {
         char errbuf[1024];
         ERROR ("creating UNIX socket failed: %s",
@@ -477,7 +481,6 @@ int notify_systemd (void)
     }
     else
     {
-#if KERNEL_LINUX
         /* Linux abstract namespace socket: specify address as "\0foo", i.e.
          * start with a null byte. Since null bytes have no special meaning in
          * that case, we have to set su_size correctly to cover only the bytes
@@ -487,11 +490,6 @@ int notify_systemd (void)
         su_size = sizeof (sa_family_t) + strlen (notifysocket);
         if (su_size > sizeof (su))
             su_size = sizeof (su);
-#else
-       ERROR ("Systemd socket uses Linux abstract namespace notation (\"%s\"), "
-                       "but I don't appear to be running on Linux.", notifysocket);
-       return 0;
-#endif
     }
 
     if (sendto (fd, buffer, strlen (buffer), MSG_NOSIGNAL, (void *) &su, (socklen_t) su_size) < 0)
@@ -503,6 +501,7 @@ int notify_systemd (void)
         return 0;
     }
 
+    unsetenv ("NOTIFY_SOCKET");
     close(fd);
     return 1;
 }
index 8f22011..dfaa61a 100644 (file)
@@ -48,6 +48,8 @@
 #include <sys/types.h>
 #include <netdb.h>
 
+#include <poll.h>
+
 #if HAVE_NETINET_IN_H
 # include <netinet/in.h>
 #endif
@@ -269,9 +271,23 @@ ssize_t swrite (int fd, const void *buf, size_t count)
        const char *ptr;
        size_t      nleft;
        ssize_t     status;
+       struct      pollfd pfd;
 
        ptr   = (const char *) buf;
        nleft = count;
+       
+       /* checking for closed peer connection */
+       pfd.fd = fd;
+       pfd.events = POLLIN | POLLHUP;
+       pfd.revents = 0;
+       if (poll(&pfd, 1, 0) > 0) {
+               char buffer[32];
+               if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) {
+                       // if recv returns zero (even though poll() said there is data to be read),
+                       // that means the connection has been closed
+                       return -1;
+               }
+       }
 
        while (nleft > 0)
        {
index 23c6f23..399f8b5 100644 (file)
 #include "testing.h"
 #include "common.h"
 
+#if HAVE_LIBKSTAT
+kstat_ctl_t *kc;
+#endif /* HAVE_LIBKSTAT */
+
 DEF_TEST(sstrncpy)
 {
   char buffer[16] = "";
index 6ee8446..4e46ed5 100644 (file)
@@ -255,7 +255,6 @@ void meta_data_destroy (meta_data_t *md) /* {{{ */
   if (md == NULL)
     return;
 
-  pthread_mutex_destroy(&md->lock);
   md_entry_free (md->head);
   pthread_mutex_destroy (&md->lock);
   free (md);
index be3f03f..831e3fb 100644 (file)
@@ -1089,6 +1089,7 @@ int plugin_load (char const *plugin_name, uint32_t flags)
                        /* success */
                        plugin_mark_loaded (plugin_name);
                        ret = 0;
+                       INFO ("plugin_load: plugin \"%s\" successfully loaded.", plugin_name);
                        break;
                }
                else
@@ -1724,8 +1725,6 @@ void plugin_init_all (void)
                write_threads_num = 5;
        }
 
-       start_write_threads ((size_t) write_threads_num);
-
        if ((list_init == NULL) && (read_heap == NULL))
                return;
 
@@ -1761,6 +1760,8 @@ void plugin_init_all (void)
                le = le->next;
        }
 
+       start_write_threads ((size_t) write_threads_num);
+
        max_read_interval = global_option_get_time ("MaxReadInterval",
                        DEFAULT_MAX_READ_INTERVAL);
 
index e251975..58b8b84 100644 (file)
@@ -652,6 +652,7 @@ int c_avl_pick (c_avl_tree_t *t, void **key, void **value)
        *value = n->value;
 
        free_node (n);
+       --t->size;
        rebalance (t, p);
 
        return (0);
index 2a8244c..6dbafe1 100644 (file)
@@ -27,6 +27,7 @@
 #include "testing.h"
 #include "collectd.h"
 #include "utils_avltree.h"
+#include "common.h" /* STATIC_ARRAY_SIZE */
 
 static int compare_total_count = 0;
 #define RESET_COUNTS() do { compare_total_count = 0; } while (0)
@@ -42,30 +43,99 @@ static int compare_callback (void const *v0, void const *v1)
 
 DEF_TEST(success)
 {
+  struct {
+    char *key;
+    char *value;
+  } cases[] = {
+    {"Eeph7chu", "vai1reiV"},
+    {"igh3Paiz", "teegh1Ee"},
+    {"caip6Uu8", "ooteQu8n"},
+    {"Aech6vah", "AijeeT0l"},
+    {"Xah0et2L", "gah8Taep"},
+    {"BocaeB8n", "oGaig8io"},
+    {"thai8AhM", "ohjeFo3f"},
+    {"ohth6ieC", "hoo8ieWo"},
+    {"aej7Woow", "phahuC2s"},
+    {"Hai8ier2", "Yie6eimi"},
+    {"phuXi3Li", "JaiF7ieb"},
+    {"Shaig5ef", "aihi5Zai"},
+    {"voh6Aith", "Oozaeto0"},
+    {"zaiP5kie", "seep5veM"},
+    {"pae7ba7D", "chie8Ojo"},
+    {"Gou2ril3", "ouVoo0ha"},
+    {"lo3Thee3", "ahDu4Zuj"},
+    {"Rah8kohv", "ieShoc7E"},
+    {"ieN5engi", "Aevou1ah"},
+    {"ooTe4OhP", "aingai5Y"},
+  };
+
   c_avl_tree_t *t;
-  char key_orig[] = "foo";
-  char value_orig[] = "bar";
-  char *key_ret = NULL;
-  char *value_ret = NULL;
+  size_t i;
 
   RESET_COUNTS ();
-  t = c_avl_create (compare_callback);
-  OK (t != NULL);
+  CHECK_NOT_NULL (t = c_avl_create (compare_callback));
+
+  /* insert */
+  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+  {
+    char *key;
+    char *value;
 
-  OK (c_avl_insert (t, key_orig, value_orig) == 0);
-  OK (c_avl_size (t) == 1);
+    CHECK_NOT_NULL (key = strdup (cases[i].key));
+    CHECK_NOT_NULL (value = strdup (cases[i].value));
+
+    CHECK_ZERO (c_avl_insert (t, key, value));
+    EXPECT_EQ_INT ((int) (i + 1), c_avl_size (t));
+  }
 
   /* Key already exists. */
-  OK (c_avl_insert (t, "foo", "qux") > 0);
+  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+    EXPECT_EQ_INT (1, c_avl_insert (t, cases[i].key, cases[i].value));
+
+  /* get */
+  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+  {
+    char *value_ret = NULL;
+
+    CHECK_ZERO (c_avl_get (t, cases[i].key, (void *) &value_ret));
+    EXPECT_EQ_STR (cases[i].value, value_ret);
+  }
+
+  /* remove half */
+  for (i = 0; i < STATIC_ARRAY_SIZE (cases) / 2; i++)
+  {
+    char *key = NULL;
+    char *value = NULL;
+
+    int expected_size = (int) (STATIC_ARRAY_SIZE (cases) - (i + 1));
+
+    CHECK_ZERO (c_avl_remove (t, cases[i].key, (void *) &key, (void *) &value));
+
+    EXPECT_EQ_STR (cases[i].key, key);
+    EXPECT_EQ_STR (cases[i].value, value);
+
+    free (key);
+    free (value);
+
+    EXPECT_EQ_INT (expected_size, c_avl_size (t));
+  }
+
+  /* pick the other half */
+  for (i = STATIC_ARRAY_SIZE (cases) / 2; i < STATIC_ARRAY_SIZE (cases); i++)
+  {
+    char *key = NULL;
+    char *value = NULL;
+
+    int expected_size = (int) (STATIC_ARRAY_SIZE (cases) - (i + 1));
+
+    EXPECT_EQ_INT (expected_size + 1, c_avl_size (t));
+    EXPECT_EQ_INT (0, c_avl_pick (t, (void *) &key, (void *) &value));
 
-  OK (c_avl_get (t, "foo", (void *) &value_ret) == 0);
-  OK (value_ret == &value_orig[0]);
+    free (key);
+    free (value);
 
-  key_ret = value_ret = NULL;
-  OK (c_avl_remove (t, "foo", (void *) &key_ret, (void *) &value_ret) == 0);
-  OK (key_ret == &key_orig[0]);
-  OK (value_ret == &value_orig[0]);
-  OK (c_avl_size (t) == 0);
+    EXPECT_EQ_INT (expected_size, c_avl_size (t));
+  }
 
   c_avl_destroy (t);
 
diff --git a/src/daemon/utils_ignorelist.c b/src/daemon/utils_ignorelist.c
new file mode 100644 (file)
index 0000000..a8ca7db
--- /dev/null
@@ -0,0 +1,338 @@
+/**
+ * collectd - src/utils_ignorelist.c
+ * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
+ * Copyright (C) 2008 Florian Forster <octo at collectd.org>
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Authors:
+ *   Lubos Stanek <lubek at users.sourceforge.net>
+ *   Florian Forster <octo at collectd.org>
+ **/
+/**
+ * ignorelist handles plugin's list of configured collectable
+ * entries with global ignore action
+ **/
+/**
+ * Usage:
+ * 
+ * Define plugin's global pointer variable of type ignorelist_t:
+ *   ignorelist_t *myconfig_ignore;
+ * If you know the state of the global ignore (IgnoreSelected),
+ * allocate the variable with:
+ *   myconfig_ignore = ignorelist_create (YourKnownIgnore);
+ * If you do not know the state of the global ignore,
+ * initialize the global variable and set the ignore flag later:
+ *   myconfig_ignore = ignorelist_init ();
+ * Append single entries in your cf_register'ed callback function:
+ *   ignorelist_add (myconfig_ignore, newentry);
+ * When you hit the IgnoreSelected config option,
+ * offer it to the list:
+ *   ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore);
+ * That is all for the ignorelist initialization.
+ * Later during read and write (plugin's registered functions) get
+ * the information whether this entry would be collected or not:
+ *   if (ignorelist_match (myconfig_ignore, thisentry))
+ *     return;
+ **/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "common.h"
+#include "plugin.h"
+#include "utils_ignorelist.h"
+
+/*
+ * private prototypes
+ */
+struct ignorelist_item_s
+{
+#if HAVE_REGEX_H
+       regex_t *rmatch;        /* regular expression entry identification */
+#endif
+       char *smatch;           /* string entry identification */
+       struct ignorelist_item_s *next;
+};
+typedef struct ignorelist_item_s ignorelist_item_t;
+
+struct ignorelist_s
+{
+       int ignore;             /* ignore entries */
+       ignorelist_item_t *head;        /* pointer to the first entry */
+};
+
+/* *** *** *** ********************************************* *** *** *** */
+/* *** *** *** *** *** ***   private functions   *** *** *** *** *** *** */
+/* *** *** *** ********************************************* *** *** *** */
+
+static inline void ignorelist_append (ignorelist_t *il, ignorelist_item_t *item)
+{
+       assert ((il != NULL) && (item != NULL));
+
+       item->next = il->head;
+       il->head = item;
+}
+
+#if HAVE_REGEX_H
+static int ignorelist_append_regex(ignorelist_t *il, const char *re_str)
+{
+       regex_t *re;
+       ignorelist_item_t *entry;
+       int status;
+
+       re = malloc (sizeof (*re));
+       if (re == NULL)
+       {
+               ERROR ("utils_ignorelist: malloc failed");
+               return (ENOMEM);
+       }
+       memset (re, 0, sizeof (*re));
+
+       status = regcomp (re, re_str, REG_EXTENDED);
+       if (status != 0)
+       {
+               char errbuf[1024] = "";
+               regerror (status, re, errbuf, sizeof (errbuf));
+               ERROR ("utils_ignorelist: regcomp failed: %s", errbuf);
+               regfree (re);
+               sfree (re);
+               return (status);
+       }
+
+       entry = malloc (sizeof (*entry));
+       if (entry == NULL)
+       {
+               ERROR ("utils_ignorelist: malloc failed");
+               regfree (re);
+               sfree (re);
+               return (ENOMEM);
+       }
+       memset (entry, 0, sizeof (*entry));
+       entry->rmatch = re;
+
+       ignorelist_append (il, entry);
+       return (0);
+} /* int ignorelist_append_regex */
+#endif
+
+static int ignorelist_append_string(ignorelist_t *il, const char *entry)
+{
+       ignorelist_item_t *new;
+
+       /* create new entry */
+       if ((new = malloc(sizeof(ignorelist_item_t))) == NULL )
+       {
+               ERROR ("cannot allocate new entry");
+               return (1);
+       }
+       memset (new, '\0', sizeof(ignorelist_item_t));
+       new->smatch = sstrdup(entry);
+
+       /* append new entry */
+       ignorelist_append (il, new);
+
+       return (0);
+} /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */
+
+#if HAVE_REGEX_H
+/*
+ * check list for entry regex match
+ * return 1 if found
+ */
+static int ignorelist_match_regex (ignorelist_item_t *item, const char *entry)
+{
+       assert ((item != NULL) && (item->rmatch != NULL)
+                       && (entry != NULL) && (strlen (entry) > 0));
+
+       /* match regex */
+       if (regexec (item->rmatch, entry, 0, NULL, 0) == 0)
+               return (1);
+
+       return (0);
+} /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */
+#endif
+
+/*
+ * check list for entry string match
+ * return 1 if found
+ */
+static int ignorelist_match_string (ignorelist_item_t *item, const char *entry)
+{
+       assert ((item != NULL) && (item->smatch != NULL)
+                       && (entry != NULL) && (strlen (entry) > 0));
+
+       if (strcmp (entry, item->smatch) == 0)
+               return (1);
+
+       return (0);
+} /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */
+
+
+/* *** *** *** ******************************************** *** *** *** */
+/* *** *** *** *** *** ***   public functions   *** *** *** *** *** *** */
+/* *** *** *** ******************************************** *** *** *** */
+
+/*
+ * create the ignorelist_t with known ignore state
+ * return pointer to ignorelist_t
+ */
+ignorelist_t *ignorelist_create (int invert)
+{
+       ignorelist_t *il;
+
+       /* smalloc exits if it failes */
+       il = (ignorelist_t *) smalloc (sizeof (ignorelist_t));
+       memset (il, '\0', sizeof (ignorelist_t));
+
+       /*
+        * ->ignore == 0  =>  collect
+        * ->ignore == 1  =>  ignore
+        */
+       il->ignore = invert ? 0 : 1;
+
+       return (il);
+} /* ignorelist_t *ignorelist_create (int ignore) */
+
+/*
+ * free memory used by ignorelist_t
+ */
+void ignorelist_free (ignorelist_t *il)
+{
+       ignorelist_item_t *this;
+       ignorelist_item_t *next;
+
+       if (il == NULL)
+               return;
+
+       for (this = il->head; this != NULL; this = next)
+       {
+               next = this->next;
+#if HAVE_REGEX_H
+               if (this->rmatch != NULL)
+               {
+                       regfree (this->rmatch);
+                       sfree (this->rmatch);
+                       this->rmatch = NULL;
+               }
+#endif
+               if (this->smatch != NULL)
+               {
+                       sfree (this->smatch);
+                       this->smatch = NULL;
+               }
+               sfree (this);
+       }
+
+       sfree (il);
+       il = NULL;
+} /* void ignorelist_destroy (ignorelist_t *il) */
+
+/*
+ * set ignore state of the ignorelist_t
+ */
+void ignorelist_set_invert (ignorelist_t *il, int invert)
+{
+       if (il == NULL)
+       {
+               DEBUG("ignore call with ignorelist_t == NULL");
+               return;
+       }
+
+       il->ignore = invert ? 0 : 1;
+} /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */
+
+/*
+ * append entry into ignorelist_t
+ * return 0 for success
+ */
+int ignorelist_add (ignorelist_t *il, const char *entry)
+{
+       size_t entry_len;
+
+       if (il == NULL)
+       {
+               DEBUG ("add called with ignorelist_t == NULL");
+               return (1);
+       }
+
+       entry_len = strlen (entry);
+
+       /* append nothing */
+       if (entry_len == 0)
+       {
+               DEBUG("not appending: empty entry");
+               return (1);
+       }
+
+#if HAVE_REGEX_H
+       /* regex string is enclosed in "/.../" */
+       if ((entry_len > 2) && (entry[0] == '/') && entry[entry_len - 1] == '/')
+       {
+               char *entry_copy;
+               size_t entry_copy_size;
+               int status;
+
+               /* We need to copy `entry' since it's const */
+               entry_copy_size = entry_len - 1;
+               entry_copy = smalloc (entry_copy_size);
+               sstrncpy (entry_copy, entry + 1, entry_copy_size);
+
+               status = ignorelist_append_regex(il, entry_copy);
+               sfree (entry_copy);
+               return status;
+       }
+#endif
+
+       return ignorelist_append_string(il, entry);
+} /* int ignorelist_add (ignorelist_t *il, const char *entry) */
+
+/*
+ * check list for entry
+ * return 1 for ignored entry
+ */
+int ignorelist_match (ignorelist_t *il, const char *entry)
+{
+       ignorelist_item_t *traverse;
+
+       /* if no entries, collect all */
+       if ((il == NULL) || (il->head == NULL))
+               return (0);
+
+       if ((entry == NULL) || (strlen (entry) == 0))
+               return (0);
+
+       /* traverse list and check entries */
+       for (traverse = il->head; traverse != NULL; traverse = traverse->next)
+       {
+#if HAVE_REGEX_H
+               if (traverse->rmatch != NULL)
+               {
+                       if (ignorelist_match_regex (traverse, entry))
+                               return (il->ignore);
+               }
+               else
+#endif
+               {
+                       if (ignorelist_match_string (traverse, entry))
+                               return (il->ignore);
+               }
+       } /* for traverse */
+
+       return (1 - il->ignore);
+} /* int ignorelist_match (ignorelist_t *il, const char *entry) */
+
diff --git a/src/daemon/utils_ignorelist.h b/src/daemon/utils_ignorelist.h
new file mode 100644 (file)
index 0000000..b47b55a
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * collectd - src/utils_ignorelist.h
+ * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Authors:
+ *   Lubos Stanek <lubek at users.sourceforge.net>
+ **/
+/**
+ * ignorelist handles plugin's list of configured collectable
+ * entries with global ignore action
+ **/
+
+#ifndef UTILS_IGNORELIST_H
+#define UTILS_IGNORELIST_H 1
+
+#include "collectd.h"
+
+#if HAVE_REGEX_H
+# include <regex.h>
+#endif
+
+/* public prototypes */
+
+struct ignorelist_s;
+typedef struct ignorelist_s ignorelist_t;
+
+/*
+ * create the ignorelist_t with known ignore state
+ * return pointer to ignorelist_t
+ */
+ignorelist_t *ignorelist_create (int invert);
+
+/*
+ * free memory used by ignorelist_t
+ */
+void ignorelist_free (ignorelist_t *il);
+
+/*
+ * set ignore state of the ignorelist_t
+ */
+void ignorelist_set_invert (ignorelist_t *il, int invert);
+
+/*
+ * append entry to ignorelist_t
+ * returns zero on success, non-zero upon failure.
+ */
+int ignorelist_add (ignorelist_t *il, const char *entry);
+
+/*
+ * check list for entry
+ * return 1 for ignored entry
+ */
+int ignorelist_match (ignorelist_t *il, const char *entry);
+
+#endif /* UTILS_IGNORELIST_H */
index 2a70802..c12aa10 100644 (file)
 #include "common.h" /* for STATIC_ARRAY_SIZE */
 #include "utils_subst.h"
 
+#if HAVE_LIBKSTAT
+kstat_ctl_t *kc;
+#endif /* HAVE_LIBKSTAT */
+
 DEF_TEST(subst)
 {
   struct {
index 2cc84b5..6566a73 100644 (file)
@@ -72,7 +72,7 @@
   (tsp)->tv_sec = CDTIME_T_TO_TIME_T (cdt);                                  \
   (tsp)->tv_nsec = (long) CDTIME_T_TO_NS ((cdt) & 0x3fffffff);               \
 } while (0)
-#define TIMESPEC_TO_CDTIME_T(ts) NS_TO_CDTIME_T(1000000000 * (ts)->tv_sec + (ts)->tv_nsec)
+#define TIMESPEC_TO_CDTIME_T(ts) NS_TO_CDTIME_T(1000000000ULL * (ts)->tv_sec + (ts)->tv_nsec)
 
 cdtime_t cdtime (void);
 
index c851ba2..94d0762 100644 (file)
--- a/src/dbi.c
+++ b/src/dbi.c
@@ -64,6 +64,8 @@ struct cdbi_database_s /* {{{ */
   char *name;
   char *select_db;
 
+  cdtime_t interval;
+
   char *driver;
   char *host;
   cdbi_driver_option_t *driver_options;
@@ -215,6 +217,7 @@ static void cdbi_database_free (cdbi_database_t *db) /* {{{ */
  *     
  *   <Database "plugin_instance1">
  *     Driver "mysql"
+ *     Interval 120
  *     DriverOption "hostname" "localhost"
  *     ...
  *     Query "plugin_instance0"
@@ -322,6 +325,8 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */
           &db->queries, &db->queries_num);
     else if (strcasecmp ("Host", child->key) == 0)
       status = cf_util_get_string (child, &db->host);
+    else if (strcasecmp ("Interval", child->key) == 0)
+      status = cf_util_get_cdtime(child, &db->interval);
     else
     {
       WARNING ("dbi plugin: Option `%s' not allowed here.", child->key);
@@ -407,7 +412,7 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */
       plugin_register_complex_read (/* group = */ NULL,
           /* name = */ name ? name : db->name,
           /* callback = */ cdbi_read_database,
-          /* interval = */ 0,
+          /* interval = */ (db->interval > 0) ? db->interval : 0,
           /* user_data = */ &ud);
       free (name);
     }
@@ -597,7 +602,7 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */
 
   udb_query_prepare_result (q, prep_area, (db->host ? db->host : hostname_g),
       /* plugin = */ "dbi", db->name,
-      column_names, column_num, /* interval = */ 0);
+      column_names, column_num, /* interval = */ (db->interval > 0) ? db->interval : 0);
 
   /* 0 = error; 1 = success; */
   status = dbi_result_first_row (res); /* {{{ */
index 5abee2f..e81a594 100644 (file)
@@ -1,9 +1,5 @@
 AUTOMAKE_OPTIONS = foreign no-dependencies
 
-if COMPILER_IS_GCC
-AM_CFLAGS = -Wall -Werror
-endif
-
 pkginclude_HEADERS = collectd/client.h collectd/network.h collectd/network_buffer.h collectd/lcc_features.h
 lib_LTLIBRARIES = libcollectdclient.la
 nodist_pkgconfig_DATA = libcollectdclient.pc
index 2883e6c..2d5f620 100644 (file)
@@ -147,7 +147,7 @@ static void log_logstash_print (yajl_gen g, int severity,
         * format time as a UTC ISO 8601 compliant string
         */
        strftime (timestamp_str, sizeof (timestamp_str),
-                 "%Y-%m-%d %H:%M:%SZ", &timestamp_tm);
+                 "%Y-%m-%dT%H:%M:%SZ", &timestamp_tm);
        timestamp_str[sizeof (timestamp_str) - 1] = '\0';
 
        if (yajl_gen_string(g, (u_char *)timestamp_str,
index fb2f3d3..ea16ce3 100644 (file)
@@ -76,6 +76,7 @@ static vm_size_t pagesize;
 #elif HAVE_LIBKSTAT
 static int pagesize;
 static kstat_t *ksp;
+static kstat_t *ksz;
 /* #endif HAVE_LIBKSTAT */
 
 #elif HAVE_SYSCTL
@@ -137,6 +138,12 @@ static int memory_init (void)
                ksp = NULL;
                return (-1);
        }
+       if (get_kstat (&ksz, "zfs", 0, "arcstats") != 0)
+       {
+               ksz = NULL;
+               return (-1);
+       }
+
 /* #endif HAVE_LIBKSTAT */
 
 #elif HAVE_SYSCTL
@@ -371,6 +378,8 @@ static int memory_read_internal (value_list_t *vl)
        long long mem_lock;
        long long mem_kern;
        long long mem_unus;
+       long long arcsize;
+
 
        long long pp_kernel;
        long long physmem;
@@ -378,17 +387,20 @@ static int memory_read_internal (value_list_t *vl)
 
        if (ksp == NULL)
                return (-1);
+       if (ksz == NULL)
+               return (-1);
 
        mem_used = get_kstat_value (ksp, "pagestotal");
        mem_free = get_kstat_value (ksp, "pagesfree");
        mem_lock = get_kstat_value (ksp, "pageslocked");
-       mem_kern = 0;
-       mem_unus = 0;
-
+       arcsize = get_kstat_value (ksz, "size");
        pp_kernel = get_kstat_value (ksp, "pp_kernel");
        physmem = get_kstat_value (ksp, "physmem");
        availrmem = get_kstat_value (ksp, "availrmem");
 
+       mem_kern = 0;
+       mem_unus = 0;
+
        if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL))
        {
                WARNING ("memory plugin: one of used, free or locked is negative.");
@@ -431,11 +443,14 @@ static int memory_read_internal (value_list_t *vl)
        mem_lock *= pagesize; /* some? ;) */
        mem_kern *= pagesize; /* it's 2011 RAM is cheap */
        mem_unus *= pagesize;
+       mem_kern -= arcsize;
+
 
        MEMORY_SUBMIT ("used",     (gauge_t) mem_used,
                       "free",     (gauge_t) mem_free,
                       "locked",   (gauge_t) mem_lock,
                       "kernel",   (gauge_t) mem_kern,
+                      "arc",      (gauge_t) arcsize,
                       "unusable", (gauge_t) mem_unus);
 /* #endif HAVE_LIBKSTAT */
 
index 210d38c..7003fcc 100644 (file)
@@ -24,6 +24,7 @@
  * Authors:
  *   Marc Falzon <marc at baha dot mu>
  *   Florian octo Forster <octo at collectd.org>
+ *   Jan-Piet Mens <jpmens at gmail.com>
  **/
 
 // Reference: http://mosquitto.org/api/files/mosquitto-h.html
@@ -48,6 +49,9 @@
 #ifndef MQTT_KEEPALIVE
 # define MQTT_KEEPALIVE 60
 #endif
+#ifndef SSL_VERIFY_PEER
+# define SSL_VERIFY_PEER  1
+#endif
 
 
 /*
@@ -67,6 +71,11 @@ struct mqtt_client_conf
     char               *username;
     char               *password;
     int                 qos;
+    char                *cacertificatefile;
+    char                *certificatefile;
+    char                *certificatekeyfile;
+    char                *tlsprotocol;
+    char                *ciphersuite;
 
     /* For publishing */
     char               *topic_prefix;
@@ -176,9 +185,10 @@ static void on_message (
     char *payload;
     int status;
 
-    if ((msg->payloadlen <= 0)
-            || (((uint8_t *) msg->payload)[msg->payloadlen - 1] != 0))
+    if (msg->payloadlen <= 0) {
+        DEBUG ("mqtt plugin: message has empty payload");
         return;
+    }
 
     topic = strdup (msg->topic);
     name = strip_prefix (topic);
@@ -207,7 +217,15 @@ static void on_message (
     }
     vl.values_len = ds->ds_num;
 
-    payload = strdup ((void *) msg->payload);
+    payload = malloc (msg->payloadlen+1);
+    if (payload == NULL)
+    {
+        ERROR ("mqtt plugin: malloc for payload buffer failed.");
+        return;
+    }
+    memmove (payload, msg->payload, msg->payloadlen);
+    payload[msg->payloadlen] = 0;
+
     DEBUG ("mqtt plugin: payload = \"%s\"", payload);
     status = parse_values (payload, &vl, ds);
     if (status != 0)
@@ -277,6 +295,35 @@ static int mqtt_connect (mqtt_client_conf_t *conf)
         return (-1);
     }
 
+#if LIBMOSQUITTO_MAJOR != 0
+    if (conf->cacertificatefile) {
+        status = mosquitto_tls_set(conf->mosq, conf->cacertificatefile, NULL,
+                                  conf->certificatefile, conf->certificatekeyfile, /* pw_callback */NULL);
+        if (status != MOSQ_ERR_SUCCESS) {
+            ERROR ("mqtt plugin: cannot mosquitto_tls_set: %s", mosquitto_strerror(status));
+            mosquitto_destroy (conf->mosq);
+            conf->mosq = NULL;
+            return (-1);
+        }
+
+        status = mosquitto_tls_opts_set(conf->mosq, SSL_VERIFY_PEER, conf->tlsprotocol, conf->ciphersuite);
+        if (status != MOSQ_ERR_SUCCESS) {
+            ERROR ("mqtt plugin: cannot mosquitto_tls_opts_set: %s", mosquitto_strerror(status));
+            mosquitto_destroy (conf->mosq);
+            conf->mosq = NULL;
+            return (-1);
+        }
+
+        status = mosquitto_tls_insecure_set(conf->mosq, false);
+        if (status != MOSQ_ERR_SUCCESS) {
+            ERROR ("mqtt plugin: cannot mosquitto_tls_insecure_set: %s", mosquitto_strerror(status));
+            mosquitto_destroy (conf->mosq);
+            conf->mosq = NULL;
+            return (-1);
+        }
+    }
+#endif
+
     if (conf->username && conf->password)
     {
         status = mosquitto_username_pw_set (conf->mosq, conf->username, conf->password);
@@ -407,11 +454,11 @@ static int publish (mqtt_client_conf_t *conf, char const *topic,
     {
         char errbuf[1024];
         c_complain (LOG_ERR,
-                &conf->complaint_cantpublish,
-                "plugin mqtt: mosquitto_publish failed: %s",
-                status == MOSQ_ERR_ERRNO ?
-                sstrerror(errno, errbuf, sizeof (errbuf)) :
-                mosquitto_strerror(status));
+            &conf->complaint_cantpublish,
+            "mqtt plugin: mosquitto_publish failed: %s",
+            (status == MOSQ_ERR_ERRNO)
+            ? sstrerror(errno, errbuf, sizeof (errbuf))
+            : mosquitto_strerror(status));
         /* Mark our connection "down" regardless of the error as a safety
          * measure; we will try to reconnect the next time we have to publish a
          * message */
@@ -494,6 +541,10 @@ static int mqtt_write (const data_set_t *ds, const value_list_t *vl,
  *   StoreRates true
  *   Retain false
  *   QoS 0
+ *   CACert "ca.pem"                   Enables TLS if set
+ *   CertificateFile "client-cert.pem"         optional
+ *   CertificateKeyFile "client-key.pem"               optional
+ *   TLSProtocol "tlsv1.2"             optional
  * </Publish>
  */
 static int mqtt_config_publisher (oconfig_item_t *ci)
@@ -527,6 +578,13 @@ static int mqtt_config_publisher (oconfig_item_t *ci)
     conf->topic_prefix = strdup (MQTT_DEFAULT_TOPIC_PREFIX);
     conf->store_rates = 1;
 
+    status = pthread_mutex_init (&conf->lock, NULL);
+    if (status != 0)
+    {
+      mqtt_free (conf);
+      return (status);
+    }
+
     C_COMPLAIN_INIT (&conf->complaint_cantpublish);
 
     for (i = 0; i < ci->children_num; i++)
@@ -563,6 +621,16 @@ static int mqtt_config_publisher (oconfig_item_t *ci)
             cf_util_get_boolean (child, &conf->store_rates);
         else if (strcasecmp ("Retain", child->key) == 0)
             cf_util_get_boolean (child, &conf->retain);
+        else if (strcasecmp ("CACert", child->key) == 0)
+            cf_util_get_string (child, &conf->cacertificatefile);
+        else if (strcasecmp ("CertificateFile", child->key) == 0)
+            cf_util_get_string (child, &conf->certificatefile);
+        else if (strcasecmp ("CertificateKeyFile", child->key) == 0)
+            cf_util_get_string (child, &conf->certificatekeyfile);
+        else if (strcasecmp ("TLSProtocol", child->key) == 0)
+            cf_util_get_string (child, &conf->tlsprotocol);
+        else if (strcasecmp ("CipherSuite", child->key) == 0)
+            cf_util_get_string (child, &conf->ciphersuite);
         else
             ERROR ("mqtt plugin: Unknown config option: %s", child->key);
     }
@@ -583,7 +651,7 @@ static int mqtt_config_publisher (oconfig_item_t *ci)
  *   User "guest"
  *   Password "secret"
  *   Topic "collectd/#"
- * </Publish>
+ * </Subscribe>
  */
 static int mqtt_config_subscriber (oconfig_item_t *ci)
 {
@@ -615,6 +683,13 @@ static int mqtt_config_subscriber (oconfig_item_t *ci)
     conf->topic = strdup (MQTT_DEFAULT_TOPIC);
     conf->clean_session = 1;
 
+    status = pthread_mutex_init (&conf->lock, NULL);
+    if (status != 0)
+    {
+      mqtt_free (conf);
+      return (status);
+    }
+
     C_COMPLAIN_INIT (&conf->complaint_cantpublish);
 
     for (i = 0; i < ci->children_num; i++)
index 24dbf49..d094e73 100644 (file)
@@ -2027,18 +2027,18 @@ static int ps_read (void)
                        pse.io_syscw = -1;
 
                        ps_list_add (procs[i].ki_comm, have_cmdline ? cmdline : NULL, &pse);
-               } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */
 
-               switch (procs[i].ki_stat)
-               {
-                       case SSTOP:     stopped++;      break;
-                       case SSLEEP:    sleeping++;     break;
-                       case SRUN:      running++;      break;
-                       case SIDL:      idle++;         break;
-                       case SWAIT:     wait++;         break;
-                       case SLOCK:     blocked++;      break;
-                       case SZOMB:     zombies++;      break;
-               }
+                       switch (procs[i].ki_stat)
+                       {
+                               case SSTOP:     stopped++;      break;
+                               case SSLEEP:    sleeping++;     break;
+                               case SRUN:      running++;      break;
+                               case SIDL:      idle++;         break;
+                               case SWAIT:     wait++;         break;
+                               case SLOCK:     blocked++;      break;
+                               case SZOMB:     zombies++;      break;
+                       }
+               } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */
        }
 
        kvm_close(kd);
@@ -2163,18 +2163,18 @@ static int ps_read (void)
                        pse.cswitch_invol = -1;
 
                        ps_list_add (procs[i].p_comm, have_cmdline ? cmdline : NULL, &pse);
-               } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */
 
-               switch (procs[i].p_stat)
-               {
-                       case SSTOP:     stopped++;      break;
-                       case SSLEEP:    sleeping++;     break;
-                       case SRUN:      running++;      break;
-                       case SIDL:      idle++;         break;
-                       case SONPROC:   onproc++;       break;
-                       case SDEAD:     dead++;         break;
-                       case SZOMB:     zombies++;      break;
-               }
+                       switch (procs[i].p_stat)
+                       {
+                               case SSTOP:     stopped++;      break;
+                               case SSLEEP:    sleeping++;     break;
+                               case SRUN:      running++;      break;
+                               case SIDL:      idle++;         break;
+                               case SONPROC:   onproc++;       break;
+                               case SDEAD:     dead++;         break;
+                               case SZOMB:     zombies++;      break;
+                       }
+               } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */
        }
 
        kvm_close(kd);
index b7cc5b9..210d785 100644 (file)
@@ -302,7 +302,7 @@ void cpy_log_exception(const char *context) {
                Py_XDECREF(traceback);
                return;
        }
-       list = PyObject_CallFunction(cpy_format_exception, "NNN", type, value, traceback); /* New reference. */
+       list = PyObject_CallFunction(cpy_format_exception, "NNN", type, value, traceback); /* New reference. Steals references from "type", "value" and "traceback". */
        if (list)
                l = PyObject_Length(list);
        for (i = 0; i < l; ++i) {
@@ -322,9 +322,6 @@ void cpy_log_exception(const char *context) {
        }
        Py_XDECREF(list);
        PyErr_Clear();
-       Py_DECREF(type);
-       Py_XDECREF(value);
-       Py_XDECREF(traceback);
 }
 
 static int cpy_read_callback(user_data_t *data) {
index d9a932a..6a03a19 100644 (file)
@@ -924,8 +924,7 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
     tmp_unsigned = (uint32_t) *vl->val.integer;
     tmp_signed = (int32_t) *vl->val.integer;
 
-    if ((vl->type == ASN_INTEGER)
-        || (vl->type == ASN_GAUGE))
+    if (vl->type == ASN_INTEGER)
       prefer_signed = 1;
 
     DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", tmp_unsigned);
@@ -1681,7 +1680,7 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
 
   if (host->sess_handle == NULL)
   {
-    DEBUG ("snmp plugin: csnmp_read_table: host->sess_handle == NULL");
+    DEBUG ("snmp plugin: csnmp_read_value: host->sess_handle == NULL");
     return (-1);
   }
 
index 9a6da1d..8047b1a 100644 (file)
@@ -850,8 +850,19 @@ static int statsd_metric_submit_unsafe (char const *name, /* {{{ */
     else
       values[0].gauge = (gauge_t) c_avl_size (metric->set);
   }
-  else
-    values[0].derive = (derive_t) metric->value;
+  else { /* STATSD_COUNTER */
+      /*
+       * Expand a single value to two metrics:
+       *
+       * - The absolute counter, as a gauge
+       * - A derived rate for this counter
+       */
+      values[0].derive = (derive_t) metric->value;
+      plugin_dispatch_values(&vl);
+
+      sstrncpy(vl.type, "gauge", sizeof (vl.type));
+      values[0].gauge = (gauge_t) metric->value;
+  }
 
   return (plugin_dispatch_values (&vl));
 } /* }}} int statsd_metric_submit_unsafe */
@@ -941,7 +952,7 @@ static int statsd_shutdown (void) /* {{{ */
   while (c_avl_pick (metrics_tree, &key, &value) == 0)
   {
     sfree (key);
-    sfree (value);
+    statsd_metric_free (value);
   }
   c_avl_destroy (metrics_tree);
   metrics_tree = NULL;
index b0bc95f..4e34a9e 100644 (file)
@@ -458,7 +458,7 @@ static int tbl_parse_line (tbl_t *tbl, char *line, size_t len)
        }
 
        if (i <= tbl->max_colnum) {
-               log_err ("Not enough columns in line "
+               log_warn ("Not enough columns in line "
                                "(expected at least %zu, got %zu).",
                                tbl->max_colnum + 1, i);
                return -1;
@@ -490,11 +490,11 @@ static int tbl_read_table (tbl_t *tbl)
        while (NULL != fgets (buf, sizeof (buf), fh)) {
                if ('\0' != buf[sizeof (buf) - 1]) {
                        buf[sizeof (buf) - 1] = '\0';
-                       log_err ("Table %s: Truncated line: %s", tbl->file, buf);
+                       log_warn ("Table %s: Truncated line: %s", tbl->file, buf);
                }
 
                if (0 != tbl_parse_line (tbl, buf, sizeof (buf))) {
-                       log_err ("Table %s: Failed to parse line: %s", tbl->file, buf);
+                       log_warn ("Table %s: Failed to parse line: %s", tbl->file, buf);
                        continue;
                }
        }
index 38fb546..5847218 100644 (file)
@@ -14,7 +14,8 @@ cache_eviction                value:DERIVE:0:U
 cache_operation                value:DERIVE:0:U
 cache_ratio            value:GAUGE:0:100
 cache_result           value:DERIVE:0:U
-cache_size             value:GAUGE:0:U
+cache_size             value:GAUGE:0:1125899906842623
+capacity       value:GAUGE:0:U
 ceph_bytes             value:GAUGE:U:U
 ceph_latency   value:GAUGE:U:U
 ceph_rate                      value:DERIVE:0:U
diff --git a/src/utils_ignorelist.c b/src/utils_ignorelist.c
deleted file mode 100644 (file)
index a8ca7db..0000000
+++ /dev/null
@@ -1,338 +0,0 @@
-/**
- * collectd - src/utils_ignorelist.c
- * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
- * Copyright (C) 2008 Florian Forster <octo at collectd.org>
- *
- * This program is free software; you can redistribute it and/
- * or modify it under the terms of the GNU General Public Li-
- * cence as published by the Free Software Foundation; either
- * version 2 of the Licence, or any later version.
- *
- * This program is distributed in the hope that it will be use-
- * ful, but WITHOUT ANY WARRANTY; without even the implied war-
- * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public Licence for more details.
- *
- * You should have received a copy of the GNU General Public
- * Licence along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
- *
- * Authors:
- *   Lubos Stanek <lubek at users.sourceforge.net>
- *   Florian Forster <octo at collectd.org>
- **/
-/**
- * ignorelist handles plugin's list of configured collectable
- * entries with global ignore action
- **/
-/**
- * Usage:
- * 
- * Define plugin's global pointer variable of type ignorelist_t:
- *   ignorelist_t *myconfig_ignore;
- * If you know the state of the global ignore (IgnoreSelected),
- * allocate the variable with:
- *   myconfig_ignore = ignorelist_create (YourKnownIgnore);
- * If you do not know the state of the global ignore,
- * initialize the global variable and set the ignore flag later:
- *   myconfig_ignore = ignorelist_init ();
- * Append single entries in your cf_register'ed callback function:
- *   ignorelist_add (myconfig_ignore, newentry);
- * When you hit the IgnoreSelected config option,
- * offer it to the list:
- *   ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore);
- * That is all for the ignorelist initialization.
- * Later during read and write (plugin's registered functions) get
- * the information whether this entry would be collected or not:
- *   if (ignorelist_match (myconfig_ignore, thisentry))
- *     return;
- **/
-
-#if HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "common.h"
-#include "plugin.h"
-#include "utils_ignorelist.h"
-
-/*
- * private prototypes
- */
-struct ignorelist_item_s
-{
-#if HAVE_REGEX_H
-       regex_t *rmatch;        /* regular expression entry identification */
-#endif
-       char *smatch;           /* string entry identification */
-       struct ignorelist_item_s *next;
-};
-typedef struct ignorelist_item_s ignorelist_item_t;
-
-struct ignorelist_s
-{
-       int ignore;             /* ignore entries */
-       ignorelist_item_t *head;        /* pointer to the first entry */
-};
-
-/* *** *** *** ********************************************* *** *** *** */
-/* *** *** *** *** *** ***   private functions   *** *** *** *** *** *** */
-/* *** *** *** ********************************************* *** *** *** */
-
-static inline void ignorelist_append (ignorelist_t *il, ignorelist_item_t *item)
-{
-       assert ((il != NULL) && (item != NULL));
-
-       item->next = il->head;
-       il->head = item;
-}
-
-#if HAVE_REGEX_H
-static int ignorelist_append_regex(ignorelist_t *il, const char *re_str)
-{
-       regex_t *re;
-       ignorelist_item_t *entry;
-       int status;
-
-       re = malloc (sizeof (*re));
-       if (re == NULL)
-       {
-               ERROR ("utils_ignorelist: malloc failed");
-               return (ENOMEM);
-       }
-       memset (re, 0, sizeof (*re));
-
-       status = regcomp (re, re_str, REG_EXTENDED);
-       if (status != 0)
-       {
-               char errbuf[1024] = "";
-               regerror (status, re, errbuf, sizeof (errbuf));
-               ERROR ("utils_ignorelist: regcomp failed: %s", errbuf);
-               regfree (re);
-               sfree (re);
-               return (status);
-       }
-
-       entry = malloc (sizeof (*entry));
-       if (entry == NULL)
-       {
-               ERROR ("utils_ignorelist: malloc failed");
-               regfree (re);
-               sfree (re);
-               return (ENOMEM);
-       }
-       memset (entry, 0, sizeof (*entry));
-       entry->rmatch = re;
-
-       ignorelist_append (il, entry);
-       return (0);
-} /* int ignorelist_append_regex */
-#endif
-
-static int ignorelist_append_string(ignorelist_t *il, const char *entry)
-{
-       ignorelist_item_t *new;
-
-       /* create new entry */
-       if ((new = malloc(sizeof(ignorelist_item_t))) == NULL )
-       {
-               ERROR ("cannot allocate new entry");
-               return (1);
-       }
-       memset (new, '\0', sizeof(ignorelist_item_t));
-       new->smatch = sstrdup(entry);
-
-       /* append new entry */
-       ignorelist_append (il, new);
-
-       return (0);
-} /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */
-
-#if HAVE_REGEX_H
-/*
- * check list for entry regex match
- * return 1 if found
- */
-static int ignorelist_match_regex (ignorelist_item_t *item, const char *entry)
-{
-       assert ((item != NULL) && (item->rmatch != NULL)
-                       && (entry != NULL) && (strlen (entry) > 0));
-
-       /* match regex */
-       if (regexec (item->rmatch, entry, 0, NULL, 0) == 0)
-               return (1);
-
-       return (0);
-} /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */
-#endif
-
-/*
- * check list for entry string match
- * return 1 if found
- */
-static int ignorelist_match_string (ignorelist_item_t *item, const char *entry)
-{
-       assert ((item != NULL) && (item->smatch != NULL)
-                       && (entry != NULL) && (strlen (entry) > 0));
-
-       if (strcmp (entry, item->smatch) == 0)
-               return (1);
-
-       return (0);
-} /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */
-
-
-/* *** *** *** ******************************************** *** *** *** */
-/* *** *** *** *** *** ***   public functions   *** *** *** *** *** *** */
-/* *** *** *** ******************************************** *** *** *** */
-
-/*
- * create the ignorelist_t with known ignore state
- * return pointer to ignorelist_t
- */
-ignorelist_t *ignorelist_create (int invert)
-{
-       ignorelist_t *il;
-
-       /* smalloc exits if it failes */
-       il = (ignorelist_t *) smalloc (sizeof (ignorelist_t));
-       memset (il, '\0', sizeof (ignorelist_t));
-
-       /*
-        * ->ignore == 0  =>  collect
-        * ->ignore == 1  =>  ignore
-        */
-       il->ignore = invert ? 0 : 1;
-
-       return (il);
-} /* ignorelist_t *ignorelist_create (int ignore) */
-
-/*
- * free memory used by ignorelist_t
- */
-void ignorelist_free (ignorelist_t *il)
-{
-       ignorelist_item_t *this;
-       ignorelist_item_t *next;
-
-       if (il == NULL)
-               return;
-
-       for (this = il->head; this != NULL; this = next)
-       {
-               next = this->next;
-#if HAVE_REGEX_H
-               if (this->rmatch != NULL)
-               {
-                       regfree (this->rmatch);
-                       sfree (this->rmatch);
-                       this->rmatch = NULL;
-               }
-#endif
-               if (this->smatch != NULL)
-               {
-                       sfree (this->smatch);
-                       this->smatch = NULL;
-               }
-               sfree (this);
-       }
-
-       sfree (il);
-       il = NULL;
-} /* void ignorelist_destroy (ignorelist_t *il) */
-
-/*
- * set ignore state of the ignorelist_t
- */
-void ignorelist_set_invert (ignorelist_t *il, int invert)
-{
-       if (il == NULL)
-       {
-               DEBUG("ignore call with ignorelist_t == NULL");
-               return;
-       }
-
-       il->ignore = invert ? 0 : 1;
-} /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */
-
-/*
- * append entry into ignorelist_t
- * return 0 for success
- */
-int ignorelist_add (ignorelist_t *il, const char *entry)
-{
-       size_t entry_len;
-
-       if (il == NULL)
-       {
-               DEBUG ("add called with ignorelist_t == NULL");
-               return (1);
-       }
-
-       entry_len = strlen (entry);
-
-       /* append nothing */
-       if (entry_len == 0)
-       {
-               DEBUG("not appending: empty entry");
-               return (1);
-       }
-
-#if HAVE_REGEX_H
-       /* regex string is enclosed in "/.../" */
-       if ((entry_len > 2) && (entry[0] == '/') && entry[entry_len - 1] == '/')
-       {
-               char *entry_copy;
-               size_t entry_copy_size;
-               int status;
-
-               /* We need to copy `entry' since it's const */
-               entry_copy_size = entry_len - 1;
-               entry_copy = smalloc (entry_copy_size);
-               sstrncpy (entry_copy, entry + 1, entry_copy_size);
-
-               status = ignorelist_append_regex(il, entry_copy);
-               sfree (entry_copy);
-               return status;
-       }
-#endif
-
-       return ignorelist_append_string(il, entry);
-} /* int ignorelist_add (ignorelist_t *il, const char *entry) */
-
-/*
- * check list for entry
- * return 1 for ignored entry
- */
-int ignorelist_match (ignorelist_t *il, const char *entry)
-{
-       ignorelist_item_t *traverse;
-
-       /* if no entries, collect all */
-       if ((il == NULL) || (il->head == NULL))
-               return (0);
-
-       if ((entry == NULL) || (strlen (entry) == 0))
-               return (0);
-
-       /* traverse list and check entries */
-       for (traverse = il->head; traverse != NULL; traverse = traverse->next)
-       {
-#if HAVE_REGEX_H
-               if (traverse->rmatch != NULL)
-               {
-                       if (ignorelist_match_regex (traverse, entry))
-                               return (il->ignore);
-               }
-               else
-#endif
-               {
-                       if (ignorelist_match_string (traverse, entry))
-                               return (il->ignore);
-               }
-       } /* for traverse */
-
-       return (1 - il->ignore);
-} /* int ignorelist_match (ignorelist_t *il, const char *entry) */
-
diff --git a/src/utils_ignorelist.h b/src/utils_ignorelist.h
deleted file mode 100644 (file)
index b47b55a..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * collectd - src/utils_ignorelist.h
- * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/
- * or modify it under the terms of the GNU General Public Li-
- * cence as published by the Free Software Foundation; either
- * version 2 of the Licence, or any later version.
- *
- * This program is distributed in the hope that it will be use-
- * ful, but WITHOUT ANY WARRANTY; without even the implied war-
- * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public Licence for more details.
- *
- * You should have received a copy of the GNU General Public
- * Licence along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
- *
- * Authors:
- *   Lubos Stanek <lubek at users.sourceforge.net>
- **/
-/**
- * ignorelist handles plugin's list of configured collectable
- * entries with global ignore action
- **/
-
-#ifndef UTILS_IGNORELIST_H
-#define UTILS_IGNORELIST_H 1
-
-#include "collectd.h"
-
-#if HAVE_REGEX_H
-# include <regex.h>
-#endif
-
-/* public prototypes */
-
-struct ignorelist_s;
-typedef struct ignorelist_s ignorelist_t;
-
-/*
- * create the ignorelist_t with known ignore state
- * return pointer to ignorelist_t
- */
-ignorelist_t *ignorelist_create (int invert);
-
-/*
- * free memory used by ignorelist_t
- */
-void ignorelist_free (ignorelist_t *il);
-
-/*
- * set ignore state of the ignorelist_t
- */
-void ignorelist_set_invert (ignorelist_t *il, int invert);
-
-/*
- * append entry to ignorelist_t
- * returns zero on success, non-zero upon failure.
- */
-int ignorelist_add (ignorelist_t *il, const char *entry);
-
-/*
- * check list for entry
- * return 1 for ignored entry
- */
-int ignorelist_match (ignorelist_t *il, const char *entry);
-
-#endif /* UTILS_IGNORELIST_H */
index b63a81a..afeb39e 100644 (file)
@@ -571,6 +571,64 @@ static cu_mount_t *cu_mount_gen_getmntent (void)
 #warn "This version of `getmntent' hat not yet been implemented!"
 /* #endif HAVE_SEQ_GETMNTENT */
 
+#elif HAVE_GETMNTENT_R
+static cu_mount_t *cu_mount_getmntent (void)
+{
+       FILE *fp;
+       struct mntent me;
+       char mntbuf[1024];
+
+       cu_mount_t *first = NULL;
+       cu_mount_t *last  = NULL;
+       cu_mount_t *new   = 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)));
+               return (NULL);
+       }
+
+       while (getmntent_r (fp, &me, mntbuf, sizeof (mntbuf) ))
+       {
+               if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+                       break;
+               memset (new, '\0', sizeof (cu_mount_t));
+
+               /* Copy values from `struct mntent *' */
+               new->dir         = sstrdup (me.mnt_dir);
+               new->spec_device = sstrdup (me.mnt_fsname);
+               new->type        = sstrdup (me.mnt_type);
+               new->options     = sstrdup (me.mnt_opts);
+               new->device      = get_device_name (new->options);
+               new->next        = NULL;
+
+               DEBUG ("utils_mount: new = {dir = %s, spec_device = %s, type = %s, options = %s, device = %s}",
+                               new->dir, new->spec_device, new->type, new->options, new->device);
+
+               /* Append to list */
+               if (first == NULL)
+               {
+                       first = new;
+                       last  = new;
+               }
+               else
+               {
+                       last->next = new;
+                       last       = new;
+               }
+       }
+
+       endmntent (fp);
+
+       DEBUG ("utils_mount: return (0x%p)", (void *) first);
+
+       return (first);
+} /* HAVE_GETMNTENT_R */
+
 #elif HAVE_ONE_GETMNTENT
 static cu_mount_t *cu_mount_getmntent (void)
 {
index 77a4205..b4cb432 100644 (file)
 #include "collectd.h"
 #include "utils_mount.h"
 
+#if HAVE_LIBKSTAT
+kstat_ctl_t *kc;
+#endif /* HAVE_LIBKSTAT */
+
 DEF_TEST(cu_mount_checkoption)
 {
   char line_opts[] = "foo=one,bar=two,qux=three";
index f0f0b46..f85910e 100644 (file)
 #include "utils_vl_lookup.h"
 #include "utils_avltree.h"
 
+#if HAVE_LIBKSTAT
+kstat_ctl_t *kc;
+#endif /* HAVE_LIBKSTAT */
+
 #if BUILD_TEST
 # define sstrncpy strncpy
 # define plugin_log(s, ...) do { \
index dff8f71..6824b13 100644 (file)
@@ -128,7 +128,7 @@ enum plginst_field {
 };
 
 static enum plginst_field plugin_instance_format[PLGINST_MAX_FIELDS] =
-    { plginst_name };
+    { plginst_none };
 
 /* InterfaceFormat. */
 enum if_field {
@@ -417,8 +417,8 @@ lv_config (const char *key, const char *value)
             else if (strcasecmp (fields[i], "uuid") == 0)
                 hostname_format[i] = hf_uuid;
             else {
-                sfree (value_copy);
                 ERROR (PLUGIN_NAME " plugin: unknown HostnameFormat field: %s", fields[i]);
+                sfree (value_copy);
                 return -1;
             }
         }
@@ -449,13 +449,16 @@ lv_config (const char *key, const char *value)
         }
 
         for (i = 0; i < n; ++i) {
-            if (strcasecmp (fields[i], "name") == 0)
+            if (strcasecmp (fields[i], "none") == 0) {
+                plugin_instance_format[i] = plginst_none;
+                break;
+            } else if (strcasecmp (fields[i], "name") == 0)
                 plugin_instance_format[i] = plginst_name;
             else if (strcasecmp (fields[i], "uuid") == 0)
                 plugin_instance_format[i] = plginst_uuid;
             else {
+                ERROR (PLUGIN_NAME " plugin: unknown PluginInstanceFormat field: %s", fields[i]);
                 sfree (value_copy);
-                ERROR (PLUGIN_NAME " plugin: unknown HostnameFormat field: %s", fields[i]);
                 return -1;
             }
         }
index ed596bb..868bca8 100644 (file)
@@ -59,6 +59,7 @@ struct wh_callback_s
         char *clientkeypass;
         long sslversion;
         _Bool store_rates;
+        _Bool log_http_error;
         int   low_speed_limit;
         time_t low_speed_time;
         int timeout;
@@ -80,6 +81,19 @@ struct wh_callback_s
 };
 typedef struct wh_callback_s wh_callback_t;
 
+static void wh_log_http_error (wh_callback_t *cb)
+{
+        if (!cb->log_http_error)
+                return;
+
+        long http_code = 0;
+
+        curl_easy_getinfo (cb->curl, CURLINFO_RESPONSE_CODE, &http_code);
+
+        if (http_code != 200)
+                INFO ("write_http plugin: HTTP Error code: %lu", http_code);
+}
+
 static void wh_reset_buffer (wh_callback_t *cb)  /* {{{ */
 {
         memset (cb->send_buffer, 0, cb->send_buffer_size);
@@ -101,6 +115,9 @@ static int wh_send_buffer (wh_callback_t *cb) /* {{{ */
 
         curl_easy_setopt (cb->curl, CURLOPT_POSTFIELDS, cb->send_buffer);
         status = curl_easy_perform (cb->curl);
+
+        wh_log_http_error (cb);
+
         if (status != CURLE_OK)
         {
                 ERROR ("write_http plugin: curl_easy_perform failed with "
@@ -538,6 +555,7 @@ static int wh_config_node (oconfig_item_t *ci) /* {{{ */
         cb->sslversion = CURL_SSLVERSION_DEFAULT;
         cb->low_speed_limit = 0;
         cb->timeout = 0;
+        cb->log_http_error = 0;
 
         pthread_mutex_init (&cb->send_lock, /* attr = */ NULL);
 
@@ -609,6 +627,8 @@ static int wh_config_node (oconfig_item_t *ci) /* {{{ */
                         cf_util_get_int (child, &cb->low_speed_limit);
                 else if (strcasecmp ("Timeout", child->key) == 0)
                         cf_util_get_int (child, &cb->timeout);
+                else if (strcasecmp ("LogHttpError", child->key) == 0)
+                        cf_util_get_boolean (child, &cb->log_http_error);
                 else
                 {
                         ERROR ("write_http plugin: Invalid configuration "
index 7ba476c..1eb082f 100644 (file)
@@ -46,6 +46,8 @@ struct wr_node_s
   struct timeval timeout;
   char *prefix;
   int database;
+  int max_set_size;
+  _Bool store_rates;
 
   redisContext *conn;
   pthread_mutex_t lock;
@@ -68,7 +70,6 @@ static int wr_write (const data_set_t *ds, /* {{{ */
   char *value_ptr;
   int status;
   redisReply   *rr;
-  int i;
 
   status = FORMAT_VL (ident, sizeof (ident), vl);
   if (status != 0)
@@ -81,40 +82,7 @@ static int wr_write (const data_set_t *ds, /* {{{ */
   memset (value, 0, sizeof (value));
   value_size = sizeof (value);
   value_ptr = &value[0];
-
-#define APPEND(...) do {                                             \
-  status = snprintf (value_ptr, value_size, __VA_ARGS__);            \
-  if (((size_t) status) > value_size)                                \
-  {                                                                  \
-    value_ptr += value_size;                                         \
-    value_size = 0;                                                  \
-  }                                                                  \
-  else                                                               \
-  {                                                                  \
-    value_ptr += status;                                             \
-    value_size -= status;                                            \
-  }                                                                  \
-} while (0)
-
-  APPEND ("%s:", time);
-
-  for (i = 0; i < ds->ds_num; i++)
-  {
-    if (ds->ds[i].type == DS_TYPE_COUNTER)
-      APPEND ("%llu", vl->values[i].counter);
-    else if (ds->ds[i].type == DS_TYPE_GAUGE)
-      APPEND (GAUGE_FORMAT, vl->values[i].gauge);
-    else if (ds->ds[i].type == DS_TYPE_DERIVE)
-      APPEND ("%"PRIi64, vl->values[i].derive);
-    else if (ds->ds[i].type == DS_TYPE_ABSOLUTE)
-      APPEND ("%"PRIu64, vl->values[i].absolute);
-    else
-      assert (23 == 42);
-  }
-
-#undef APPEND
-
-  status = format_values (value_ptr, value_size, ds, vl, /* store rates = */ 0);
+  status = format_values (value_ptr, value_size, ds, vl, node->store_rates);
   pthread_mutex_lock (&node->lock);
   if (status != 0)
     return (status);
@@ -139,7 +107,7 @@ static int wr_write (const data_set_t *ds, /* {{{ */
       pthread_mutex_unlock (&node->lock);
       return (-1);
     }
-   
+
     rr = redisCommand(node->conn, "SELECT %d", node->database);
     if (rr == NULL)
       WARNING("SELECT command error. database:%d message:%s", node->database, node->conn->errstr);
@@ -153,6 +121,15 @@ static int wr_write (const data_set_t *ds, /* {{{ */
   else
     freeReplyObject (rr);
 
+  if (node->max_set_size >= 0)
+  {
+    rr = redisCommand (node->conn, "ZREMRANGEBYRANK %s %d %d", key, 0, (-1 * node->max_set_size) - 1);
+    if (rr == NULL)
+      WARNING("ZREMRANGEBYRANK command error. key:%s message:%s", key, node->conn->errstr);
+    else
+      freeReplyObject (rr);
+  }
+
   /* TODO(octo): This is more overhead than necessary. Use the cache and
    * metadata to determine if it is a new metric and call SADD only once for
    * each metric. */
@@ -204,6 +181,8 @@ static int wr_config_node (oconfig_item_t *ci) /* {{{ */
   node->conn = NULL;
   node->prefix = NULL;
   node->database = 0;
+  node->max_set_size = -1;
+  node->store_rates = 1;
   pthread_mutex_init (&node->lock, /* attr = */ NULL);
 
   status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name));
@@ -238,6 +217,12 @@ static int wr_config_node (oconfig_item_t *ci) /* {{{ */
     else if (strcasecmp ("Database", child->key) == 0) {
       status = cf_util_get_int (child, &node->database);
     }
+    else if (strcasecmp ("MaxSetSize", child->key) == 0) {
+      status = cf_util_get_int (child, &node->max_set_size);
+    }
+    else if (strcasecmp ("StoreRates", child->key) == 0) {
+      status = cf_util_get_boolean (child, &node->store_rates);
+    }
     else
       WARNING ("write_redis plugin: Ignoring unknown config option \"%s\".",
           child->key);
index f0d2323..dd633d5 100644 (file)
@@ -251,6 +251,9 @@ static int za_read (void)
 
        /* Sizes */
        za_read_gauge (ksp, "size",    "cache_size", "arc");
+       za_read_gauge (ksp, "c",    "cache_size", "c");
+       za_read_gauge (ksp, "c_min",    "cache_size", "c_min");
+       za_read_gauge (ksp, "c_max",    "cache_size", "c_max");
 
        /* The "l2_size" value has disappeared from Solaris some time in
         * early 2013, and has only reappeared recently in Solaris 11.2.