]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: added get_flags API methods
authorJason Dillaman <dillaman@redhat.com>
Tue, 3 Feb 2015 04:24:09 +0000 (23:24 -0500)
committerJason Dillaman <dillaman@redhat.com>
Tue, 3 Feb 2015 04:24:09 +0000 (23:24 -0500)
Exposed the RBD image flags bitmask through the API via
new methods in the C/C++/Python RBD APIs.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/ImageCtx.cc
src/librbd/ImageCtx.h
src/librbd/SnapInfo.h
src/librbd/internal.cc
src/librbd/internal.h
src/librbd/librbd.cc
src/pybind/rbd.py
src/test/pybind/test_rbd.py
src/tracing/librbd.tp

index b94faff149ffd9114d9fa8c6a8380f8ce11d20b3..625d472b537128cbd22c6e625d3d24624a5e40e7 100644 (file)
@@ -157,6 +157,7 @@ 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_flags(rbd_image_t image, uint64_t *flags);
 
 /* exclusive lock feature */
 CEPH_RBD_API int rbd_is_exclusive_lock_owner(rbd_image_t image, int *is_owner);
index b6be508a69b316453bf57f710160580222833701..569fc77db94ca8509f5e88288f40cc52f1fb95ac 100644 (file)
@@ -117,6 +117,7 @@ public:
   int size(uint64_t *size);
   int features(uint64_t *features);
   int overlap(uint64_t *overlap);
+  int get_flags(uint64_t *flags);
 
   /* exclusive lock feature */
   int is_exclusive_lock_owner(bool *is_owner);
index 398b49b69dbbb5e35ee365a51a88f0f37483c0c0..9882634108da43750cb912cd1bcf3f857a2e724c 100644 (file)
@@ -415,12 +415,12 @@ namespace librbd {
   }
 
   void ImageCtx::add_snap(string in_snap_name, snap_t id, uint64_t in_size,
-                         uint64_t features,
-                         parent_info parent,
-                         uint8_t protection_status)
+                         uint64_t features, parent_info parent,
+                         uint8_t protection_status, uint64_t flags)
   {
     snaps.push_back(id);
-    SnapInfo info(in_snap_name, in_size, features, parent, protection_status);
+    SnapInfo info(in_snap_name, in_size, features, parent, protection_status,
+                 flags);
     snap_info.insert(pair<snap_t, SnapInfo>(id, info));
     snap_ids.insert(pair<string, snap_t>(in_snap_name, id));
   }
@@ -452,6 +452,20 @@ namespace librbd {
     return -ENOENT;
   }
 
+  int ImageCtx::get_flags(librados::snap_t _snap_id, uint64_t *_flags) const
+  {
+    if (_snap_id == CEPH_NOSNAP) {
+      *_flags = flags;
+      return 0;
+    }
+    const SnapInfo *info = get_snap_info(_snap_id);
+    if (info) {
+      *_flags = info->flags;
+      return 0;
+    }
+    return -ENOENT;
+  }
+
   const parent_info* ImageCtx::get_parent_info(snap_t in_snap_id) const
   {
     if (in_snap_id == CEPH_NOSNAP)
index 5dd5b8adbf9f9724e05bae3f1ce9fd1dde03d912..13a5bfc2fffb5a32c67b6c89a452d73998b69de9 100644 (file)
@@ -151,10 +151,12 @@ namespace librbd {
 
     void add_snap(std::string in_snap_name, librados::snap_t id,
                  uint64_t in_size, uint64_t features,
-                 parent_info parent, uint8_t protection_status);
+                 parent_info parent, uint8_t protection_status,
+                 uint64_t flags);
     uint64_t get_image_size(librados::snap_t in_snap_id) const;
     int get_features(librados::snap_t in_snap_id,
                     uint64_t *out_features) const;
+    int get_flags(librados::snap_t in_snap_id, uint64_t *flags) const;
     const parent_info* get_parent_info(librados::snap_t in_snap_id) const;
     int64_t get_parent_pool_id(librados::snap_t in_snap_id) const;
     std::string get_parent_image_id(librados::snap_t in_snap_id) const;
index fd973536d872a4dac050b2fde3472922f977f82e..a3307ff49075a6172bda7339860f3482c1a8d7bb 100644 (file)
@@ -18,10 +18,11 @@ namespace librbd {
     uint64_t features;
     parent_info parent;
     uint8_t protection_status;
+    uint64_t flags;
     SnapInfo(std::string _name, uint64_t _size, uint64_t _features,
-            parent_info _parent, uint8_t _protection_status) :
-      name(_name), size(_size), features(_features), parent(_parent),
-      protection_status(_protection_status) {}
+            parent_info _parent, uint8_t _protection_status, uint64_t _flags)
+      name(_name), size(_size), features(_features), parent(_parent),
+       protection_status(_protection_status), flags(_flags) {}
   };
 }
 
index 285f0551eebe7fd60fd9968b16178ea4303a4626..1d6c914372f49ea9f064108116ae3867d39dfa38 100644 (file)
@@ -1452,6 +1452,18 @@ reprotect_and_return_err:
     return 0;
   }
 
+  int get_flags(ImageCtx *ictx, uint64_t *flags)
+  {
+    int r = ictx_check(ictx);
+    if (r < 0) {
+      return r;
+    }
+
+    RWLock::RLocker l(ictx->md_lock);
+    RWLock::RLocker l2(ictx->snap_lock);
+    return ictx->get_flags(ictx->snap_id, flags);
+  }
+
   int is_exclusive_lock_owner(ImageCtx *ictx, bool *is_owner)
   {
     RWLock::RLocker l(ictx->owner_lock);
@@ -1851,6 +1863,7 @@ reprotect_and_return_err:
     vector<uint64_t> snap_features;
     vector<parent_info> snap_parents;
     vector<uint8_t> snap_protection;
+    vector<uint64_t> snap_flags;
     {
       int r;
       RWLock::WLocker l(ictx->snap_lock);
@@ -1918,31 +1931,33 @@ reprotect_and_return_err:
              return -ENOSYS;
            }
 
-            r = cls_client::get_flags(&ictx->md_ctx, ictx->header_oid,
-                                      ictx->snap_id, &ictx->flags);
+           r = cls_client::get_flags(&ictx->md_ctx, ictx->header_oid,
+                                     &ictx->flags, new_snapc.snaps,
+                                     &snap_flags);
             if (r == -EOPNOTSUPP || r == -EIO) {
               // Older OSD doesn't support RBD flags, need to assume the worst
               ldout(ictx->cct, 10) << "OSD does not support RBD flags" << dendl;
-            } else if (r == -ENOENT) {
-              ldout(ictx->cct, 10) << "Image at invalid snapshot" << dendl;
-            } else if (r < 0 && r != -ENOENT) {
-              lderr(cct) << "Error reading flags: " << cpp_strerror(r) << dendl;
-              return r;
-            }
-            if (r < 0) {
               ictx->flags = 0;
               if ((ictx->features & RBD_FEATURE_OBJECT_MAP) != 0) {
                 ldout(ictx->cct, 10) << "disabling object map optimizations"
                                      << dendl;
                 ictx->flags |= RBD_FLAG_OBJECT_MAP_INVALID;
               }
+
+             vector<uint64_t> default_flags(new_snapc.snaps.size(), ictx->flags);
+             snap_flags.swap(default_flags);
+            } else if (r == -ENOENT) {
+              ldout(ictx->cct, 10) << "Image at invalid snapshot" << dendl;
+             continue;
+            } else if (r < 0) {
+              lderr(cct) << "Error reading flags: " << cpp_strerror(r) << dendl;
+              return r;
             }
 
            r = cls_client::snapshot_list(&(ictx->md_ctx), ictx->header_oid,
                                          new_snapc.snaps, &snap_names,
                                          &snap_sizes, &snap_features,
-                                         &snap_parents,
-                                         &snap_protection);
+                                         &snap_parents, &snap_protection);
            // -ENOENT here means we raced with snapshot deletion
            if (r < 0 && r != -ENOENT) {
              lderr(ictx->cct) << "snapc = " << new_snapc << dendl;
@@ -1975,13 +1990,14 @@ reprotect_and_return_err:
        ictx->snap_ids.clear();
        for (size_t i = 0; i < new_snapc.snaps.size(); ++i) {
          uint64_t features = ictx->old_format ? 0 : snap_features[i];
+         uint64_t flags = ictx->old_format ? 0 : snap_flags[i];
          uint8_t protection_status = ictx->old_format ?
            (uint8_t)RBD_PROTECTION_STATUS_UNPROTECTED : snap_protection[i];
          parent_info parent;
          if (!ictx->old_format)
            parent = snap_parents[i];
-         ictx->add_snap(snap_names[i], new_snapc.snaps[i].val,
-                        snap_sizes[i], features, parent, protection_status);
+         ictx->add_snap(snap_names[i], new_snapc.snaps[i].val, snap_sizes[i],
+                        features, parent, protection_status, flags);
        }
 
        r = refresh_parent(ictx);
index 9984b4b663daa0d0c74a8e27f8b4cc11b2a2607c..1e6f790b2da6dd01544ac59ae3032a746a8fa86c 100644 (file)
@@ -104,6 +104,7 @@ namespace librbd {
   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);
+  int get_flags(ImageCtx *ictx, uint64_t *flags);
   int is_exclusive_lock_owner(ImageCtx *ictx, bool *is_owner);
 
   int remove(librados::IoCtx& io_ctx, const char *imgname,
index f2d3dd92d4054224152d8dd22b95590cdf539f46..2d1e56777a396172fb140fa4e517b4a886342f7b 100644 (file)
@@ -360,6 +360,15 @@ namespace librbd {
     return r;
   }
 
+  int Image::get_flags(uint64_t *flags)
+  {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    tracepoint(librbd, get_flags_enter, ictx);
+    int r = librbd::get_flags(ictx, flags);
+    tracepoint(librbd, get_flags_exit, ictx, r, *flags);
+    return r;
+  }
+
   int Image::is_exclusive_lock_owner(bool *is_owner)
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
@@ -1175,6 +1184,15 @@ extern "C" int rbd_get_parent_info(rbd_image_t image,
   return 0;
 }
 
+extern "C" int rbd_get_flags(rbd_image_t image, uint64_t *flags)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  tracepoint(librbd, get_flags_enter, ictx);
+  int r = librbd::get_flags(ictx, flags);
+  tracepoint(librbd, get_flags_exit, ictx, r, *flags);
+  return r;
+}
+
 extern "C" int rbd_is_exclusive_lock_owner(rbd_image_t image, int *is_owner)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
index a91f7c84d8ddc5c05bc45f5c58286c78fbf19cc1..82f5033e41deab37c862bfbf4ac70b2d527aa7a3 100644 (file)
@@ -29,6 +29,8 @@ RBD_FEATURE_LAYERING = 1
 RBD_FEATURE_STRIPINGV2 = 2
 RBD_FEATURE_EXCLUSIVE_LOCK = 4
 
+RBD_FLAG_OBJECT_MAP_INVALID = 1
+
 class Error(Exception):
     pass
 
@@ -525,7 +527,24 @@ class Image(object):
             raise make_ex(ret, 'error getting overlap for image' % (self.name))
         return overlap.value
 
+    def flags(self):
+        """
+        Gets the flags bitmask of the image.
+
+        :returns: int - the flags bitmask of the image
+        """
+        flags = c_uint64()
+        reg = self.librbd.rbd_get_flags(self.image, byref(flags))
+        if (ret != 0):
+            raise make_ex(ret, 'error getting flags for image' % (self.name))
+        return flags.value
+
     def is_exclusive_lock_owner(self):
+        """
+        Gets the status of the image exclusive lock.
+
+        :returns: bool - true if the image is exclusively locked
+        """
         owner = c_int()
         ret = self.librbd.rbd_is_exclusive_lock_owner(self.image, byref(owner))
         if (ret != 0):
index 985bcf0c408bfbc9a8282f312406eef31e6994d6..84d5902623b09d429065104726667bf266d99b95 100644 (file)
@@ -292,6 +292,10 @@ class TestImage(object):
         info = self.image.stat()
         check_stat(info, IMG_SIZE, IMG_ORDER)
 
+    def test_flags(self):
+        flags = self.image.flags()
+        eq(0, flags)
+
     def test_write(self):
         data = rand_data(256)
         self.image.write(data, 0)
index 6b0580ac6a8326d99bdb6bfd4f0a3ceabec60686..bc0b662cc21d5f32d392de5aedda8708168e16dc 100644 (file)
@@ -1393,6 +1393,26 @@ TRACEPOINT_EVENT(librbd, get_old_format_exit,
     )
 )
 
+TRACEPOINT_EVENT(librbd, get_flags_enter,
+    TP_ARGS(
+        void*, imagectx),
+    TP_FIELDS(
+      ctf_integer_hex(void*, imagectx, imagectx)
+    )
+)
+
+TRACEPOINT_EVENT(librbd, get_flags_exit,
+    TP_ARGS(
+        void*, imagectx,
+        int, retval,
+        uint64_t, flags),
+    TP_FIELDS(
+      ctf_integer_hex(void*, imagectx, imagectx)
+      ctf_integer(int, retval, retval)
+      ctf_integer(uint64_t, flags, flags)
+    )
+)
+
 TRACEPOINT_EVENT(librbd, is_exclusive_lock_owner_enter,
     TP_ARGS(
         void*, imagectx),