Merge branch 'collectd-4.3'
authorFlorian Forster <octo@crystal.wlan.home.verplant.org>
Wed, 27 Feb 2008 14:33:57 +0000 (15:33 +0100)
committerFlorian Forster <octo@crystal.wlan.home.verplant.org>
Wed, 27 Feb 2008 14:33:57 +0000 (15:33 +0100)
1  2 
src/Makefile.am
src/network.c
src/utils_cache.c

diff --combined src/Makefile.am
@@@ -30,10 -30,7 +30,10 @@@ collectd_SOURCES = collectd.c collectd.
                   utils_cache.c utils_cache.h \
                   utils_ignorelist.c utils_ignorelist.h \
                   utils_llist.c utils_llist.h \
 +                 utils_tail_match.c utils_tail_match.h \
 +                 utils_match.c utils_match.h \
                   utils_mount.c utils_mount.h \
 +                 utils_tail.c utils_tail.h \
                   utils_threshold.c utils_threshold.h \
                   types_list.c types_list.h
  collectd_CPPFLAGS = $(LTDLINCL)
@@@ -219,7 -216,9 +219,9 @@@ endi
  
  if BUILD_PLUGIN_EXEC
  pkglib_LTLIBRARIES += exec.la
- exec_la_SOURCES = exec.c utils_cmd_putval.c utils_cmd_putval.h
+ exec_la_SOURCES = exec.c \
+                 utils_cmd_putnotif.c utils_cmd_putnotif.h \
+                 utils_cmd_putval.c utils_cmd_putval.h
  exec_la_LDFLAGS = -module -avoid-version
  if BUILD_WITH_LIBPTHREAD
  exec_la_LDFLAGS += -lpthread
@@@ -566,14 -565,6 +568,14 @@@ collectd_LDADD += "-dlopen" syslog.l
  collectd_DEPENDENCIES += syslog.la
  endif
  
 +if BUILD_PLUGIN_TAIL
 +pkglib_LTLIBRARIES += tail.la
 +tail_la_SOURCES = tail.c
 +tail_la_LDFLAGS = -module -avoid-version
 +collectd_LDADD += "-dlopen" tail.la
 +collectd_DEPENDENCIES += tail.la
 +endif
 +
  if BUILD_PLUGIN_TAPE
  pkglib_LTLIBRARIES += tape.la
  tape_la_SOURCES = tape.c
@@@ -592,10 -583,7 +594,10 @@@ endi
  
  if BUILD_PLUGIN_UNIXSOCK
  pkglib_LTLIBRARIES += unixsock.la
 -unixsock_la_SOURCES = unixsock.c utils_cmd_putval.h utils_cmd_putval.c utils_cmd_putnotif.h utils_cmd_putnotif.c
 +unixsock_la_SOURCES = unixsock.c \
 +                    utils_cmd_getval.h utils_cmd_getval.c \
 +                    utils_cmd_putval.h utils_cmd_putval.c \
 +                    utils_cmd_putnotif.h utils_cmd_putnotif.c
  unixsock_la_LDFLAGS = -module -avoid-version -lpthread
  collectd_LDADD += "-dlopen" unixsock.la
  collectd_DEPENDENCIES += unixsock.la
diff --combined src/network.c
@@@ -306,37 -306,83 +306,83 @@@ static int cache_check (const char *typ
  static int write_part_values (char **ret_buffer, int *ret_buffer_len,
                const data_set_t *ds, const value_list_t *vl)
  {
-       part_values_t pv;
+       char *packet_ptr;
+       int packet_len;
+       int num_values;
+       part_header_t pkg_ph;
+       uint16_t      pkg_num_values;
+       uint8_t      *pkg_values_types;
+       value_t      *pkg_values;
+       int offset;
        int i;
  
-       i = 6 + (9 * vl->values_len);
-       if (*ret_buffer_len < i)
+       num_values = vl->values_len;
+       packet_len = sizeof (part_header_t) + sizeof (uint16_t)
+               + (num_values * sizeof (uint8_t))
+               + (num_values * sizeof (value_t));
+       if (*ret_buffer_len < packet_len)
                return (-1);
-       *ret_buffer_len -= i;
  
-       pv.head = (part_header_t *) *ret_buffer;
-       pv.num_values = (uint16_t *) (pv.head + 1);
-       pv.values_types = (uint8_t *) (pv.num_values + 1);
-       pv.values = (value_t *) (pv.values_types + vl->values_len);
-       *ret_buffer = (void *) (pv.values + vl->values_len);
+       pkg_values_types = (uint8_t *) malloc (num_values * sizeof (uint8_t));
+       if (pkg_values_types == NULL)
+       {
+               ERROR ("network plugin: write_part_values: malloc failed.");
+               return (-1);
+       }
  
-       pv.head->type = htons (TYPE_VALUES);
-       pv.head->length = htons (6 + (9 * vl->values_len));
-       *pv.num_values = htons ((uint16_t) vl->values_len);
-       
-       for (i = 0; i < vl->values_len; i++)
+       pkg_values = (value_t *) malloc (num_values * sizeof (value_t));
+       if (pkg_values == NULL)
+       {
+               free (pkg_values_types);
+               ERROR ("network plugin: write_part_values: malloc failed.");
+               return (-1);
+       }
+       pkg_ph.type = htons (TYPE_VALUES);
+       pkg_ph.length = htons (packet_len);
+       pkg_num_values = htons ((uint16_t) vl->values_len);
+       for (i = 0; i < num_values; i++)
        {
                if (ds->ds[i].type == DS_TYPE_COUNTER)
                {
-                       pv.values_types[i] = DS_TYPE_COUNTER;
-                       pv.values[i].counter = htonll (vl->values[i].counter);
+                       pkg_values_types[i] = DS_TYPE_COUNTER;
+                       pkg_values[i].counter = htonll (vl->values[i].counter);
                }
                else
                {
-                       pv.values_types[i] = DS_TYPE_GAUGE;
-                       pv.values[i].gauge = vl->values[i].gauge;
+                       pkg_values_types[i] = DS_TYPE_GAUGE;
+                       pkg_values[i].gauge = vl->values[i].gauge;
                }
-       } /* for (values) */
+       }
+       /*
+        * Use `memcpy' to write everything to the buffer, because the pointer
+        * may be unaligned and some architectures, such as SPARC, can't handle
+        * that.
+        */
+       packet_ptr = *ret_buffer;
+       offset = 0;
+       memcpy (packet_ptr + offset, &pkg_ph, sizeof (pkg_ph));
+       offset += sizeof (pkg_ph);
+       memcpy (packet_ptr + offset, &pkg_num_values, sizeof (pkg_num_values));
+       offset += sizeof (pkg_num_values);
+       memcpy (packet_ptr + offset, pkg_values_types, num_values * sizeof (uint8_t));
+       offset += num_values * sizeof (uint8_t);
+       memcpy (packet_ptr + offset, pkg_values, num_values * sizeof (value_t));
+       offset += num_values * sizeof (value_t);
+       assert (offset == packet_len);
+       *ret_buffer = packet_ptr + packet_len;
+       *ret_buffer_len -= packet_len;
+       free (pkg_values_types);
+       free (pkg_values);
  
        return (0);
  } /* int write_part_values */
  static int write_part_number (char **ret_buffer, int *ret_buffer_len,
                int type, uint64_t value)
  {
-       part_number_t pn;
+       char *packet_ptr;
+       int packet_len;
+       part_header_t pkg_head;
+       uint64_t pkg_value;
+       
+       int offset;
+       packet_len = sizeof (pkg_head) + sizeof (pkg_value);
  
-       if (*ret_buffer_len < 12)
+       if (*ret_buffer_len < packet_len)
                return (-1);
  
-       pn.head = (part_header_t *) *ret_buffer;
-       pn.value = (uint64_t *) (pn.head + 1);
+       pkg_head.type = htons (type);
+       pkg_head.length = htons (packet_len);
+       pkg_value = htonll (value);
  
-       pn.head->type = htons (type);
-       pn.head->length = htons (12);
-       *pn.value = htonll (value);
+       packet_ptr = *ret_buffer;
+       offset = 0;
+       memcpy (packet_ptr + offset, &pkg_head, sizeof (pkg_head));
+       offset += sizeof (pkg_head);
+       memcpy (packet_ptr + offset, &pkg_value, sizeof (pkg_value));
+       offset += sizeof (pkg_value);
  
-       *ret_buffer = (char *) (pn.value + 1);
-       *ret_buffer_len -= 12;
+       assert (offset == packet_len);
+       *ret_buffer = packet_ptr + packet_len;
+       *ret_buffer_len -= packet_len;
  
        return (0);
  } /* int write_part_number */
  static int write_part_string (char **ret_buffer, int *ret_buffer_len,
                int type, const char *str, int str_len)
  {
-       part_string_t ps;
-       int len;
+       char *packet_ptr;
+       int packet_len;
+       part_header_t pkg_head;
+       int offset;
  
-       len = 4 + str_len + 1;
-       if (*ret_buffer_len < len)
+       packet_len = sizeof (pkg_head) + str_len + 1;
+       if (*ret_buffer_len < packet_len)
                return (-1);
-       *ret_buffer_len -= len;
  
-       ps.head = (part_header_t *) *ret_buffer;
-       ps.value = (char *) (ps.head + 1);
+       pkg_head.type = htons (type);
+       pkg_head.length = htons (packet_len);
+       packet_ptr = *ret_buffer;
+       offset = 0;
+       memcpy (packet_ptr + offset, &pkg_head, sizeof (pkg_head));
+       offset += sizeof (pkg_head);
+       memcpy (packet_ptr + offset, str, str_len);
+       offset += str_len;
+       memset (packet_ptr + offset, '\0', 1);
+       offset += 1;
+       assert (offset == packet_len);
  
-       ps.head->type = htons ((uint16_t) type);
-       ps.head->length = htons ((uint16_t) str_len + 5);
-       if (str_len > 0)
-               memcpy (ps.value, str, str_len);
-       ps.value[str_len] = '\0';
-       *ret_buffer = (void *) (ps.value + (str_len + 1));
+       *ret_buffer = packet_ptr + packet_len;
+       *ret_buffer_len -= packet_len;
  
        return (0);
  } /* int write_part_string */
@@@ -1602,25 -1672,9 +1672,25 @@@ static int network_init (void
        return (0);
  } /* int network_init */
  
 +static int network_flush (int timeout)
 +{
 +      pthread_mutex_lock (&send_buffer_lock);
 +
 +      if (((time (NULL) - cache_flush_last) >= timeout)
 +                      && (send_buffer_fill > 0))
 +      {
 +              flush_buffer ();
 +      }
 +
 +      pthread_mutex_unlock (&send_buffer_lock);
 +
 +      return (0);
 +} /* int network_flush */
 +
  void module_register (void)
  {
        plugin_register_config ("network", network_config,
                        config_keys, config_keys_num);
        plugin_register_init   ("network", network_init);
 +      plugin_register_flush   ("network", network_flush);
  } /* void module_register */
diff --combined src/utils_cache.c
@@@ -56,6 -56,43 +56,43 @@@ static int cache_compare (const cache_e
    return (strcmp (a->name, b->name));
  } /* int cache_compare */
  
+ static cache_entry_t *cache_alloc (int values_num)
+ {
+   cache_entry_t *ce;
+   ce = (cache_entry_t *) malloc (sizeof (cache_entry_t));
+   if (ce == NULL)
+   {
+     ERROR ("utils_cache: cache_alloc: malloc failed.");
+     return (NULL);
+   }
+   memset (ce, '\0', sizeof (cache_entry_t));
+   ce->values_num = values_num;
+   ce->values_gauge = (gauge_t *) calloc (values_num, sizeof (gauge_t));
+   ce->values_counter = (counter_t *) calloc (values_num, sizeof (counter_t));
+   if ((ce->values_gauge == NULL) || (ce->values_counter == NULL))
+   {
+     sfree (ce->values_gauge);
+     sfree (ce->values_counter);
+     sfree (ce);
+     ERROR ("utils_cache: cache_alloc: calloc failed.");
+     return (NULL);
+   }
+   return (ce);
+ } /* cache_entry_t *cache_alloc */
+ static void cache_free (cache_entry_t *ce)
+ {
+   if (ce == NULL)
+     return;
+   sfree (ce->values_gauge);
+   sfree (ce->values_counter);
+   sfree (ce);
+ } /* void cache_free */
  static int uc_send_notification (const char *name)
  {
    cache_entry_t *ce = NULL;
@@@ -206,7 -243,7 +243,7 @@@ int uc_check_timeout (void
        ERROR ("uc_check_timeout: c_avl_remove (%s) failed.", keys[i]);
        }
        sfree (keys[i]);
-       sfree (ce);
+       cache_free (ce);
      }
      else /* (status > 0); ``service'' is interesting */
      {
@@@ -312,8 -349,6 +349,6 @@@ int uc_update (const data_set_t *ds, co
    else /* key is not found */
    {
      int i;
-     size_t ce_size = sizeof (cache_entry_t)
-       + ds->ds_num * (sizeof (counter_t) + sizeof (gauge_t));
      char *key;
      
      key = strdup (name);
        return (-1);
      }
  
-     ce = (cache_entry_t *) malloc (ce_size);
+     ce = cache_alloc (ds->ds_num);
      if (ce == NULL)
      {
        pthread_mutex_unlock (&cache_lock);
-       ERROR ("uc_insert: malloc (%u) failed.", (unsigned int) ce_size);
+       ERROR ("uc_insert: cache_alloc (%i) failed.", ds->ds_num);
        return (-1);
      }
  
-     memset (ce, '\0', ce_size);
-     strncpy (ce->name, name, sizeof (ce->name));
-     ce->name[sizeof (ce->name) - 1] = '\0';
-     ce->values_num = ds->ds_num;
-     ce->values_gauge = (gauge_t *) (ce + 1);
-     ce->values_counter = (counter_t *) (ce->values_gauge + ce->values_num);
+     sstrncpy (ce->name, name, sizeof (ce->name));
  
      for (i = 0; i < ds->ds_num; i++)
      {
    return (0);
  } /* int uc_insert */
  
 -gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl)
 +int uc_get_rate_by_name (const char *name, gauge_t **ret_values, size_t *ret_values_num)
  {
 -  char name[6 * DATA_MAX_NAME_LEN];
    gauge_t *ret = NULL;
 +  size_t ret_num = 0;
    cache_entry_t *ce = NULL;
 -
 -  if (FORMAT_VL (name, sizeof (name), vl, ds) != 0)
 -  {
 -    ERROR ("uc_insert: FORMAT_VL failed.");
 -    return (NULL);
 -  }
 +  int status = 0;
  
    pthread_mutex_lock (&cache_lock);
  
    if (c_avl_get (cache_tree, name, (void *) &ce) == 0)
    {
      assert (ce != NULL);
 -    assert (ce->values_num == ds->ds_num);
  
 -    ret = (gauge_t *) malloc (ce->values_num * sizeof (gauge_t));
 +    ret_num = ce->values_num;
 +    ret = (gauge_t *) malloc (ret_num * sizeof (gauge_t));
      if (ret == NULL)
      {
 -      ERROR ("uc_get_rate: malloc failed.");
 +      ERROR ("utils_cache: uc_get_rate_by_name: malloc failed.");
 +      status = -1;
      }
      else
      {
 -      memcpy (ret, ce->values_gauge, ce->values_num * sizeof (gauge_t));
 +      memcpy (ret, ce->values_gauge, ret_num * sizeof (gauge_t));
      }
    }
 +  else
 +  {
 +    DEBUG ("utils_cache: uc_get_rate_by_name: No such value: %s", name);
 +    status = -1;
 +  }
  
    pthread_mutex_unlock (&cache_lock);
  
 +  if (status == 0)
 +  {
 +    *ret_values = ret;
 +    *ret_values_num = ret_num;
 +  }
 +
 +  return (status);
 +} /* gauge_t *uc_get_rate_by_name */
 +
 +gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl)
 +{
 +  char name[6 * DATA_MAX_NAME_LEN];
 +  gauge_t *ret = NULL;
 +  size_t ret_num = 0;
 +  int status;
 +
 +  if (FORMAT_VL (name, sizeof (name), vl, ds) != 0)
 +  {
 +    ERROR ("uc_insert: FORMAT_VL failed.");
 +    return (NULL);
 +  }
 +
 +  status = uc_get_rate_by_name (name, &ret, &ret_num);
 +  if (status != 0)
 +    return (NULL);
 +
 +  /* This is important - the caller has no other way of knowing how many
 +   * values are returned. */
 +  if (ret_num != ds->ds_num)
 +  {
 +    ERROR ("utils_cache: uc_get_rate: ds[%s] has %i values, "
 +      "but uc_get_rate_by_name returned %i.",
 +      ds->type, ds->ds_num, ret_num);
 +    sfree (ret);
 +    return (NULL);
 +  }
 +
    return (ret);
  } /* gauge_t *uc_get_rate */