]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-fuse: fix enumerate_images() image names buffer size issue 1425/head
authorIlya Dryomov <ilya.dryomov@inktank.com>
Tue, 11 Mar 2014 14:00:37 +0000 (16:00 +0200)
committerIlya Dryomov <ilya.dryomov@inktank.com>
Tue, 11 Mar 2014 14:00:37 +0000 (16:00 +0200)
Image names buffer is fixed at 1024.  This turns out to be not enough:
there are at least two "rbd-fuse rbd_list: error %d Numerical result
out of range" reports on the ML.  Fix it by calling rbd_list() twice to
first get the expected buffer size.  Also, get rid of the memory leak
and tweak the error message while at it.

Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com>
src/rbd_fuse/rbd-fuse.c

index 2a6a8d22e813b7e787a7074486270140fecfd0a8..f3f9b7b8067a8ed305252ab955f62e5fcec80a17 100644 (file)
@@ -17,6 +17,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <getopt.h>
+#include <assert.h>
 
 #include "include/rbd/librbd.h"
 
@@ -75,11 +76,11 @@ void simple_err(const char *msg, int err);
 void
 enumerate_images(struct rbd_image **head)
 {
-       char *ibuf;
-       size_t ibuf_len;
+       char *ibuf = NULL;
+       size_t ibuf_len = 0;
        struct rbd_image *im, *next;
        char *ip;
-       int actual_len;
+       int ret;
 
        if (*head != NULL) {
                for (im = *head; im != NULL;) {
@@ -90,17 +91,29 @@ enumerate_images(struct rbd_image **head)
                *head = NULL;
        }
 
-       ibuf_len = 1024;
-       ibuf = malloc(ibuf_len);
-       actual_len = rbd_list(ioctx, ibuf, &ibuf_len);
-       if (actual_len < 0) {
-               simple_err("rbd_list: error %d\n", actual_len);
+       ret = rbd_list(ioctx, ibuf, &ibuf_len);
+       if (ret == -ERANGE) {
+               assert(ibuf_len > 0);
+               ibuf = malloc(ibuf_len);
+               if (!ibuf) {
+                       simple_err("Failed to get ibuf", -ENOMEM);
+                       return;
+               }
+       } else if (ret < 0) {
+               simple_err("Failed to get ibuf_len", ret);
+               return;
+       }
+
+       ret = rbd_list(ioctx, ibuf, &ibuf_len);
+       if (ret < 0) {
+               simple_err("Failed to populate ibuf", ret);
+               free(ibuf);
                return;
        }
+       assert(ret == ibuf_len);
 
        fprintf(stderr, "pool %s: ", pool_name);
-       for (ip = ibuf; *ip != '\0' && ip < &ibuf[actual_len];
-            ip += strlen(ip) + 1)  {
+       for (ip = ibuf; ip < &ibuf[ibuf_len]; ip += strlen(ip) + 1)  {
                fprintf(stderr, "%s, ", ip);
                im = malloc(sizeof(*im));
                im->image_name = ip;
@@ -108,7 +121,6 @@ enumerate_images(struct rbd_image **head)
                *head = im;
        }
        fprintf(stderr, "\n");
-       return;
 }
 
 int