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)
src/Makefile.am
src/network.c
src/utils_cache.c

index da9ca9b..48a2013 100644 (file)
@@ -219,7 +219,9 @@ endif
 
 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
index 618bf52..80e5a53 100644 (file)
@@ -306,37 +306,83 @@ static int cache_check (const char *type, const value_list_t *vl)
 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 */
@@ -344,20 +390,34 @@ static int write_part_values (char **ret_buffer, int *ret_buffer_len,
 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 */
@@ -365,23 +425,33 @@ static int write_part_number (char **ret_buffer, int *ret_buffer_len,
 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 */
index e7ab03c..ad8fb19 100644 (file)
@@ -56,6 +56,43 @@ static int cache_compare (const cache_entry_t *a, const cache_entry_t *b)
   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 @@ 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 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
   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);
@@ -324,22 +359,15 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
       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++)
     {