gmond plugin: Check return value of sendto(2).
[collectd.git] / src / gmond.c
index 2ffc42a..629a9ad 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/gmond.c
- * Copyright (C) 2009  Florian octo Forster
+ * Copyright (C) 2009,2010  Florian octo Forster
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -16,7 +16,7 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  *
  * Authors:
- *   Florian octo Forster <octo at verplant.org>
+ *   Florian octo Forster <octo at collectd.org>
  **/
 
 #include "collectd.h"
@@ -217,13 +217,13 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
   struct addrinfo *ai_ptr;
   int              ai_return;
 
-  socket_entry_t *sockets;
-  size_t          sockets_num;
+  socket_entry_t *sockets = NULL;
+  size_t          sockets_num = 0;
 
   int status;
-    
-  sockets     = *ret_sockets;
-  sockets_num = *ret_sockets_num;
+
+  if (*ret_sockets != NULL)
+    return (EINVAL);
 
   memset (&ai_hints, 0, sizeof (ai_hints));
   ai_hints.ai_flags    = 0;
@@ -286,8 +286,14 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
     {
       int yes = 1;
 
-      setsockopt (sockets[sockets_num].fd, SOL_SOCKET, SO_REUSEADDR,
+      status = setsockopt (sockets[sockets_num].fd, SOL_SOCKET, SO_REUSEADDR,
           (void *) &yes, sizeof (yes));
+      if (status != 0)
+      {
+        char errbuf[1024];
+        WARNING ("gmond plugin: setsockopt(2) failed: %s",
+                 sstrerror (errno, errbuf, sizeof (errbuf)));
+      }
     }
 
     status = bind (sockets[sockets_num].fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
@@ -355,8 +361,11 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
 
   freeaddrinfo (ai_list);
 
-  if ((*ret_sockets_num) >= sockets_num)
+  if (sockets_num == 0)
+  {
+    sfree (sockets);
     return (-1);
+  }
 
   *ret_sockets = sockets;
   *ret_sockets_num = sockets_num;
@@ -402,10 +411,19 @@ static int request_meta_data (const char *host, const char *name) /* {{{ */
 
   pthread_mutex_lock (&mc_send_sockets_lock);
   for (i = 0; i < mc_send_sockets_num; i++)
-    sendto (mc_send_sockets[i].fd, buffer, (size_t) buffer_size,
+  {
+    ssize_t status = sendto (mc_send_sockets[i].fd, buffer, (size_t) buffer_size,
         /* flags = */ 0,
         (struct sockaddr *) &mc_send_sockets[i].addr,
         mc_send_sockets[i].addrlen);
+    if (status == -1)
+    {
+      char errbuf[1024];
+      ERROR ("gmond plugin: sendto(2) failed: %s",
+             sstrerror (errno, errbuf, sizeof (errbuf)));
+      continue;
+    }
+  }
   pthread_mutex_unlock (&mc_send_sockets_lock);
 
   sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.host);
@@ -545,6 +563,8 @@ static int staging_entry_update (const char *host, const char *name, /* {{{ */
     se->vl.values[ds_index].derive += value.derive;
   else if (ds_type == DS_TYPE_ABSOLUTE)
     se->vl.values[ds_index].absolute = value.absolute;
+  else
+    assert (23 == 42);
 
   se->flags |= (0x01 << ds_index);
 
@@ -593,32 +613,24 @@ static int mc_handle_value_msg (Ganglia_value_msg *msg) /* {{{ */
     case gmetric_string:
     {
       Ganglia_gmetric_string msg_string;
-      char *endptr;
+      int status;
 
       msg_string = msg->Ganglia_value_msg_u.gstr;
 
       host = msg_string.metric_id.host;
       name = msg_string.metric_id.name;
 
-      endptr = NULL;
-      errno = 0;
-      value_counter.counter = (counter_t) strtoull (msg_string.str,
-          &endptr, /* base = */ 0);
-      if ((endptr == msg_string.str) || (errno != 0))
-        value_counter.counter = -1;
-
-      endptr = NULL;
-      errno = 0;
-      value_gauge.gauge = (gauge_t) strtod (msg_string.str, &endptr);
-      if ((endptr == msg_string.str) || (errno != 0))
+      status = parse_value (msg_string.str, &value_derive, DS_TYPE_DERIVE);
+      if (status != 0)
+        value_derive.derive = -1;
+
+      status = parse_value (msg_string.str, &value_gauge, DS_TYPE_GAUGE);
+      if (status != 0)
         value_gauge.gauge = NAN;
 
-      endptr = NULL;
-      errno = 0;
-      value_derive.derive = (derive_t) strtoll (msg_string.str,
-          &endptr, /* base = */ 0);
-      if ((endptr == msg_string.str) || (errno != 0))
-        value_derive.derive = 0;
+      status = parse_value (msg_string.str, &value_counter, DS_TYPE_COUNTER);
+      if (status != 0)
+        value_counter.counter = 0;
 
       break;
     }
@@ -663,11 +675,15 @@ static int mc_handle_value_msg (Ganglia_value_msg *msg) /* {{{ */
   {
     value_t val_copy;
 
-    val_copy = value_counter;
-    if (map->ds_type == DS_TYPE_GAUGE)
+    if ((map->ds_type == DS_TYPE_COUNTER)
+        || (map->ds_type == DS_TYPE_ABSOLUTE))
+      val_copy = value_counter;
+    else if (map->ds_type == DS_TYPE_GAUGE)
       val_copy = value_gauge;
     else if (map->ds_type == DS_TYPE_DERIVE)
       val_copy = value_derive;
+    else
+      assert (23 == 42);
 
     return (staging_entry_update (host, name,
           map->type, map->type_instance,
@@ -719,7 +735,7 @@ static int mc_handle_metadata_msg (Ganglia_metadata_msg *msg) /* {{{ */
           map->type, map->type_instance,
           ds->ds_num);
       if (se != NULL)
-        se->vl.interval = (int) msg_meta.metric.tmax;
+        se->vl.interval = TIME_T_TO_CDTIME_T (msg_meta.metric.tmax);
       pthread_mutex_unlock (&staging_lock);
 
       if (se == NULL)
@@ -869,6 +885,7 @@ static void *mc_receive_thread (void *arg) /* {{{ */
     }
   } /* while (mc_receive_thread_loop != 0) */
 
+  free (mc_receive_socket_entries);
   return ((void *) 0);
 } /* }}} void *mc_receive_thread */
 
@@ -881,7 +898,7 @@ static int mc_receive_thread_start (void) /* {{{ */
 
   mc_receive_thread_loop = 1;
 
-  status = pthread_create (&mc_receive_thread_id, /* attr = */ NULL,
+  status = plugin_thread_create (&mc_receive_thread_id, /* attr = */ NULL,
       mc_receive_thread, /* args = */ NULL);
   if (status != 0)
   {