ceph plugin: Guard against g_num_daemons being zero.
[collectd.git] / src / ceph.c
index e9bb960..458112a 100644 (file)
@@ -167,7 +167,7 @@ static int convert_special_metrics = 1;
 static struct ceph_daemon **g_daemons = NULL;
 
 /** Number of elements in g_daemons */
-static int g_num_daemons = 0;
+static size_t g_num_daemons = 0;
 
 /**
  * A set of data that we build up in memory while parsing the JSON.
@@ -262,8 +262,11 @@ static int ceph_cb_boolean(void *ctx, int bool_val)
 
 #define BUFFER_ADD(dest, src) do { \
     size_t dest_size = sizeof (dest); \
-    strncat ((dest), (src), dest_size - strlen (dest)); \
-    (dest)[dest_size - 1] = '\0'; \
+    size_t dest_len = strlen (dest); \
+    if (dest_size > dest_len) { \
+        sstrncpy ((dest) + dest_len, (src), dest_size - dest_len); \
+    } \
+    (dest)[dest_size - 1] = 0; \
 } while (0)
 
 static int
@@ -271,11 +274,10 @@ ceph_cb_number(void *ctx, const char *number_val, yajl_len_t number_len)
 {
     yajl_struct *state = (yajl_struct*) ctx;
     char buffer[number_len+1];
-    char key[2 * DATA_MAX_NAME_LEN];
+    char key[2 * DATA_MAX_NAME_LEN] = { 0 };
     _Bool latency_type = 0;
     int status;
 
-    key[0] = '\0';
     memcpy(buffer, number_val, number_len);
     buffer[sizeof(buffer) - 1] = '\0';
 
@@ -425,7 +427,7 @@ static void ceph_daemon_print(const struct ceph_daemon *d)
 
 static void ceph_daemons_print(void)
 {
-    for(int i = 0; i < g_num_daemons; ++i)
+    for(size_t i = 0; i < g_num_daemons; ++i)
     {
         ceph_daemon_print(g_daemons[i]);
     }
@@ -752,7 +754,8 @@ static int cc_add_daemon_config(oconfig_item_t *ci)
         return ENOMEM;
     }
     memcpy(nd, &cd, sizeof(*nd));
-    g_daemons[g_num_daemons++] = nd;
+    g_daemons[g_num_daemons] = nd;
+    g_num_daemons++;
     return 0;
 }
 
@@ -1464,7 +1467,7 @@ static int cconn_main_loop(uint32_t request_type)
 
     /* create cconn array */
     memset(io_array, 0, sizeof(io_array));
-    for(int i = 0; i < g_num_daemons; ++i)
+    for(size_t i = 0; i < g_num_daemons; ++i)
     {
         io_array[i].d = g_daemons[i];
         io_array[i].request_type = request_type;
@@ -1483,13 +1486,13 @@ static int cconn_main_loop(uint32_t request_type)
         struct pollfd fds[g_num_daemons];
         memset(fds, 0, sizeof(fds));
         nfds = 0;
-        for(int i = 0; i < g_num_daemons; ++i)
+        for(size_t i = 0; i < g_num_daemons; ++i)
         {
             struct cconn *io = io_array + i;
             ret = cconn_prepare(io, fds + nfds);
             if(ret < 0)
             {
-                WARNING("ceph plugin: cconn_prepare(name=%s,i=%d,st=%d)=%d",
+                WARNING("ceph plugin: cconn_prepare(name=%s,i=%zu,st=%d)=%d",
                         io->d->name, i, io->state, ret);
                 cconn_close(io);
                 io->request_type = ASOK_REQ_NONE;
@@ -1528,6 +1531,7 @@ static int cconn_main_loop(uint32_t request_type)
             if(revents == 0)
             {
                 /* do nothing */
+                continue;
             }
             else if(cconn_validate_revents(io, revents))
             {
@@ -1552,7 +1556,7 @@ static int cconn_main_loop(uint32_t request_type)
             }
         }
     }
-    done: for(int i = 0; i < g_num_daemons; ++i)
+    done: for(size_t i = 0; i < g_num_daemons; ++i)
     {
         cconn_close(io_array + i);
     }
@@ -1575,16 +1579,14 @@ static int ceph_read(void)
 /******* lifecycle *******/
 static int ceph_init(void)
 {
-    int ret;
-
-#ifdef HAVE_SYS_CAPABILITY_H
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_DAC_OVERRIDE)
   if (check_capability (CAP_DAC_OVERRIDE) != 0)
   {
     if (getuid () == 0)
       WARNING ("ceph plugin: Running collectd as root, but the "
           "CAP_DAC_OVERRIDE capability is missing. The plugin's read "
           "function will probably fail. Is your init system dropping "
-          "capabilities ?");
+          "capabilities?");
     else
       WARNING ("ceph plugin: collectd doesn't have the CAP_DAC_OVERRIDE "
           "capability. If you don't want to run collectd as root, try running "
@@ -1594,14 +1596,18 @@ static int ceph_init(void)
 
     ceph_daemons_print();
 
-    ret = cconn_main_loop(ASOK_REQ_VERSION);
+    if (g_num_daemons < 1)
+    {
+        ERROR ("ceph plugin: No daemons configured. See the \"Daemon\" config option.");
+        return ENOENT;
+    }
 
-    return (ret) ? ret : 0;
+    return cconn_main_loop(ASOK_REQ_VERSION);
 }
 
 static int ceph_shutdown(void)
 {
-    for(int i = 0; i < g_num_daemons; ++i)
+    for(size_t i = 0; i < g_num_daemons; ++i)
     {
         ceph_daemon_free(g_daemons[i]);
     }