From: Ilya Dryomov Date: Tue, 11 Mar 2014 14:00:37 +0000 (+0200) Subject: rbd-fuse: fix enumerate_images() image names buffer size issue X-Git-Tag: v0.78~40^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F1425%2Fhead;p=ceph.git rbd-fuse: fix enumerate_images() image names buffer size issue 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 --- diff --git a/src/rbd_fuse/rbd-fuse.c b/src/rbd_fuse/rbd-fuse.c index 2a6a8d22e81..f3f9b7b8067 100644 --- a/src/rbd_fuse/rbd-fuse.c +++ b/src/rbd_fuse/rbd-fuse.c @@ -17,6 +17,7 @@ #include #include #include +#include #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