Merge branch 'collectd-4.8' into collectd-4.9
authorFlorian Forster <octo@noris.net>
Wed, 21 Apr 2010 17:04:01 +0000 (19:04 +0200)
committerFlorian Forster <octo@noris.net>
Wed, 21 Apr 2010 17:04:01 +0000 (19:04 +0200)
Conflicts:
ChangeLog

1  2 
ChangeLog
src/network.c
src/plugin.c
version-gen.sh

diff --combined ChangeLog
+++ b/ChangeLog
@@@ -1,57 -1,34 +1,88 @@@
 +2010-01-14, Version 4.9.1
 +      * Documentation: Some manpage fixes.
 +      * Default config: Added sample configuration for missing plugins.
 +      * apache plugin: Fix a segmentation fault in the config handling of
 +        VerifyPeer / VerifyHost. Thanks to "plazmus" for his or her patch.
 +      * processes plugin: Fix handling of derive data sources.
 +      * rrdtool plugin: Fix a bug with random write timeouts. Due to an
 +        incorrect initialization some files may be suspended basically
 +        indefinitely. After flushing the files they were written regularly
 +        again.
 +      * routeros plugin: Use the node name for the "host" field.
 +      * Monitorus.pm: Put the plugin into the "Collectd::Plugins" namespace.
 +      * Perl bindings: Fix a warning that was printed when building
 +        debugging output.
 +
 +2009-12-21, Version 4.9.0
 +      * contextswitch plugin: The new ContextSwitch plugin gathers the
 +        number of context switches done by the CPU. Thanks to Patrik
 +        Weiskircher for the patch.
 +      * cpu plugin: Support for SMP (multiple processors) under FreeBSD has
 +        been added. Thanks to Doug MacEachern for the patch.
 +      * curl plugin: The “MeasureResponseTime” option has been added. Thanks
 +        to Aman Gupta for the patch.
 +      * df plugin: Collecting the inode count and reserved space has been
 +        added. Thanks to Patrik Weiskircher for the patch.
 +      * exec plugin: The environment variables “COLLECTD_INTERVAL” and
 +        “COLLECTD_HOSTNAME” are now set before executing the application.
 +      * Monitorus plugin: This Perl-based plugin to query statistics from
 +        mon.itor.us has been added. Thanks to Jeff Green for the patch.
 +      * netapp plugin: New plugin to collect statistics from NetApp filers.
 +        Thanks to Sven Trenkel of the noris network AG for the patch.
 +      * network plugin: Statistics collection about the plugin itself has
 +        been implemented.
 +      * openvpn plugin: Add support for more versions of the “status file”.
 +        Thanks to Marco Chiappero for the patch.
 +      * OpenVZ plugin: This Perl-based plugin to gather OpenVZ statistics
 +        has been added. Thanks to Jonathan Kolb for the patch.
 +      * ping plugin: The config options "SourceAddress" and "Device"
 +        have been added. Thanks to Sebastian Harl for the patch.
 +      * processes plugin: Collection of IO-metrics has been added. Thanks to
 +        Andrés J. Díaz for the patch.
 +      * python plugin: The new Python plugin integrates a Python interpreter
 +        into collectd and allows to execute plugins written in the scripting
 +        language. Thanks to Sven Trenkel for his work.
 +      * routeros plugin: The new RouterOS plugin queries interface and
 +        wireless registration statistics from RouterOS.
 +      * Various plugins: AIX support has been added to the cpu, disk,
 +        interface, load, memory, processes, and swap plugins. Thanks to
 +        Manuel Sanmartin for his patches.
 +      * hashed match: This match for simple load balancing and redundant
 +        storage has been added.
 +      * scale target: This target to scale (multiply) values by an arbitrary
 +        value has been added.
 +
+ 2010-04-07, Version 4.8.4
+       * Build system, various plugins: Fixes for AIX compatibility have been
+         added. Thanks to Manuel Sanmartin for his patches.
+       * Build system: Checking for "nanosleep" on old Solaris machines has
+         been fixed. Thanks to Vincent McIntyre and Sebastian Harl for
+         figuring out a way to make this work.
+       * collectd: Serialization of NANs in JSON format has been fixed.
+         Thanks to Chris Buben for pointing out the resulting syntax error.
+       * collectd: Checks whether a "sleep" returned early have been added;
+         the cases are now handled correctly. Thanks to Michael Stapelberg
+         for the patch.
+       * collectd: Continue reading files in a directory when parsing one
+         file fails.
+       * apache plugin: Collection of the number of active connections has
+         been fixed for Apache 2.*.
+       * exec plugin: Error messages have been improved. The "running" flag
+         is now cleared correctly when forking a child fails.
+       * iptables plugin: Fix a violation of aliasing rules. This resolves a
+         warning / error with new GCC versions. Thanks to Jan Engelhardt for
+         the work-around.
+       * java plugin: The Java API files are now packaged into a .jar file.
+         Thanks to Amit Gupta for his patch.
+       * network plugin: A memory leak when receiving encrypted network
+         packets has been fixed.
+       * oracle plugin: Fix checking for lost connections and reconnect in
+         this case. Thanks to Sven Trenkel for pointing out the problem.
+       * unixsock plugin: A memory leak in the "LISTVAL" command has been
+         fixed. Thanks to Peter Warasin for pointing it out.
+       * write_http plugin: Use the "any" authentication schema. This used to
+         be "digest". Thanks to Paul Sadauskas for the patch.
  2010-01-14, Version 4.8.3
        * Documentation: Some manpage fixes.
        * rrdtool plugin: Fix a bug with random write timeouts. Due to an
diff --combined src/network.c
@@@ -256,7 -256,6 +256,7 @@@ typedef struct receive_list_entry_s rec
  static int network_config_ttl = 0;
  static size_t network_config_packet_size = 1024;
  static int network_config_forward = 0;
 +static int network_config_stats = 0;
  
  static sockent_t *sending_sockets = NULL;
  
@@@ -264,7 -263,6 +264,7 @@@ static receive_list_entry_t *receive_li
  static receive_list_entry_t *receive_list_tail = NULL;
  static pthread_mutex_t       receive_list_lock = PTHREAD_MUTEX_INITIALIZER;
  static pthread_cond_t        receive_list_cond = PTHREAD_COND_INITIALIZER;
 +static uint64_t              receive_list_length = 0;
  
  static sockent_t     *listen_sockets = NULL;
  static struct pollfd *listen_sockets_pollfd = NULL;
@@@ -285,22 -283,6 +285,22 @@@ static int              send_buffer_fil
  static value_list_t     send_buffer_vl = VALUE_LIST_STATIC;
  static pthread_mutex_t  send_buffer_lock = PTHREAD_MUTEX_INITIALIZER;
  
 +/* XXX: These counters are incremented from one place only. The spot in which
 + * the values are incremented is either only reachable by one thread (the
 + * dispatch thread, for example) or locked by some lock (send_buffer_lock for
 + * example). Only if neither is true, the stats_lock is acquired. The counters
 + * are always read without holding a lock in the hope that writing 8 bytes to
 + * memory is an atomic operation. */
 +static uint64_t stats_octets_rx  = 0;
 +static uint64_t stats_octets_tx  = 0;
 +static uint64_t stats_packets_rx = 0;
 +static uint64_t stats_packets_tx = 0;
 +static uint64_t stats_values_dispatched = 0;
 +static uint64_t stats_values_not_dispatched = 0;
 +static uint64_t stats_values_sent = 0;
 +static uint64_t stats_values_not_sent = 0;
 +static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER;
 +
  /*
   * Private functions
   */
@@@ -359,13 -341,12 +359,13 @@@ static int network_dispatch_values (val
    if (!check_receive_okay (vl))
    {
  #if COLLECT_DEBUG
 -        char name[6*DATA_MAX_NAME_LEN];
 -        FORMAT_VL (name, sizeof (name), vl);
 -        name[sizeof (name) - 1] = 0;
 -        DEBUG ("network plugin: network_dispatch_values: "
 -            "NOT dispatching %s.", name);
 +    char name[6*DATA_MAX_NAME_LEN];
 +    FORMAT_VL (name, sizeof (name), vl);
 +    name[sizeof (name) - 1] = 0;
 +    DEBUG ("network plugin: network_dispatch_values: "
 +      "NOT dispatching %s.", name);
  #endif
 +    stats_values_not_dispatched++;
      return (0);
    }
  
    }
  
    plugin_dispatch_values (vl);
 +  stats_values_dispatched++;
  
    meta_data_destroy (vl->meta);
    vl->meta = NULL;
@@@ -740,11 -720,11 +740,11 @@@ static int parse_part_values (void **re
                    break;
  
                  default:
-                   sfree (pkg_types);
-                   sfree (pkg_values);
                    NOTICE ("network plugin: parse_part_values: "
                        "Don't know how to handle data source type %"PRIu8,
                        pkg_types[i]);
+                   sfree (pkg_types);
+                   sfree (pkg_values);
                    return (-1);
                } /* switch (pkg_types[i]) */
        }
@@@ -1996,7 -1976,6 +1996,7 @@@ static void *dispatch_thread (void __at
      ent = receive_list_head;
      if (ent != NULL)
        receive_list_head = ent->next;
 +    receive_list_length--;
      pthread_mutex_unlock (&receive_list_lock);
  
      /* Check whether we are supposed to exit. We do NOT check `listen_loop'
@@@ -2048,13 -2027,11 +2048,13 @@@ static int network_receive (void) /* {{
  
        receive_list_entry_t *private_list_head;
        receive_list_entry_t *private_list_tail;
 +      uint64_t              private_list_length;
  
          assert (listen_sockets_num > 0);
  
        private_list_head = NULL;
        private_list_tail = NULL;
 +      private_list_length = 0;
  
        while (listen_loop == 0)
        {
                                return (-1);
                        }
  
 +                      stats_octets_rx += ((uint64_t) buffer_len);
 +                      stats_packets_rx++;
 +
                        /* TODO: Possible performance enhancement: Do not free
                         * these entries in the dispatch thread but put them in
                         * another list, so we don't have to allocate more and
                        ent->data = malloc (network_config_packet_size);
                        if (ent->data == NULL)
                        {
 +                              sfree (ent);
                                ERROR ("network plugin: malloc failed.");
                                return (-1);
                        }
                        else
                                private_list_tail->next = ent;
                        private_list_tail = ent;
 +                      private_list_length++;
  
                        /* Do not block here. Blocking here has led to
                         * insufficient performance in the past. */
                        if (pthread_mutex_trylock (&receive_list_lock) == 0)
                        {
 +                              assert (((receive_list_head == NULL) && (receive_list_length == 0))
 +                                              || ((receive_list_head != NULL) && (receive_list_length != 0)));
 +
                                if (receive_list_head == NULL)
                                        receive_list_head = private_list_head;
                                else
                                        receive_list_tail->next = private_list_head;
                                receive_list_tail = private_list_tail;
 -
 -                              private_list_head = NULL;
 -                              private_list_tail = NULL;
 +                              receive_list_length += private_list_length;
  
                                pthread_cond_signal (&receive_list_cond);
                                pthread_mutex_unlock (&receive_list_lock);
 +
 +                              private_list_head = NULL;
 +                              private_list_tail = NULL;
 +                              private_list_length = 0;
                        }
                } /* for (listen_sockets_pollfd) */
        } /* while (listen_loop == 0) */
                else
                        receive_list_tail->next = private_list_head;
                receive_list_tail = private_list_tail;
 +              receive_list_length += private_list_length;
  
                private_list_head = NULL;
                private_list_tail = NULL;
 +              private_list_length = 0;
  
                pthread_cond_signal (&receive_list_cond);
                pthread_mutex_unlock (&receive_list_lock);
@@@ -2472,10 -2437,6 +2472,10 @@@ static void flush_buffer (void
                        send_buffer_fill);
  
        network_send_buffer (send_buffer, (size_t) send_buffer_fill);
 +
 +      stats_octets_tx += ((uint64_t) send_buffer_fill);
 +      stats_packets_tx++;
 +
        network_init_buffer ();
  }
  
@@@ -2493,11 -2454,6 +2493,11 @@@ static int network_write (const data_se
          DEBUG ("network plugin: network_write: "
              "NOT sending %s.", name);
  #endif
 +        /* Counter is not protected by another lock and may be reached by
 +         * multiple threads */
 +        pthread_mutex_lock (&stats_lock);
 +        stats_values_not_sent++;
 +        pthread_mutex_unlock (&stats_lock);
          return (0);
        }
  
                /* status == bytes added to the buffer */
                send_buffer_fill += status;
                send_buffer_ptr  += status;
 +
 +              stats_values_sent++;
        }
        else
        {
                {
                        send_buffer_fill += status;
                        send_buffer_ptr  += status;
 +
 +                      stats_values_sent++;
                }
        }
  
@@@ -2574,9 -2526,13 +2574,9 @@@ static int network_config_set_boolean (
    {
      char *str = ci->values[0].value.string;
  
 -    if ((strcasecmp ("true", str) == 0)
 -        || (strcasecmp ("yes", str) == 0)
 -        || (strcasecmp ("on", str) == 0))
 +    if (IS_TRUE (str))
        *retval = 1;
 -    else if ((strcasecmp ("false", str) == 0)
 -        || (strcasecmp ("no", str) == 0)
 -        || (strcasecmp ("off", str) == 0))
 +    else if (IS_FALSE (str))
        *retval = 0;
      else
      {
@@@ -2853,8 -2809,6 +2853,8 @@@ static int network_config (oconfig_item
        network_config_set_buffer_size (child);
      else if (strcasecmp ("Forward", child->key) == 0)
        network_config_set_boolean (child, &network_config_forward);
 +    else if (strcasecmp ("ReportStats", child->key) == 0)
 +      network_config_set_boolean (child, &network_config_stats);
      else if (strcasecmp ("CacheFlush", child->key) == 0)
        /* no op for backwards compatibility only */;
      else
@@@ -2981,83 -2935,6 +2981,83 @@@ static int network_shutdown (void
        return (0);
  } /* int network_shutdown */
  
 +static int network_stats_read (void) /* {{{ */
 +{
 +      uint64_t copy_octets_rx;
 +      uint64_t copy_octets_tx;
 +      uint64_t copy_packets_rx;
 +      uint64_t copy_packets_tx;
 +      uint64_t copy_values_dispatched;
 +      uint64_t copy_values_not_dispatched;
 +      uint64_t copy_values_sent;
 +      uint64_t copy_values_not_sent;
 +      uint64_t copy_receive_list_length;
 +      value_list_t vl = VALUE_LIST_INIT;
 +      value_t values[2];
 +
 +      copy_octets_rx = stats_octets_rx;
 +      copy_octets_tx = stats_octets_tx;
 +      copy_packets_rx = stats_packets_rx;
 +      copy_packets_tx = stats_packets_tx;
 +      copy_values_dispatched = stats_values_dispatched;
 +      copy_values_not_dispatched = stats_values_not_dispatched;
 +      copy_values_sent = stats_values_sent;
 +      copy_values_not_sent = stats_values_not_sent;
 +      copy_receive_list_length = receive_list_length;
 +
 +      /* Initialize `vl' */
 +      vl.values = values;
 +      vl.values_len = 2;
 +      vl.time = 0;
 +      vl.interval = interval_g;
 +      sstrncpy (vl.host, hostname_g, sizeof (vl.host));
 +      sstrncpy (vl.plugin, "network", sizeof (vl.plugin));
 +
 +      /* Octets received / sent */
 +      vl.values[0].counter = (counter_t) copy_octets_rx;
 +      vl.values[1].counter = (counter_t) copy_octets_tx;
 +      sstrncpy (vl.type, "if_octets", sizeof (vl.type));
 +      plugin_dispatch_values (&vl);
 +
 +      /* Packets received / send */
 +      vl.values[0].counter = (counter_t) copy_packets_rx;
 +      vl.values[1].counter = (counter_t) copy_packets_tx;
 +      sstrncpy (vl.type, "if_packets", sizeof (vl.type));
 +      plugin_dispatch_values (&vl);
 +
 +      /* Values (not) dispatched and (not) send */
 +      sstrncpy (vl.type, "total_values", sizeof (vl.type));
 +      vl.values_len = 1;
 +
 +      vl.values[0].derive = (derive_t) copy_values_dispatched;
 +      sstrncpy (vl.type_instance, "dispatch-accepted",
 +                      sizeof (vl.type_instance));
 +      plugin_dispatch_values (&vl);
 +
 +      vl.values[0].derive = (derive_t) copy_values_not_dispatched;
 +      sstrncpy (vl.type_instance, "dispatch-rejected",
 +                      sizeof (vl.type_instance));
 +      plugin_dispatch_values (&vl);
 +
 +      vl.values[0].derive = (derive_t) copy_values_sent;
 +      sstrncpy (vl.type_instance, "send-accepted",
 +                      sizeof (vl.type_instance));
 +      plugin_dispatch_values (&vl);
 +
 +      vl.values[0].derive = (derive_t) copy_values_not_sent;
 +      sstrncpy (vl.type_instance, "send-rejected",
 +                      sizeof (vl.type_instance));
 +      plugin_dispatch_values (&vl);
 +
 +      /* Receive queue length */
 +      vl.values[0].gauge = (gauge_t) copy_receive_list_length;
 +      sstrncpy (vl.type, "queue_length", sizeof (vl.type));
 +      vl.type_instance[0] = 0;
 +      plugin_dispatch_values (&vl);
 +
 +      return (0);
 +} /* }}} int network_stats_read */
 +
  static int network_init (void)
  {
        static _Bool have_init = false;
        gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
  #endif
  
 +      if (network_config_stats != 0)
 +              plugin_register_read ("network", network_stats_read);
 +
        plugin_register_shutdown ("network", network_shutdown);
  
        send_buffer = malloc (network_config_packet_size);
diff --combined src/plugin.c
@@@ -151,7 -151,7 +151,7 @@@ static void destroy_read_heap (void) /
        {
                callback_func_t *cf;
  
 -              cf = c_head_get_root (read_heap);
 +              cf = c_heap_get_root (read_heap);
                if (cf == NULL)
                        break;
  
@@@ -173,7 -173,7 +173,7 @@@ static int register_callback (llist_t *
                *list = llist_create ();
                if (*list == NULL)
                {
 -                      ERROR ("plugin: create_register_callback: "
 +                      ERROR ("plugin: register_callback: "
                                        "llist_create failed.");
                        destroy_callback (cf);
                        return (-1);
        key = strdup (name);
        if (key == NULL)
        {
 -              ERROR ("plugin: create_register_callback: strdup failed.");
 +              ERROR ("plugin: register_callback: strdup failed.");
                destroy_callback (cf);
                return (-1);
        }
                le = llentry_create (key, cf);
                if (le == NULL)
                {
 -                      ERROR ("plugin: create_register_callback: "
 +                      ERROR ("plugin: register_callback: "
                                        "llentry_create failed.");
                        free (key);
                        destroy_callback (cf);
                old_cf = le->value;
                le->value = cf;
  
 +              WARNING ("plugin: register_callback: "
 +                              "a callback named `%s' already exists - "
 +                              "overwriting the old entry!", name);
 +
                destroy_callback (old_cf);
                sfree (key);
        }
@@@ -274,7 -270,7 +274,7 @@@ static int plugin_unregister (llist_t *
   * object, but it will bitch about a shared object not having a
   * ``module_register'' symbol..
   */
 -static int plugin_load_file (char *file)
 +static int plugin_load_file (char *file, uint32_t flags)
  {
        lt_dlhandle dlh;
        void (*reg_handle) (void);
        lt_dlinit ();
        lt_dlerror (); /* clear errors */
  
 -      if ((dlh = lt_dlopen (file)) == NULL)
 +#if LIBTOOL_VERSION == 2
 +      if (flags & PLUGIN_FLAGS_GLOBAL) {
 +              lt_dladvise advise;
 +              lt_dladvise_init(&advise);
 +              lt_dladvise_global(&advise);
 +              dlh = lt_dlopenadvise(file, advise);
 +              lt_dladvise_destroy(&advise);
 +      } else {
 +              dlh = lt_dlopen (file);
 +      }
 +#else /* if LIBTOOL_VERSION == 1 */
 +      if (flags & PLUGIN_FLAGS_GLOBAL)
 +              ERROR ("plugin_load_file: The global flag is not supported, "
 +                              "libtool 2 is required for this.");
 +      dlh = lt_dlopen (file);
 +#endif
 +
 +      if (dlh == NULL)
        {
                const char *error = lt_dlerror ();
  
@@@ -341,7 -320,7 +341,7 @@@ static void *plugin_read_thread (void _
                int rc;
  
                /* Get the read function that needs to be read next. */
 -              rf = c_head_get_root (read_heap);
 +              rf = c_heap_get_root (read_heap);
                if (rf == NULL)
                {
                        struct timespec abstime;
@@@ -572,7 -551,7 +572,7 @@@ void plugin_set_dir (const char *dir
  }
  
  #define BUFSIZE 512
 -int plugin_load (const char *type)
 +int plugin_load (const char *type, uint32_t flags)
  {
        DIR  *dh;
        const char *dir;
                        continue;
                }
  
 -              if (plugin_load_file (filename) == 0)
 +              if (plugin_load_file (filename, flags) == 0)
                {
                        /* success */
                        ret = 0;
@@@ -1073,7 -1052,7 +1073,7 @@@ int plugin_read_all_once (void
        {
                read_func_t *rf;
  
 -              rf = c_head_get_root (read_heap);
 +              rf = c_heap_get_root (read_heap);
                if (rf == NULL)
                        break;
  
@@@ -1480,14 -1459,6 +1480,6 @@@ void plugin_log (int level, const char 
        va_list ap;
        llentry_t *le;
  
-       if (list_log == NULL)
-       {
-               va_start (ap, format);
-               vfprintf (stderr, format, ap);
-               va_end (ap);
-               return;
-       }
  #if !COLLECT_DEBUG
        if (level >= LOG_DEBUG)
                return;
        msg[sizeof (msg) - 1] = '\0';
        va_end (ap);
  
+       if (list_log == NULL)
+       {
+               fprintf (stderr, "%s\n", msg);
+               return;
+       }
        le = llist_head (list_log);
        while (le != NULL)
        {
diff --combined version-gen.sh
@@@ -1,6 -1,6 +1,6 @@@
  #!/bin/sh
  
- DEFAULT_VERSION="4.8.2.git"
+ DEFAULT_VERSION="4.8.4.git"
  
  VERSION="`git describe 2> /dev/null | sed -e 's/^collectd-//'`"
  
@@@ -10,8 -10,4 +10,8 @@@ f
  
  VERSION="`echo \"$VERSION\" | sed -e 's/-/./g'`"
  
 -echo -n "$VERSION"
 +if test "x`uname -s`" = "xAIX" ; then 
 +      echo "$VERSION\c"
 +else 
 +      echo -n "$VERSION"
 +fi