Code

Removed `gethostbyname' and replaced with protocol independend `getaddrinfo'
[collectd.git] / src / ping.c
index eb35360b5464b9f55f378b5bd18b21b840829a12..f80cab517182437ec2291885dc4c7d14458f25f1 100644 (file)
  *   Florian octo Forster <octo at verplant.org>
  **/
 
-#include "ping.h"
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "configfile.h"
 
-#if COLLECT_PING
 #define MODULE_NAME "ping"
 
-#include "plugin.h"
-#include "common.h"
-
 #include <netinet/in.h>
 #include "libping/ping.h"
 
-extern char *pinghosts[MAX_PINGHOSTS];
-extern int   num_pinghosts;
-static int   pingerrors[MAX_PINGHOSTS];
+#define MAX_PINGHOSTS 32
+
+typedef struct
+{
+       char *name;
+       int   flags;
+       int   disable; /* How long (how many iterations) this host is still disabled */
+       int   backoff; /* How long the host will be disabled, if it failes again */
+} pinghost_t;
+
+static pinghost_t hosts[MAX_PINGHOSTS];
+static int        num_pinghosts;
 
 static char *file_template = "ping-%s.rrd";
 
@@ -44,19 +52,49 @@ static char *ds_def[] =
 };
 static int ds_num = 1;
 
-extern time_t curtime;
+static char *config_keys[] =
+{
+       "Host",
+       NULL
+};
+static int config_keys_num = 1;
 
-void ping_init (void)
+static void ping_init (void)
 {
        int i;
 
-       for (i = 0; i < num_pinghosts; i++)
-               pingerrors[i] = 0;
+       for (i = 0; i < MAX_PINGHOSTS; i++)
+       {
+               hosts[i].flags = 0;
+               hosts[i].disable = 0;
+               hosts[i].backoff = 1;
+       }
 
        return;
 }
 
-void ping_write (char *host, char *inst, char *val)
+static int ping_config (char *key, char *value)
+{
+       if (strcasecmp (key, "host"))
+       {
+               return (-1);
+       }
+       else if (num_pinghosts >= MAX_PINGHOSTS)
+       {
+               return (1);
+       }
+       else if ((hosts[num_pinghosts].name = strdup (value)) == NULL)
+       {
+               return (2);
+       }
+       else
+       {
+               num_pinghosts++;
+               return (0);
+       }
+}
+
+static void ping_write (char *host, char *inst, char *val)
 {
        char file[512];
        int status;
@@ -71,59 +109,67 @@ void ping_write (char *host, char *inst, char *val)
 }
 
 #define BUFSIZE 256
-void ping_submit (int ping_time, char *host)
+static void ping_submit (int ping_time, char *host)
 {
        char buf[BUFSIZE];
 
-       if (snprintf (buf, BUFSIZE, "%u:%u", (unsigned int) curtime, ping_time) >= BUFSIZE)
+       if (snprintf (buf, BUFSIZE, "%u:%i", (unsigned int) curtime, ping_time) >= BUFSIZE)
                return;
 
        plugin_submit (MODULE_NAME, host, buf);
 }
 #undef BUFSIZE
 
-void ping_read (void)
+static void ping_read (void)
 {
        int ping;
        int i;
 
        for (i = 0; i < num_pinghosts; i++)
        {
-               if (pingerrors[i] & 0x30)
+               if (hosts[i].disable > 0)
+               {
+                       hosts[i].disable--;
                        continue;
+               }
                
-               ping = tpinghost (pinghosts[i]);
+               ping = tpinghost (hosts[i].name);
 
                switch (ping)
                {
                        case 0:
-                               if (!(pingerrors[i] & 0x01))
-                                       syslog (LOG_WARNING, "ping %s: Connection timed out.", pinghosts[i]);
-                               pingerrors[i] |= 0x01;
+                               if (!(hosts[i].flags & 0x01))
+                                       syslog (LOG_WARNING, "ping %s: Connection timed out.", hosts[i].name);
+                               hosts[i].flags |= 0x01;
                                break;
 
                        case -1:
-                               if (!(pingerrors[i] & 0x02))
-                                       syslog (LOG_WARNING, "ping %s: Host or service is not reachable.", pinghosts[i]);
-                               pingerrors[i] |= 0x02;
+                               if (!(hosts[i].flags & 0x02))
+                                       syslog (LOG_WARNING, "ping %s: Host or service is not reachable.", hosts[i].name);
+                               hosts[i].flags |= 0x02;
                                break;
 
                        case -2:
-                               syslog (LOG_ERR, "ping %s: Socket error. Ping will be disabled.", pinghosts[i]);
-                               pingerrors[i] |= 0x10;
+                               syslog (LOG_ERR, "ping %s: Socket error. Ping will be disabled for %i iteration(s).",
+                                               hosts[i].name, hosts[i].backoff);
+                               hosts[i].disable = hosts[i].backoff;
+                               if (hosts[i].backoff < 8192) /* 22 3/4 hours */
+                                       hosts[i].backoff *= 2;
+                               hosts[i].flags |= 0x10;
                                break;
 
                        case -3:
-                               if (!(pingerrors[i] & 0x04))
-                                       syslog (LOG_WARNING, "ping %s: Connection refused.", pinghosts[i]);
-                               pingerrors[i] |= 0x04;
+                               if (!(hosts[i].flags & 0x04))
+                                       syslog (LOG_WARNING, "ping %s: Connection refused.", hosts[i].name);
+                               hosts[i].flags |= 0x04;
                                break;
 
                        default:
-                               if (pingerrors[i] != 0x00)
-                                       syslog (LOG_NOTICE, "ping %s: Back to normal: %ims.", pinghosts[i], ping);
-                               pingerrors[i] = 0x00;
-                               ping_submit (ping, pinghosts[i]);
+                               if (hosts[i].flags != 0x00)
+                                       syslog (LOG_NOTICE, "ping %s: Back to normal: %ims.", hosts[i].name, ping);
+                               hosts[i].flags = 0x00;
+                               hosts[i].backoff = 1;
+                               ping_submit (ping, hosts[i].name);
                } /* switch (ping) */
        } /* for (i = 0; i < num_pinghosts; i++) */
 }
@@ -131,7 +177,7 @@ void ping_read (void)
 void module_register (void)
 {
        plugin_register (MODULE_NAME, ping_init, ping_read, ping_write);
+       cf_register (MODULE_NAME, ping_config, config_keys, config_keys_num);
 }
 
 #undef MODULE_NAME
-#endif /* COLLECT_PING */