]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: add API function to get image name
authorMykola Golub <mgolub@suse.com>
Thu, 15 Mar 2018 16:32:50 +0000 (18:32 +0200)
committerMykola Golub <mgolub@suse.com>
Fri, 16 Mar 2018 18:05:34 +0000 (20:05 +0200)
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 <mgolub@suse.com>
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/librbd.cc
src/pybind/rbd/rbd.pyx
src/test/librbd/test_librbd.cc
src/test/pybind/test_rbd.py

index bfa065aa7dbf5f38e9b9c0811cb57efb3d841c23..9a38fed74bb12f8f12ff6d9614c62bf781527f03 100644 (file)
@@ -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);
index 1c0a3fe3f83a523b4f6ccb47546cb66a5f8a6227..1b43f3db758381ff7243c937de91cf4a578058b3 100644 (file)
@@ -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();
index 6734a52a500bea7cef03865de19be4c1c12304f1..44e76897020c316f75d3a644fb140f2ef48480b7 100644 (file)
@@ -1129,6 +1129,13 @@ namespace librbd {
     return r;
   }
 
+  int Image::get_name(std::string *name)
+  {
+    ImageCtx *ictx = reinterpret_cast<ImageCtx *>(ctx);
+    *name = ictx->name;
+    return 0;
+  }
+
   int Image::get_id(std::string *id)
   {
     ImageCtx *ictx = reinterpret_cast<ImageCtx *>(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<librbd::ImageCtx *>(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<librbd::ImageCtx *>(image);
index e2ba0f7978c9a50f831a3522fbd41bfe79aff663..d35590923b2dccd3a5f6608d9033de793ae5ebcc 100644 (file)
@@ -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 =  <char *>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
index 8d08a771ae8b9f08766aede87e956de8520ef71f..beaac69b22ce4565bc9a92b6aaf2c5c3ad96c11b 100644 (file)
@@ -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);
   }
 }
 
index 6ce6c32c9d5cc22d7c964dc1caa1d4504c5a200c..355ea6ded71a62bdff7be3264b2d518d33b18ed0 100644 (file)
@@ -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)