configure.ac: rewrite liblua detection
[collectd.git] / src / ping.c
index 7eb2293..5f66aab 100644 (file)
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_complain.h"
 
-#include <pthread.h>
 #include <netinet/in.h>
 #if HAVE_NETDB_H
 # include <netdb.h> /* NI_MAXHOST */
 #endif
 
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
 #include <oping.h>
 
 #ifndef NI_MAXHOST
@@ -152,11 +155,10 @@ static void time_calc (struct timespec *ts_dest, /* {{{ */
 
 static int ping_dispatch_all (pingobj_t *pingobj) /* {{{ */
 {
-  pingobj_iter_t *iter;
   hostlist_t *hl;
   int status;
 
-  for (iter = ping_iterator_get (pingobj);
+  for (pingobj_iter_t *iter = ping_iterator_get (pingobj);
       iter != NULL;
       iter = ping_iterator_next (iter))
   { /* {{{ */
@@ -244,14 +246,13 @@ static int ping_dispatch_all (pingobj_t *pingobj) /* {{{ */
 
 static void *ping_thread (void *arg) /* {{{ */
 {
-  static pingobj_t *pingobj = NULL;
+  pingobj_t *pingobj = NULL;
 
   struct timeval  tv_begin;
   struct timeval  tv_end;
   struct timespec ts_wait;
   struct timespec ts_int;
 
-  hostlist_t *hl;
   int count;
 
   c_complain_t complaint = C_COMPLAIN_INIT_STATIC;
@@ -287,7 +288,7 @@ static void *ping_thread (void *arg) /* {{{ */
 
   /* Add all the hosts to the ping object. */
   count = 0;
-  for (hl = hostlist_head; hl != NULL; hl = hl->next)
+  for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next)
   {
     int tmp_status;
     tmp_status = ping_host_add (pingobj, hl->host);
@@ -385,7 +386,7 @@ static int start_thread (void) /* {{{ */
   if (ping_thread_loop != 0)
   {
     pthread_mutex_unlock (&ping_lock);
-    return (-1);
+    return (0);
   }
 
   ping_thread_loop = 1;
@@ -399,7 +400,7 @@ static int start_thread (void) /* {{{ */
     pthread_mutex_unlock (&ping_lock);
     return (-1);
   }
-    
+
   pthread_mutex_unlock (&ping_lock);
   return (0);
 } /* }}} int start_thread */
@@ -427,8 +428,10 @@ static int stop_thread (void) /* {{{ */
     status = -1;
   }
 
+  pthread_mutex_lock (&ping_lock);
   memset (&ping_thread_id, 0, sizeof (ping_thread_id));
   ping_thread_error = 0;
+  pthread_mutex_unlock (&ping_lock);
 
   return (status);
 } /* }}} int stop_thread */
@@ -448,10 +451,21 @@ static int ping_init (void) /* {{{ */
         "Will use a timeout of %gs.", ping_timeout);
   }
 
-  if (start_thread () != 0)
-    return (-1);
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_NET_RAW)
+  if (check_capability (CAP_NET_RAW) != 0)
+  {
+    if (getuid () == 0)
+      WARNING ("ping plugin: Running collectd as root, but the CAP_NET_RAW "
+          "capability is missing. The plugin's read function will probably "
+          "fail. Is your init system dropping capabilities?");
+    else
+      WARNING ("ping plugin: collectd doesn't have the CAP_NET_RAW capability. "
+          "If you don't want to run collectd as root, try running \"setcap "
+          "cap_net_raw=ep\" on the collectd binary.");
+  }
+#endif
 
-  return (0);
+  return (start_thread ());
 } /* }}} int ping_init */
 
 static int config_set_string (const char *name, /* {{{ */
@@ -481,7 +495,7 @@ static int ping_config (const char *key, const char *value) /* {{{ */
     hostlist_t *hl;
     char *host;
 
-    hl = (hostlist_t *) malloc (sizeof (hostlist_t));
+    hl = malloc (sizeof (*hl));
     if (hl == NULL)
     {
       char errbuf[1024];
@@ -543,26 +557,19 @@ static int ping_config (const char *key, const char *value) /* {{{ */
           tmp, value);
   }
   else if (strcasecmp (key, "Size") == 0) {
-    int size;
-
-    if (ping_data != NULL)
-    {
-      free(ping_data);
-      ping_data = NULL;
-    }
+    size_t size = (size_t) atoi (value);
 
-    size = atoi (value);
-    if ((size >= 1) && (size <= 65536))
+    /* Max IP packet size - (IPv6 + ICMP) = 65535 - (40 + 8) = 65487 */
+    if (size <= 65487)
     {
-      int i;
-      ping_data = (char*) malloc(size + 1);
+      sfree (ping_data);
+      ping_data = malloc (size + 1);
       if (ping_data == NULL)
       {
-        char errbuf[1024];
-        ERROR ("ping plugin: malloc failed: %s",
-            sstrerror (errno, errbuf, sizeof (errbuf)));
+        ERROR ("ping plugin: malloc failed.");
         return (1);
       }
+
       /* Note: By default oping is using constant string
        * "liboping -- ICMP ping library <http://octo.it/liboping/>"
        * which is exactly 56 bytes.
@@ -570,15 +577,15 @@ static int ping_config (const char *key, const char *value) /* {{{ */
        * Optimally we would follow the ping(1) behaviour, but we
        * cannot use byte 00 or start data payload at exactly same
        * location, due to oping library limitations. */
-      for (i = 0; i < size; i++) /* {{{ */
+      for (size_t i = 0; i < size; i++) /* {{{ */
       {
         /* This restricts data pattern to be only composed of easily
          * printable characters, and not NUL character. */
         ping_data[i] = ('0' + i % 64);
       }  /* }}} for (i = 0; i < size; i++) */
-      ping_data[size] = '\0';
+      ping_data[size] = 0;
     } else
-      WARNING ("ping plugin: Ignoring invalid Size %i.", size);
+      WARNING ("ping plugin: Ignoring invalid Size %zu.", size);
   }
   else if (strcasecmp (key, "Timeout") == 0)
   {
@@ -626,15 +633,13 @@ static void submit (const char *host, const char *type, /* {{{ */
 
 static int ping_read (void) /* {{{ */
 {
-  hostlist_t *hl;
-
   if (ping_thread_error != 0)
   {
     ERROR ("ping plugin: The ping thread had a problem. Restarting it.");
 
     stop_thread ();
 
-    for (hl = hostlist_head; hl != NULL; hl = hl->next)
+    for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next)
     {
       hl->pkg_sent = 0;
       hl->pkg_recv = 0;
@@ -647,7 +652,7 @@ static int ping_read (void) /* {{{ */
     return (-1);
   } /* if (ping_thread_error != 0) */
 
-  for (hl = hostlist_head; hl != NULL; hl = hl->next) /* {{{ */
+  for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next) /* {{{ */
   {
     uint32_t pkg_sent;
     uint32_t pkg_recv;