Code

libvirtstats plugin: Added a plugin to collect virtual host statistics.
[collectd.git] / src / ipvs.c
index 9bf2224a816e9b559fef9fb0ef8a70017268b70e..68a3d7f3bf9d46a9f47c17492a6acd926458cfbc 100644 (file)
 #endif /* HAVE_IP_VS_H */
 
 #define log_err(...) ERROR ("ipvs: " __VA_ARGS__)
-
+#define log_info(...) INFO ("ipvs: " __VA_ARGS__)
 
 /*
  * private variables
  */
-
-static int   sockfd    = -1;
-
+static int sockfd = -1;
 
 /*
  * libipvs API
  */
-
 static struct ip_vs_get_services *ipvs_get_services (void)
 {
        struct ip_vs_getinfo       ipvs_info;
@@ -133,19 +130,46 @@ static struct ip_vs_get_dests *ipvs_get_dests (struct ip_vs_service_entry *se)
        return ret;
 } /* ip_vs_get_dests */
 
-
 /*
  * collectd plugin API and helper functions
  */
-
 static int cipvs_init (void)
 {
+       struct ip_vs_getinfo ipvs_info;
+
+       socklen_t len;
+
        if (-1 == (sockfd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW))) {
                char errbuf[1024];
                log_err ("cipvs_init: socket() failed: %s",
                                sstrerror (errno, errbuf, sizeof (errbuf)));
                return -1;
        }
+
+       len = sizeof (ipvs_info);
+
+       if (0 != getsockopt (sockfd, IPPROTO_IP, IP_VS_SO_GET_INFO,
+                               (void *)&ipvs_info, &len)) {
+               char errbuf[1024];
+               log_err ("cipvs_init: getsockopt() failed: %s",
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+               close (sockfd);
+               sockfd = -1;
+               return -1;
+       }
+
+       /* we need IPVS >= 1.1.4 */
+       if (ipvs_info.version < ((1 << 16) + (1 << 8) + 4)) {
+               log_err ("cipvs_init: IPVS version too old (%d.%d.%d < %d.%d.%d)",
+                               NVERSION (ipvs_info.version), 1, 1, 4);
+               close (sockfd);
+               sockfd = -1;
+               return -1;
+       }
+       else {
+               log_info ("Successfully connected to IPVS %d.%d.%d",
+                               NVERSION (ipvs_info.version));
+       }
        return 0;
 } /* cipvs_init */
 
@@ -287,9 +311,11 @@ static void cipvs_submit_service (struct ip_vs_service_entry *se)
 static int cipvs_read (void)
 {
        struct ip_vs_get_services *services = NULL;
-
        int i = 0;
 
+       if (sockfd < 0)
+               return (-1);
+
        if (NULL == (services = ipvs_get_services ()))
                return -1;
 
@@ -302,7 +328,10 @@ static int cipvs_read (void)
 
 static int cipvs_shutdown (void)
 {
-       close (sockfd);
+       if (sockfd >= 0)
+               close (sockfd);
+       sockfd = -1;
+
        return 0;
 } /* cipvs_shutdown */
 
@@ -315,4 +344,3 @@ void module_register (void)
 } /* module_register */
 
 /* vim: set sw=4 ts=4 tw=78 noexpandtab : */
-