From: Mykola Golub Date: Thu, 15 Mar 2018 16:32:50 +0000 (+0200) Subject: librbd: add API function to get image name X-Git-Tag: v13.1.0~441^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d75973f8b3f0e0e662ce36f271f8fdf80b5b4220;p=ceph.git librbd: add API function to get image name We already have open_by_id function, so an image name may be unknown to the user, and get_name may be useful then. Signed-off-by: Mykola Golub --- diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index bfa065aa7dbf..9a38fed74bb1 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -402,6 +402,7 @@ CEPH_RBD_API int rbd_get_create_timestamp(rbd_image_t image, struct timespec *timestamp); CEPH_RBD_API int rbd_get_overlap(rbd_image_t image, uint64_t *overlap); +CEPH_RBD_API int rbd_get_name(rbd_image_t image, char *name, size_t *name_len); CEPH_RBD_API int rbd_get_id(rbd_image_t image, char *id, size_t id_len); CEPH_RBD_API int rbd_get_block_name_prefix(rbd_image_t image, char *prefix, size_t prefix_len); diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index 1c0a3fe3f83a..1b43f3db7583 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -290,6 +290,7 @@ public: int resize2(uint64_t size, bool allow_shrink, ProgressContext& pctx); int resize_with_progress(uint64_t size, ProgressContext& pctx); int stat(image_info_t &info, size_t infosize); + int get_name(std::string *name); int get_id(std::string *id); std::string get_block_name_prefix(); int64_t get_data_pool_id(); diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 6734a52a500b..44e76897020c 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -1129,6 +1129,13 @@ namespace librbd { return r; } + int Image::get_name(std::string *name) + { + ImageCtx *ictx = reinterpret_cast(ctx); + *name = ictx->name; + return 0; + } + int Image::get_id(std::string *id) { ImageCtx *ictx = reinterpret_cast(ctx); @@ -3147,6 +3154,20 @@ extern "C" int rbd_get_overlap(rbd_image_t image, uint64_t *overlap) return r; } +extern "C" int rbd_get_name(rbd_image_t image, char *name, size_t *name_len) +{ + librbd::ImageCtx *ictx = reinterpret_cast(image); + if (*name_len <= ictx->name.size()) { + *name_len = ictx->name.size() + 1; + return -ERANGE; + } + + strncpy(name, ictx->name.c_str(), ictx->name.size()); + name[ictx->name.size()] = '\0'; + *name_len = ictx->name.size() + 1; + return 0; +} + extern "C" int rbd_get_id(rbd_image_t image, char *id, size_t id_len) { librbd::ImageCtx *ictx = reinterpret_cast(image); diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx index e2ba0f7978c9..d35590923b2d 100644 --- a/src/pybind/rbd/rbd.pyx +++ b/src/pybind/rbd/rbd.pyx @@ -283,6 +283,7 @@ cdef extern from "rbd/librbd.h" nogil: int rbd_get_stripe_count(rbd_image_t image, uint64_t *stripe_count) int rbd_get_create_timestamp(rbd_image_t image, timespec *timestamp) int rbd_get_overlap(rbd_image_t image, uint64_t *overlap) + int rbd_get_name(rbd_image_t image, char *name, size_t *name_len) int rbd_get_id(rbd_image_t image, char *id, size_t id_len) int rbd_get_block_name_prefix(rbd_image_t image, char *prefix, size_t prefix_len) @@ -1805,6 +1806,8 @@ cdef class Image(object): if ret != 0: raise make_ex(ret, 'error opening image %s at snapshot %s' % (self.name, snapshot)) self.closed = False + if name is None: + self.name = self.get_name() def __enter__(self): return self @@ -1915,6 +1918,28 @@ cdef class Image(object): 'parent_name' : info.parent_name } + def get_name(self): + """ + Get the RBD image name + + :returns: str - image name + """ + cdef: + int ret = -errno.ERANGE + size_t size = 64 + char *image_name = NULL + try: + while ret == -errno.ERANGE: + image_name = realloc_chk(image_name, size) + with nogil: + ret = rbd_get_name(self.image, image_name, &size) + + if ret != 0: + raise make_ex(ret, 'error getting name for image %s' % (self.name,)) + return decode_cstr(image_name) + finally: + free(image_name) + def id(self): """ Get the RBD v2 internal image id diff --git a/src/test/librbd/test_librbd.cc b/src/test/librbd/test_librbd.cc index 8d08a771ae8b..beaac69b22ce 100644 --- a/src/test/librbd/test_librbd.cc +++ b/src/test/librbd/test_librbd.cc @@ -377,6 +377,15 @@ TEST_F(TestLibRBD, GetId) ASSERT_EQ(-ERANGE, rbd_get_id(image, id, 0)); ASSERT_EQ(0, rbd_get_id(image, id, sizeof(id))); ASSERT_LT(0U, strlen(id)); + + ASSERT_EQ(0, rbd_close(image)); + ASSERT_EQ(0, rbd_open_by_id(ioctx, id, &image, NULL)); + size_t name_len = 0; + ASSERT_EQ(-ERANGE, rbd_get_name(image, NULL, &name_len)); + ASSERT_EQ(name_len, name.size() + 1); + char image_name[name_len]; + ASSERT_EQ(0, rbd_get_name(image, image_name, &name_len)); + ASSERT_STREQ(name.c_str(), image_name); } ASSERT_EQ(0, rbd_close(image)); @@ -402,6 +411,12 @@ TEST_F(TestLibRBD, GetIdPP) } else { ASSERT_EQ(0, image.get_id(&id)); ASSERT_LT(0U, id.size()); + + ASSERT_EQ(0, image.close()); + ASSERT_EQ(0, rbd.open_by_id(ioctx, image, id.c_str(), NULL)); + std::string image_name; + ASSERT_EQ(0, image.get_name(&image_name)); + ASSERT_EQ(name, image_name); } } diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py index 6ce6c32c9d5c..355ea6ded71a 100644 --- a/src/test/pybind/test_rbd.py +++ b/src/test/pybind/test_rbd.py @@ -290,6 +290,18 @@ def test_open_readonly_dne(): assert_raises(ImageNotFound, Image, ioctx, image_name, 'snap', read_only=True) +@require_new_format() +def test_open_by_id(): + with Rados(conffile='') as cluster: + with cluster.open_ioctx(pool_name) as ioctx: + image_name = get_temp_image_name() + RBD().create(ioctx, image_name, IMG_SIZE) + with Image(ioctx, image_name) as image: + image_id = image.id() + with Image(ioctx, image_id=image_id) as image: + eq(image.get_name(), image_name) + RBD().remove(ioctx, image_name) + def test_remove_dne(): assert_raises(ImageNotFound, remove_image)