]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: extended parent info API to retrieve parent id
authorJason Dillaman <dillaman@redhat.com>
Fri, 28 Apr 2017 14:05:57 +0000 (10:05 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 1 May 2017 14:10:13 +0000 (10:10 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/internal.cc
src/librbd/internal.h
src/librbd/librbd.cc
src/pybind/rbd/rbd.pyx
src/test/pybind/test_rbd.py
src/tracing/librbd.tp

index b435feac1ee1daabb2fc8e59065a9813bd5cf2fb..289640a499da110a61c763ce89be5434d72d587a 100644 (file)
@@ -1,4 +1,4 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 /*
  * Ceph - scalable distributed file system
@@ -370,6 +370,13 @@ CEPH_RBD_API int rbd_get_parent_info(rbd_image_t image,
                                     char *parent_name, size_t pnamelen,
                                     char *parent_snapname,
                                      size_t psnapnamelen);
+CEPH_RBD_API int rbd_get_parent_info2(rbd_image_t image,
+                                      char *parent_poolname,
+                                      size_t ppoolnamelen,
+                                      char *parent_name, size_t pnamelen,
+                                      char *parent_id, size_t pidlen,
+                                      char *parent_snapname,
+                                      size_t psnapnamelen);
 CEPH_RBD_API int rbd_get_flags(rbd_image_t image, uint64_t *flags);
 CEPH_RBD_API int rbd_set_image_notification(rbd_image_t image, int fd, int type);
 
index f404494b1be6b2ca2d70a328e068901a82c78c9a..d774b9d10ae6bb254326bbcc38b53b667d031b79 100644 (file)
@@ -253,7 +253,9 @@ public:
   std::string get_block_name_prefix();
   int64_t get_data_pool_id();
   int parent_info(std::string *parent_poolname, std::string *parent_name,
-                     std::string *parent_snapname);
+                 std::string *parent_snapname);
+  int parent_info2(std::string *parent_poolname, std::string *parent_name,
+                   std::string *parent_id, std::string *parent_snapname);
   int old_format(uint8_t *old);
   int size(uint64_t *size);
   int get_group(group_spec_t *group_spec);
index af7a3c60fc6928ecfafed76715cab5589cb9770d..1168afac7f730d706d3483e335b4283c64a2e4d4 100644 (file)
@@ -1045,7 +1045,8 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
   }
 
   int get_parent_info(ImageCtx *ictx, string *parent_pool_name,
-                     string *parent_name, string *parent_snap_name)
+                      string *parent_name, string *parent_id,
+                      string *parent_snap_name)
   {
     int r = ictx->state->refresh_if_required();
     if (r < 0)
@@ -1097,6 +1098,9 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
       RWLock::RLocker snap_locker(ictx->parent->snap_lock);
       *parent_name = ictx->parent->name;
     }
+    if (parent_id) {
+      *parent_id = ictx->parent->id;
+    }
 
     return 0;
   }
index 59c9fad926a3a93c948ff707443ff60275ef8f1a..cf07472b1af0e92d2e233f2b8e44d0f2c26149b4 100644 (file)
@@ -128,7 +128,8 @@ namespace librbd {
   int get_features(ImageCtx *ictx, uint64_t *features);
   int get_overlap(ImageCtx *ictx, uint64_t *overlap);
   int get_parent_info(ImageCtx *ictx, std::string *parent_pool_name,
-                     std::string *parent_name, std::string *parent_snap_name);
+                      std::string *parent_name, std::string *parent_id,
+                      std::string *parent_snap_name);
   int get_flags(ImageCtx *ictx, uint64_t *flags);
   int set_image_notification(ImageCtx *ictx, int fd, int type);
   int is_exclusive_lock_owner(ImageCtx *ictx, bool *is_owner);
index 5a4bf51d5ba33b224b62e63a10b065d12a2dceb4..a2180170cf3e2eed7b679cfde9adc60734049bcb 100644 (file)
@@ -1029,12 +1029,24 @@ namespace librbd {
 
   int Image::parent_info(string *parent_pool_name, string *parent_name,
                         string *parent_snap_name)
+  {
+    return parent_info2(parent_pool_name, parent_name, nullptr,
+                        parent_snap_name);
+  }
+
+  int Image::parent_info2(string *parent_pool_name, string *parent_name,
+                          string *parent_id, string *parent_snap_name)
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
-    tracepoint(librbd, get_parent_info_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only);
+    tracepoint(librbd, get_parent_info_enter, ictx, ictx->name.c_str(),
+               ictx->snap_name.c_str(), ictx->read_only);
     int r = librbd::get_parent_info(ictx, parent_pool_name, parent_name,
-                                  parent_snap_name);
-    tracepoint(librbd, get_parent_info_exit, r, parent_pool_name ? parent_pool_name->c_str() : NULL, parent_name ? parent_name->c_str() : NULL, parent_snap_name ? parent_snap_name->c_str() : NULL);
+                                    parent_id, parent_snap_name);
+    tracepoint(librbd, get_parent_info_exit, r,
+               parent_pool_name ? parent_pool_name->c_str() : NULL,
+               parent_name ? parent_name->c_str() : NULL,
+               parent_id ? parent_id->c_str() : NULL,
+               parent_snap_name ? parent_snap_name->c_str() : NULL);
     return r;
   }
 
@@ -2825,22 +2837,38 @@ extern "C" int64_t rbd_get_data_pool_id(rbd_image_t image)
 }
 
 extern "C" int rbd_get_parent_info(rbd_image_t image,
-  char *parent_pool_name, size_t ppool_namelen, char *parent_name,
-  size_t pnamelen, char *parent_snap_name, size_t psnap_namelen)
+                                   char *parent_pool_name, size_t ppool_namelen,
+                                   char *parent_name, size_t pnamelen,
+                                   char *parent_snap_name, size_t psnap_namelen)
+{
+  return rbd_get_parent_info2(image, parent_pool_name, ppool_namelen,
+                              parent_name, pnamelen, nullptr, 0,
+                              parent_snap_name, psnap_namelen);
+}
+
+extern "C" int rbd_get_parent_info2(rbd_image_t image,
+                                    char *parent_pool_name,
+                                    size_t ppool_namelen,
+                                    char *parent_name, size_t pnamelen,
+                                    char *parent_id, size_t pidlen,
+                                    char *parent_snap_name,
+                                    size_t psnap_namelen)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
-  tracepoint(librbd, get_parent_info_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only);
-  string p_pool_name, p_name, p_snap_name;
+  tracepoint(librbd, get_parent_info_enter, ictx, ictx->name.c_str(),
+             ictx->snap_name.c_str(), ictx->read_only);
+  string p_pool_name, p_name, p_id, p_snap_name;
 
-  int r = librbd::get_parent_info(ictx, &p_pool_name, &p_name, &p_snap_name);
+  int r = librbd::get_parent_info(ictx, &p_pool_name, &p_name, &p_id,
+                                  &p_snap_name);
   if (r < 0) {
-    tracepoint(librbd, get_parent_info_exit, r, NULL, NULL, NULL);
+    tracepoint(librbd, get_parent_info_exit, r, NULL, NULL, NULL, NULL);
     return r;
   }
 
   if (parent_pool_name) {
     if (p_pool_name.length() + 1 > ppool_namelen) {
-      tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL);
+      tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL, NULL);
       return -ERANGE;
     }
 
@@ -2848,22 +2876,31 @@ extern "C" int rbd_get_parent_info(rbd_image_t image,
   }
   if (parent_name) {
     if (p_name.length() + 1 > pnamelen) {
-      tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL);
+      tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL, NULL);
       return -ERANGE;
     }
 
     strcpy(parent_name, p_name.c_str());
   }
+  if (parent_id) {
+    if (p_id.length() + 1 > pidlen) {
+      tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL, NULL);
+      return -ERANGE;
+    }
+
+    strcpy(parent_id, p_id.c_str());
+  }
   if (parent_snap_name) {
     if (p_snap_name.length() + 1 > psnap_namelen) {
-      tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL);
+      tracepoint(librbd, get_parent_info_exit, -ERANGE, NULL, NULL, NULL, NULL);
       return -ERANGE;
     }
 
     strcpy(parent_snap_name, p_snap_name.c_str());
   }
 
-  tracepoint(librbd, get_parent_info_exit, 0, parent_pool_name, parent_name, parent_snap_name);
+  tracepoint(librbd, get_parent_info_exit, 0, parent_pool_name, parent_name,
+             parent_id, parent_snap_name);
   return 0;
 }
 
index 08d067bf5347934ce8231ba0110f589dee4e3039..3457fcc0a675a560b3c3401818fd1782905ddd3f 100644 (file)
@@ -229,10 +229,11 @@ cdef extern from "rbd/librbd.h" nogil:
     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)
-    int rbd_get_parent_info(rbd_image_t image,
-                            char *parent_poolname, size_t ppoolnamelen,
-                            char *parent_name, size_t pnamelen,
-                            char *parent_snapname, size_t psnapnamelen)
+    int rbd_get_parent_info2(rbd_image_t image,
+                             char *parent_poolname, size_t ppoolnamelen,
+                             char *parent_name, size_t pnamelen,
+                             char *parent_id, size_t pidlen,
+                             char *parent_snapname, size_t psnapnamelen)
     int rbd_get_flags(rbd_image_t image, uint64_t *flags)
     ssize_t rbd_read2(rbd_image_t image, uint64_t ofs, size_t len,
                       char *buf, int op_flags)
@@ -1506,8 +1507,8 @@ cdef class Image(object):
                 name = <char *>realloc_chk(name, size)
                 snapname = <char *>realloc_chk(snapname, size)
                 with nogil:
-                    ret = rbd_get_parent_info(self.image, pool, size, name,
-                                              size, snapname, size)
+                    ret = rbd_get_parent_info2(self.image, pool, size, name,
+                                               size, NULL, 0, snapname, size)
                 if ret == -errno.ERANGE:
                     size *= 2
 
@@ -1519,6 +1520,32 @@ cdef class Image(object):
             free(name)
             free(snapname)
 
+    def parent_id(self):
+        """
+        Get image id of a cloned image's parent (if any)
+
+        :returns: str - the parent id
+        :raises: :class:`ImageNotFound` if the image doesn't have a parent
+        """
+        cdef:
+            int ret = -errno.ERANGE
+            size_t size = 32
+            char *parent_id = NULL
+        try:
+            while ret == -errno.ERANGE and size <= 4096:
+                parent_id = <char *>realloc_chk(parent_id, size)
+                with nogil:
+                    ret = rbd_get_parent_info2(self.image, NULL, 0, NULL, 0,
+                                               parent_id, size, NULL, 0)
+                if ret == -errno.ERANGE:
+                    size *= 2
+
+            if ret != 0:
+                raise make_ex(ret, 'error getting parent id for image %s' % (self.name,))
+            return decode_cstr(parent_id)
+        finally:
+            free(parent_id)
+
     def old_format(self):
         """
         Find out whether the image uses the old RBD format.
index c3eb371d5e62317fb981d96ee678c380c91316bf..57c35fd82c81786d23a34c44cd27d02bc0f4e30e 100644 (file)
@@ -938,6 +938,7 @@ class TestClone(object):
         eq(pool, pool_name)
         eq(image, image_name)
         eq(snap, 'snap1')
+        eq(self.image.id(), self.clone.parent_id())
 
         # create a new pool...
         pool_name2 = get_temp_pool_name()
@@ -954,6 +955,7 @@ class TestClone(object):
         eq(pool, pool_name)
         eq(image, image_name)
         eq(snap, 'snap1')
+        eq(self.image.id(), self.other_clone.parent_id())
 
         # can't unprotect snap with children
         assert_raises(ImageBusy, self.image.unprotect_snap, 'snap1')
@@ -1127,6 +1129,8 @@ class TestClone(object):
                 clone.flatten()
                 assert_raises(ImageNotFound, clone.parent_info)
                 assert_raises(ImageNotFound, clone2.parent_info)
+                assert_raises(ImageNotFound, clone.parent_id)
+                assert_raises(ImageNotFound, clone2.parent_id)
                 after_flatten = clone.read(IMG_SIZE // 2, 256)
                 eq(data, after_flatten)
                 after_flatten = clone2.read(IMG_SIZE // 2, 256)
@@ -1220,6 +1224,7 @@ class TestExclusiveLock(object):
                 image1.write(data, 0)
                 image2.flatten()
                 assert_raises(ImageNotFound, image1.parent_info)
+                assert_raises(ImageNotFound, image1.parent_id)
                 parent = True
                 for x in range(30):
                     try:
index 95ccaa6695531e8268cc2931674c2b5a3bae1785..7078390daed9cf4079b6f9346a6d1b4c757c04b6 100644 (file)
@@ -1851,11 +1851,13 @@ TRACEPOINT_EVENT(librbd, get_parent_info_exit,
         int, retval,
         const char*, parent_pool_name,
         const char*, parent_name,
+        const char*, parent_id,
         const char*, parent_snap_name),
     TP_FIELDS(
         ctf_integer(int, retval, retval)
         ceph_ctf_string(parent_pool_name, parent_pool_name)
         ceph_ctf_string(parent_name, parent_name)
+        ceph_ctf_string(parent_id, parent_id)
         ceph_ctf_string(parent_snap_name, parent_snap_name)
     )
 )