Merge branch 'collectd-4.3' into collectd-4.4
authorFlorian Forster <octo@huhu.verplant.org>
Wed, 30 Apr 2008 08:59:32 +0000 (10:59 +0200)
committerFlorian Forster <octo@huhu.verplant.org>
Wed, 30 Apr 2008 08:59:32 +0000 (10:59 +0200)
1  2 
bindings/perl/Collectd.pm
configure.in
src/collectd.c
src/perl.c

@@@ -42,9 -42,6 +42,9 @@@ our %EXPORT_TAGS = 
                        plugin_register
                        plugin_unregister
                        plugin_dispatch_values
 +                      plugin_flush
 +                      plugin_flush_one
 +                      plugin_flush_all
                        plugin_dispatch_notification
                        plugin_log
        ) ],
@@@ -55,7 -52,6 +55,7 @@@
                        TYPE_SHUTDOWN
                        TYPE_LOG
                        TYPE_NOTIF
 +                      TYPE_FLUSH
                        TYPE_DATASET
        ) ],
        'ds_types' => [ qw(
@@@ -105,8 -101,7 +105,8 @@@ my %types = 
        TYPE_WRITE,    "write",
        TYPE_SHUTDOWN, "shutdown",
        TYPE_LOG,      "log",
 -      TYPE_NOTIF,    "notify"
 +      TYPE_NOTIF,    "notify",
 +      TYPE_FLUSH,    "flush"
  );
  
  foreach my $type (keys %types) {
@@@ -251,7 -246,7 +251,7 @@@ sub plugin_register 
  
                my %p : shared;
  
-               if ($data !~ m/^$pkg/) {
+               if ($data !~ m/^$pkg\:\:/) {
                        $data = $pkg . "::" . $data;
                }
  
@@@ -295,34 -290,6 +295,34 @@@ sub plugin_unregister 
        }
  }
  
 +sub plugin_flush {
 +      my %args = @_;
 +
 +      my $timeout = -1;
 +
 +      DEBUG ("Collectd::plugin_flush:"
 +              . (defined ($args{'timeout'}) ? " timeout = $args{'timeout'}" : "")
 +              . (defined ($args{'plugins'}) ? " plugins = $args{'plugins'}" : ""));
 +
 +      if (defined ($args{'timeout'}) && ($args{'timeout'} > 0)) {
 +              $timeout = $args{'timeout'};
 +      }
 +
 +      if (! defined $args{'plugins'}) {
 +              plugin_flush_all ($timeout);
 +      }
 +      else {
 +              if ("ARRAY" eq ref ($args{'plugins'})) {
 +                      foreach my $plugin (@{$args{'plugins'}}) {
 +                              plugin_flush_one ($timeout, $plugin);
 +                      }
 +              }
 +              else {
 +                      plugin_flush_one ($timeout, $args{'plugins'});
 +              }
 +      }
 +}
 +
  1;
  
  # vim: set sw=4 ts=4 tw=78 noexpandtab :
diff --combined configure.in
@@@ -1095,24 -1095,21 +1095,21 @@@ AM_CONDITIONAL(BUILD_WITH_LIBCURL, tes
  ### END of check for libcurl ###
  
  with_libiokit="no"
- collectd_libiokit=0
  AC_CHECK_LIB(IOKit, IOServiceGetMatchingServices,
  [
        with_libiokit="yes"
-       collectd_libiokit=1
- ],
+ ], 
  [
        with_libiokit="no"
-       collectd_libiokit=0
  ])
- AC_DEFINE_UNQUOTED(COLLECT_LIBIOKIT, [$collect_libiokit], [Wether or not to use the IOKit library])
  AM_CONDITIONAL(BUILD_WITH_LIBIOKIT, test "x$with_libiokit" = "xyes")
  
  with_libstatgrab_cflags=""
  with_libstatgrab_ldflags=""
  AC_ARG_WITH(libstatgrab, [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [Path to libstatgrab.])],
  [
-       if test "x$withval" != "xno" -a "x$withval" != "xyes"
+       if test "x$withval" != "xno" \
+               && test "x$withval" != "xyes"
        then
                with_libstatgrab_cflags="-I$withval/include"
                with_libstatgrab_ldflags="-L$withval/lib"
        fi
  ],
  [
-       if test "x$ac_system" == "xunknown"
+       if test "x$ac_system" = "xunknown"
        then
                with_libstatgrab="yes"
        else
  AM_CONDITIONAL(BUILD_WITH_LIBSTATGRAB, test "x$with_libstatgrab" = "xyes")
  if test "x$with_libstatgrab" = "xyes"
  then
+   AC_DEFINE(HAVE_LIBSTATGRAB, 1, [Define to 1 if you have the 'statgrab' library (-lstatgrab)])
    BUILD_WITH_LIBSTATGRAB_CFLAGS="$with_libstatgrab_cflags"
    BUILD_WITH_LIBSTATGRAB_LDFLAGS="$with_libstatgrab_ldflags"
    AC_SUBST(BUILD_WITH_LIBSTATGRAB_CFLAGS)
  fi
  AM_CONDITIONAL(BUILD_WITH_LIBNETLINK, test "x$with_libnetlink" = "xyes")
  
 +with_libopenipmipthread="yes"
 +with_libopenipmipthread_cflags=""
 +with_libopenipmipthread_libs=""
 +
 +AC_MSG_CHECKING([for pkg-config])
 +temp_result="no"
 +if test "x$PKG_CONFIG" = "x"
 +then
 +      with_libopenipmipthread="no"
 +      temp_result="no"
 +else
 +      temp_result="$PKG_CONFIG"
 +fi
 +AC_MSG_RESULT([$temp_result])
 +
 +if test "x$with_libopenipmipthread" = "xyes"
 +then
 +      AC_MSG_CHECKING([for libOpenIPMIpthread])
 +      $PKG_CONFIG --exists OpenIPMIpthread 2>/dev/null
 +      if test "$?" != "0"
 +      then
 +              with_libopenipmipthread="no ($PKG_CONFIG doesn't know OpenIPMIpthread)"
 +      fi
 +      AC_MSG_RESULT([$with_libopenipmipthread])
 +fi
 +
 +if test "x$with_libopenipmipthread" = "xyes"
 +then
 +      AC_MSG_CHECKING([for libOpenIPMIpthread CFLAGS])
 +      temp_result="`$PKG_CONFIG --cflags OpenIPMIpthread`"
 +      if test "$?" = "0"
 +      then
 +              with_libopenipmipthread_cflags="$temp_result"
 +      else
 +              with_libopenipmipthread="no ($PKG_CONFIG --cflags OpenIPMIpthread failed)"
 +              temp_result="$PKG_CONFIG --cflags OpenIPMIpthread failed"
 +      fi
 +      AC_MSG_RESULT([$temp_result])
 +fi
 +
 +if test "x$with_libopenipmipthread" = "xyes"
 +then
 +      AC_MSG_CHECKING([for libOpenIPMIpthread LDFLAGS])
 +      temp_result="`$PKG_CONFIG --libs OpenIPMIpthread`"
 +      if test "$?" = "0"
 +      then
 +              with_libopenipmipthread_ldflags="$temp_result"
 +      else
 +              with_libopenipmipthread="no ($PKG_CONFIG --libs OpenIPMIpthread failed)"
 +              temp_result="$PKG_CONFIG --libs OpenIPMIpthread failed"
 +      fi
 +      AC_MSG_RESULT([$temp_result])
 +fi
 +
 +if test "x$with_libopenipmipthread" = "xyes"
 +then
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      CPPFLAGS="$CPPFLAGS $with_libopenipmipthread_cflags"
 +
 +      AC_CHECK_HEADERS(OpenIPMI/ipmi_smi.h,
 +                       [with_libopenipmipthread="yes"],
 +                       [with_libopenipmipthread="no (OpenIPMI/ipmi_smi.h not found)"],
 +[#include <OpenIPMI/ipmiif.h>
 +#include <OpenIPMI/ipmi_err.h>
 +#include <OpenIPMI/ipmi_posix.h>
 +#include <OpenIPMI/ipmi_conn.h>
 +])
 +
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +fi
 +
 +if test "x$with_libopenipmipthread" = "xyes"
 +then
 +      BUILD_WITH_OPENIPMI_CFLAGS="$with_libopenipmipthread_cflags"
 +      BUILD_WITH_OPENIPMI_LIBS="$with_libopenipmipthread_ldflags"
 +      AC_SUBST(BUILD_WITH_OPENIPMI_CFLAGS)
 +      AC_SUBST(BUILD_WITH_OPENIPMI_LIBS)
 +fi
 +
  dnl Check for libvirt and libxml2 libraries.
  with_libxml2="no (pkg-config isn't available)"
  with_libxml2_cflags=""
@@@ -2044,6 -1963,7 +2042,6 @@@ with_libxml2_ldflags="
  with_libvirt="no (pkg-config isn't available)"
  with_libvirt_cflags=""
  with_libvirt_ldflags=""
 -PKG_PROG_PKG_CONFIG
  if test "x$PKG_CONFIG" != "x"
  then
        pkg-config --exists 'libxml-2.0' 2>/dev/null
@@@ -2258,7 -2178,6 +2256,7 @@@ AC_COLLECTD([debug],     [enable],  [fe
  AC_COLLECTD([daemon],    [disable], [feature], [daemon mode])
  AC_COLLECTD([getifaddrs],[enable],  [feature], [getifaddrs under Linux])
  
 +plugin_ascent="no"
  plugin_battery="no"
  plugin_cpu="no"
  plugin_cpufreq="no"
@@@ -2266,7 -2185,6 +2264,7 @@@ plugin_df="no
  plugin_disk="no"
  plugin_entropy="no"
  plugin_interface="no"
 +plugin_ipmi="no"
  plugin_ipvs="no"
  plugin_irq="no"
  plugin_libvirt="no"
@@@ -2281,7 -2199,6 +2279,7 @@@ plugin_swap="no
  plugin_tape="no"
  plugin_tcpconns="no"
  plugin_users="no"
 +plugin_vmem="no"
  plugin_vserver="no"
  plugin_wireless="no"
  
@@@ -2302,7 -2219,6 +2300,7 @@@ the
        plugin_serial="yes"
        plugin_swap="yes"
        plugin_tcpconns="yes"
 +      plugin_vmem="yes"
        plugin_vserver="yes"
        plugin_wireless="yes"
  
        plugin_swap="yes"
  fi
  
 +if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"
 +then
 +      plugin_ascent="yes"
 +fi
 +
 +if test "x$with_libopenipmipthread" = "xyes"
 +then
 +      plugin_ipmi="yes"
 +fi
 +
  if test "x$have_processor_info" = "xyes"
  then
        plugin_cpu="yes"
@@@ -2427,7 -2333,6 +2425,7 @@@ collectd plugins:]
  AC_PLUGIN([apache],      [$with_libcurl],      [Apache httpd statistics])
  AC_PLUGIN([apcups],      [yes],                [Statistics of UPSes by APC])
  AC_PLUGIN([apple_sensors], [$with_libiokit],   [Apple's hardware sensors])
 +AC_PLUGIN([ascent],      [$plugin_ascent],     [AscentEmu player statistics])
  AC_PLUGIN([battery],     [$plugin_battery],    [Battery statistics])
  AC_PLUGIN([cpu],         [$plugin_cpu],        [CPU usage statistics])
  AC_PLUGIN([cpufreq],     [$plugin_cpufreq],    [CPU frequency statistics])
@@@ -2441,7 -2346,6 +2439,7 @@@ AC_PLUGIN([exec],        [yes]
  AC_PLUGIN([hddtemp],     [yes],                [Query hddtempd])
  AC_PLUGIN([interface],   [$plugin_interface],  [Interface traffic statistics])
  AC_PLUGIN([iptables],    [$with_libiptc],      [IPTables rule counters])
 +AC_PLUGIN([ipmi],        [$plugin_ipmi],       [IPMI sensor statistics])
  AC_PLUGIN([ipvs],        [$plugin_ipvs],       [IPVS connection statistics])
  AC_PLUGIN([irq],         [$plugin_irq],        [IRQ statistics])
  AC_PLUGIN([libvirt],     [$plugin_libvirt],    [Virtual machine statistics])
@@@ -2460,7 -2364,6 +2458,7 @@@ AC_PLUGIN([ntpd],        [yes]
  AC_PLUGIN([nut],         [$with_libupsclient], [Network UPS tools statistics])
  AC_PLUGIN([perl],        [$plugin_perl],       [Embed a Perl interpreter])
  AC_PLUGIN([ping],        [$with_liboping],     [Network latency statistics])
 +AC_PLUGIN([powerdns],    [yes],                [PowerDNS statistics])
  AC_PLUGIN([processes],   [$plugin_processes],  [Process statistics])
  AC_PLUGIN([rrdtool],     [$with_rrdtool],      [RRDTool output plugin])
  AC_PLUGIN([sensors],     [$with_lm_sensors],   [lm_sensors statistics])
@@@ -2468,14 -2371,11 +2466,14 @@@ AC_PLUGIN([serial],      [$plugin_seria
  AC_PLUGIN([snmp],        [$with_libnetsnmp],   [SNMP querying plugin])
  AC_PLUGIN([swap],        [$plugin_swap],       [Swap usage statistics])
  AC_PLUGIN([syslog],      [$have_syslog],       [Syslog logging plugin])
 +AC_PLUGIN([tail],        [yes],                [Parsing of logfiles])
  AC_PLUGIN([tape],        [$plugin_tape],       [Tape drive statistics])
  AC_PLUGIN([tcpconns],    [$plugin_tcpconns],   [TCP connection statistics])
 +AC_PLUGIN([teamspeak2],  [yes],                [TeamSpeak2 server statistics])
  AC_PLUGIN([unixsock],    [yes],                [Unixsock communication plugin])
  AC_PLUGIN([users],       [$plugin_users],      [User statistics])
  AC_PLUGIN([uuid],        [yes],                [UUID as hostname plugin])
 +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([xmms],        [$with_libxmms],      [XMMS statistics])
@@@ -2553,7 -2453,6 +2551,7 @@@ Configuration
      libnetlink  . . . . $with_libnetlink
      libnetsnmp  . . . . $with_libnetsnmp
      liboconfig  . . . . $with_liboconfig
 +    libopenipmi . . . . $with_libopenipmipthread
      liboping  . . . . . $with_liboping
      libpcap . . . . . . $with_libpcap
      libperl . . . . . . $with_libperl
      apache  . . . . . . $enable_apache
      apcups  . . . . . . $enable_apcups
      apple_sensors . . . $enable_apple_sensors
 +    ascent  . . . . . . $enable_ascent
      battery . . . . . . $enable_battery
      cpu . . . . . . . . $enable_cpu
      cpufreq . . . . . . $enable_cpufreq
      hddtemp . . . . . . $enable_hddtemp
      interface . . . . . $enable_interface
      iptables  . . . . . $enable_iptables
 +    ipmi  . . . . . . . $enable_ipmi
      ipvs  . . . . . . . $enable_ipvs
      irq . . . . . . . . $enable_irq
      libvirt . . . . . . $enable_libvirt
      nut . . . . . . . . $enable_nut
      perl  . . . . . . . $enable_perl
      ping  . . . . . . . $enable_ping
 +    powerdns  . . . . . $enable_powerdns
      processes . . . . . $enable_processes
      rrdtool . . . . . . $enable_rrdtool
      sensors . . . . . . $enable_sensors
      snmp  . . . . . . . $enable_snmp
      swap  . . . . . . . $enable_swap
      syslog  . . . . . . $enable_syslog
 +    tail  . . . . . . . $enable_tail
      tape  . . . . . . . $enable_tape
      tcpconns  . . . . . $enable_tcpconns
 +    teamspeak2  . . . . $enable_teamspeak2
      unixsock  . . . . . $enable_unixsock
      users . . . . . . . $enable_users
      uuid  . . . . . . . $enable_uuid
 +    vmem  . . . . . . . $enable_vmem
      vserver . . . . . . $enable_vserver
      wireless  . . . . . $enable_wireless
      xmms  . . . . . . . $enable_xmms
diff --combined src/collectd.c
  #include <sys/socket.h>
  #include <netdb.h>
  
 +#include <pthread.h>
 +
  #include "plugin.h"
  #include "configfile.h"
  
+ #if HAVE_STATGRAB_H
+ # include <statgrab.h>
+ #endif
  /*
   * Global variables
   */
@@@ -43,37 -45,16 +47,37 @@@ kstat_ctl_t *kc
  
  static int loop = 0;
  
 -static void sigIntHandler (int signal)
 +static void *do_flush (void *arg)
 +{
 +      INFO ("Flushing all data.");
 +      plugin_flush_all (-1);
 +      INFO ("Finished flushing all data.");
 +      pthread_exit (NULL);
 +      return NULL;
 +}
 +
 +static void sig_int_handler (int signal)
  {
        loop++;
  }
  
 -static void sigTermHandler (int signal)
 +static void sig_term_handler (int signal)
  {
        loop++;
  }
  
 +static void sig_usr1_handler (int signal)
 +{
 +      pthread_t      thread;
 +      pthread_attr_t attr;
 +
 +      /* flushing the data might take a while,
 +       * so it should be done asynchronously */
 +      pthread_attr_init (&attr);
 +      pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
 +      pthread_create (&thread, &attr, do_flush, NULL);
 +}
 +
  static int init_hostname (void)
  {
        const char *str;
@@@ -250,13 -231,11 +254,13 @@@ static void exit_usage (void
                        "  General:\n"
                        "    -C <file>       Configuration file.\n"
                        "                    Default: "CONFIGFILE"\n"
 +                      "    -t              Test config and exit.\n"
                        "    -P <file>       PID-file.\n"
                        "                    Default: "PIDFILE"\n"
  #if COLLECT_DAEMON
                        "    -f              Don't fork to the background.\n"
  #endif
 +                      "    -h              Display help (this message)\n"
                        "\nBuiltin defaults:\n"
                        "  Config-File       "CONFIGFILE"\n"
                        "  PID-File          "PIDFILE"\n"
@@@ -390,9 -369,8 +394,9 @@@ static int pidfile_remove (void
  
  int main (int argc, char **argv)
  {
 -      struct sigaction sigIntAction;
 -      struct sigaction sigTermAction;
 +      struct sigaction sig_int_action;
 +      struct sigaction sig_term_action;
 +      struct sigaction sig_usr1_action;
        char *configfile = CONFIGFILE;
        int test_config  = 0;
        const char *basedir;
        /*
         * install signal handlers
         */
 -      memset (&sigIntAction, '\0', sizeof (sigIntAction));
 -      sigIntAction.sa_handler = sigIntHandler;
 -      sigaction (SIGINT, &sigIntAction, NULL);
 +      memset (&sig_int_action, '\0', sizeof (sig_int_action));
 +      sig_int_action.sa_handler = sig_int_handler;
 +      if (0 != sigaction (SIGINT, &sig_int_action, NULL)) {
 +              char errbuf[1024];
 +              ERROR ("Error: Failed to install a signal handler for signal INT: %s",
 +                              sstrerror (errno, errbuf, sizeof (errbuf)));
 +              return (1);
 +      }
 +
 +      memset (&sig_term_action, '\0', sizeof (sig_term_action));
 +      sig_term_action.sa_handler = sig_term_handler;
 +      if (0 != sigaction (SIGTERM, &sig_term_action, NULL)) {
 +              char errbuf[1024];
 +              ERROR ("Error: Failed to install a signal handler for signal TERM: %s",
 +                              sstrerror (errno, errbuf, sizeof (errbuf)));
 +              return (1);
 +      }
  
 -      memset (&sigTermAction, '\0', sizeof (sigTermAction));
 -      sigTermAction.sa_handler = sigTermHandler;
 -      sigaction (SIGTERM, &sigTermAction, NULL);
 +      memset (&sig_usr1_action, '\0', sizeof (sig_usr1_action));
 +      sig_usr1_action.sa_handler = sig_usr1_handler;
 +      if (0 != sigaction (SIGUSR1, &sig_usr1_action, NULL)) {
 +              char errbuf[1024];
 +              ERROR ("Error: Failed to install a signal handler for signal USR1: %s",
 +                              sstrerror (errno, errbuf, sizeof (errbuf)));
 +              return (1);
 +      }
  
        /*
         * run the actual loops
diff --combined src/perl.c
@@@ -61,9 -61,8 +61,9 @@@
  #define PLUGIN_SHUTDOWN 3
  #define PLUGIN_LOG      4
  #define PLUGIN_NOTIF    5
 +#define PLUGIN_FLUSH    6
  
 -#define PLUGIN_TYPES    6
 +#define PLUGIN_TYPES    7
  
  #define PLUGIN_DATASET  255
  
@@@ -78,8 -77,6 +78,8 @@@ void boot_DynaLoader (PerlInterpreter *
  static XS (Collectd_plugin_register_ds);
  static XS (Collectd_plugin_unregister_ds);
  static XS (Collectd_plugin_dispatch_values);
 +static XS (Collectd_plugin_flush_one);
 +static XS (Collectd_plugin_flush_all);
  static XS (Collectd_plugin_dispatch_notification);
  static XS (Collectd_plugin_log);
  static XS (Collectd_call_by_name);
@@@ -133,8 -130,6 +133,8 @@@ static struct 
        { "Collectd::plugin_register_data_set",   Collectd_plugin_register_ds },
        { "Collectd::plugin_unregister_data_set", Collectd_plugin_unregister_ds },
        { "Collectd::plugin_dispatch_values",     Collectd_plugin_dispatch_values },
 +      { "Collectd::plugin_flush_one",           Collectd_plugin_flush_one },
 +      { "Collectd::plugin_flush_all",           Collectd_plugin_flush_all },
        { "Collectd::plugin_dispatch_notification",
                Collectd_plugin_dispatch_notification },
        { "Collectd::plugin_log",                 Collectd_plugin_log },
@@@ -153,7 -148,6 +153,7 @@@ struct 
        { "Collectd::TYPE_SHUTDOWN",   PLUGIN_SHUTDOWN },
        { "Collectd::TYPE_LOG",        PLUGIN_LOG },
        { "Collectd::TYPE_NOTIF",      PLUGIN_NOTIF },
 +      { "Collectd::TYPE_FLUSH",      PLUGIN_FLUSH },
        { "Collectd::TYPE_DATASET",    PLUGIN_DATASET },
        { "Collectd::DS_TYPE_COUNTER", DS_TYPE_COUNTER },
        { "Collectd::DS_TYPE_GAUGE",   DS_TYPE_GAUGE },
@@@ -761,12 -755,6 +761,12 @@@ static int pplugin_call_all (pTHX_ int 
  
                XPUSHs (sv_2mortal (newRV_noinc ((SV *)notif)));
        }
 +      else if (PLUGIN_FLUSH == type) {
 +              /*
 +               * $_[0] = $timeout;
 +               */
 +              XPUSHs (sv_2mortal (newSViv (va_arg (ap, int))));
 +      }
  
        PUTBACK;
  
@@@ -903,54 -891,6 +903,54 @@@ static XS (Collectd_plugin_dispatch_val
  } /* static XS (Collectd_plugin_dispatch_values) */
  
  /*
 + * Collectd::plugin_flush_one (timeout, name).
 + *
 + * timeout:
 + *   timeout to use when flushing the data
 + *
 + * name:
 + *   name of the plugin to flush
 + */
 +static XS (Collectd_plugin_flush_one)
 +{
 +      dXSARGS;
 +
 +      if (2 != items) {
 +              log_err ("Usage: Collectd::plugin_flush_one(timeout, name)");
 +              XSRETURN_EMPTY;
 +      }
 +
 +      log_debug ("Collectd::plugin_flush_one: timeout = %i, name = \"%s\"",
 +                      (int)SvIV (ST (0)), SvPV_nolen (ST (1)));
 +
 +      if (0 == plugin_flush_one ((int)SvIV (ST (0)), SvPV_nolen (ST (1))))
 +              XSRETURN_YES;
 +      else
 +              XSRETURN_EMPTY;
 +} /* static XS (Collectd_plugin_flush_one) */
 +
 +/*
 + * Collectd::plugin_flush_all (timeout).
 + *
 + * timeout:
 + *   timeout to use when flushing the data
 + */
 +static XS (Collectd_plugin_flush_all)
 +{
 +      dXSARGS;
 +
 +      if (1 != items) {
 +              log_err ("Usage: Collectd::plugin_flush_all(timeout)");
 +              XSRETURN_EMPTY;
 +      }
 +
 +      log_debug ("Collectd::plugin_flush_all: timeout = %i", (int)SvIV (ST (0)));
 +
 +      plugin_flush_all ((int)SvIV (ST (0)));
 +      XSRETURN_YES;
 +} /* static XS (Collectd_plugin_flush_all) */
 +
 +/*
   * Collectd::plugin_dispatch_notification (notif).
   *
   * notif:
@@@ -1255,25 -1195,6 +1255,25 @@@ static int perl_notify (const notificat
        return pplugin_call_all (aTHX_ PLUGIN_NOTIF, notif);
  } /* static int perl_notify (const notification_t *) */
  
 +static int perl_flush (const int timeout)
 +{
 +      dTHX;
 +
 +      if (NULL == perl_threads)
 +              return 0;
 +
 +      if (NULL == aTHX) {
 +              c_ithread_t *t = NULL;
 +
 +              pthread_mutex_lock (&perl_threads->mutex);
 +              t = c_ithread_create (perl_threads->head->interp);
 +              pthread_mutex_unlock (&perl_threads->mutex);
 +
 +              aTHX = t->interp;
 +      }
 +      return pplugin_call_all (aTHX_ PLUGIN_FLUSH, timeout);
 +} /* static int perl_flush (const int) */
 +
  static int perl_shutdown (void)
  {
        c_ithread_t *t = NULL;
        plugin_unregister_init ("perl");
        plugin_unregister_read ("perl");
        plugin_unregister_write ("perl");
 +      plugin_unregister_flush ("perl");
  
        ret = pplugin_call_all (aTHX_ PLUGIN_SHUTDOWN);
  
@@@ -1444,6 -1364,11 +1444,11 @@@ static int init_pi (int argc, char **ar
                exit (1);
        }
  
+ #ifdef __FreeBSD__
+       /* On FreeBSD, PERL_SYS_INIT3 expands to some expression which
+        * triggers a "value computed is not used" warning by gcc. */
+       (void)
+ #endif
        PERL_SYS_INIT3 (&argc, &argv, &environ);
  
        perl_threads = (c_ithread_list_t *)smalloc (sizeof (c_ithread_list_t));
        plugin_register_read ("perl", perl_read);
  
        plugin_register_write ("perl", perl_write);
 +      plugin_register_flush ("perl", perl_flush);
        plugin_register_shutdown ("perl", perl_shutdown);
        return 0;
  } /* static int init_pi (const char **, const int) */