]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: Stub out new exclusive image feature
authorJason Dillaman <dillaman@redhat.com>
Tue, 7 Oct 2014 18:17:50 +0000 (14:17 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 8 Jan 2015 02:25:04 +0000 (21:25 -0500)
When an image is flagged with the exclusive feature, only a
single client can modify the image.  This is groundwork for
an RBD object map optimization and for RBD mirroring.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/common/config_opts.h
src/include/rbd/features.h
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/librbd.cc
src/pybind/rbd.py
src/rbd.cc
src/test/pybind/test_rbd.py
src/test/run-rbd-tests
src/tracing/librbd.tp

index 23f62ab6161067ce59f5e969b6c351ade96134c3..af432d905e12a482c4fd2283402f45f7cd1974c6 100644 (file)
@@ -843,7 +843,9 @@ OPTION(rbd_default_format, OPT_INT, 1)
 OPTION(rbd_default_order, OPT_INT, 22)
 OPTION(rbd_default_stripe_count, OPT_U64, 0) // changing requires stripingv2 feature
 OPTION(rbd_default_stripe_unit, OPT_U64, 0) // changing to non-object size requires stripingv2 feature
-OPTION(rbd_default_features, OPT_INT, 3) // 1 for layering, 3 for layering+stripingv2. only applies to format 2 images
+OPTION(rbd_default_features, OPT_INT, 7) // only applies to format 2 images
+                                        // +1 for layering, +2 for stripingv2,
+                                        // +4 for exclusive lock
 
 OPTION(nss_db_path, OPT_STR, "") // path to nss db
 
index 3f1587f3b40ae6c245d53c3473d8c7981e9222da..9b28b5749953693fe22d430030fa67526260bf0d 100644 (file)
@@ -1,10 +1,13 @@
 #ifndef CEPH_RBD_FEATURES_H
 #define CEPH_RBD_FEATURES_H
 
-#define RBD_FEATURE_LAYERING      (1<<0)
-#define RBD_FEATURE_STRIPINGV2    (1<<1)
+#define RBD_FEATURE_LAYERING           (1<<0)
+#define RBD_FEATURE_STRIPINGV2         (1<<1)
+#define RBD_FEATURE_EXCLUSIVE_LOCK     (1<<2)
 
-#define RBD_FEATURES_INCOMPATIBLE (RBD_FEATURE_LAYERING|RBD_FEATURE_STRIPINGV2)
-#define RBD_FEATURES_ALL          (RBD_FEATURE_LAYERING|RBD_FEATURE_STRIPINGV2)
+#define RBD_FEATURES_INCOMPATIBLE (RBD_FEATURE_LAYERING|RBD_FEATURE_STRIPINGV2|\
+                                   RBD_FEATURE_EXCLUSIVE_LOCK)
+#define RBD_FEATURES_ALL          (RBD_FEATURE_LAYERING|RBD_FEATURE_STRIPINGV2|\
+                                   RBD_FEATURE_EXCLUSIVE_LOCK)
 
 #endif
index 5ff8733b65f9d1d52370ef61c339f4ecfdc79979..8d7f23ff2c95e3bd1d457e7268a10a6e3e232a85 100644 (file)
@@ -155,6 +155,10 @@ CEPH_RBD_API int rbd_get_parent_info(rbd_image_t image,
                                     char *parent_name, size_t pnamelen,
                                     char *parent_snapname,
                                      size_t psnapnamelen);
+
+/* exclusive lock feature */
+CEPH_RBD_API int rbd_is_exclusive_lock_owner(rbd_image_t image, int *is_owner);
+
 CEPH_RBD_API int rbd_copy(rbd_image_t image, rados_ioctx_t dest_io_ctx,
                           const char *destname);
 CEPH_RBD_API int rbd_copy2(rbd_image_t src, rbd_image_t dest);
index 6b8712fef1813fc86ae06a10b22f6f77bee59fc9..b6be508a69b316453bf57f710160580222833701 100644 (file)
@@ -117,6 +117,10 @@ public:
   int size(uint64_t *size);
   int features(uint64_t *features);
   int overlap(uint64_t *overlap);
+
+  /* exclusive lock feature */
+  int is_exclusive_lock_owner(bool *is_owner);
+
   int copy(IoCtx& dest_io_ctx, const char *destname);
   int copy2(Image& dest);
   int copy_with_progress(IoCtx& dest_io_ctx, const char *destname,
index efbd24d66673c69b2c2089df7c9d83c82b036d5d..dc60ba94c0b1f1af2ed76bf3b31c58abc1e8dce7 100644 (file)
@@ -358,6 +358,17 @@ namespace librbd {
     return r;
   }
 
+  int Image::is_exclusive_lock_owner(bool *is_owner)
+  {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    tracepoint(librbd, is_exclusive_lock_owner_enter, ictx);
+    // TODO: implement
+    int r = 0;
+    *is_owner = false;
+    tracepoint(librbd, is_exclusive_lock_owner_exit, ictx, r, *is_owner);
+    return r;
+  }
+
   int Image::copy(IoCtx& dest_io_ctx, const char *destname)
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
@@ -1163,6 +1174,17 @@ extern "C" int rbd_get_parent_info(rbd_image_t image,
   return 0;
 }
 
+extern "C" int rbd_is_exclusive_lock_owner(rbd_image_t image, int *is_owner)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  tracepoint(librbd, is_exclusive_lock_owner_enter, ictx);
+  // TODO implement
+  int r = 0;
+  *is_owner = 0;
+  tracepoint(librbd, is_exclusive_lock_owner_exit, ictx, r, *is_owner);
+  return r;
+}
+
 /* snapshots */
 extern "C" int rbd_snap_create(rbd_image_t image, const char *snap_name)
 {
index 3d86cd881b64d0db12709417b32c89b32f2aa80f..a91f7c84d8ddc5c05bc45f5c58286c78fbf19cc1 100644 (file)
@@ -27,6 +27,7 @@ ADMIN_AUID = 0
 
 RBD_FEATURE_LAYERING = 1
 RBD_FEATURE_STRIPINGV2 = 2
+RBD_FEATURE_EXCLUSIVE_LOCK = 4
 
 class Error(Exception):
     pass
@@ -524,6 +525,13 @@ class Image(object):
             raise make_ex(ret, 'error getting overlap for image' % (self.name))
         return overlap.value
 
+    def is_exclusive_lock_owner(self):
+        owner = c_int()
+        ret = self.librbd.rbd_is_exclusive_lock_owner(self.image, byref(owner))
+        if (ret != 0):
+            raise make_ex(ret, 'error getting lock status for image' % (self.name))
+        return owner.value == 1
+
     def copy(self, dest_ioctx, dest_name):
         """
         Copy the image to another location.
index 26cb589dc1f1f828042301973ffb1552d1e187e4..3e60aeff537915fe0219064fabc2e059305f8edb 100644 (file)
@@ -165,6 +165,8 @@ static string feature_str(uint64_t feature)
     return "layering";
   case RBD_FEATURE_STRIPINGV2:
     return "striping";
+  case RBD_FEATURE_EXCLUSIVE_LOCK:
+    return "exclusive";
   default:
     return "";
   }
@@ -174,7 +176,7 @@ static string features_str(uint64_t features)
 {
   string s = "";
 
-  for (uint64_t feature = 1; feature <= RBD_FEATURE_STRIPINGV2;
+  for (uint64_t feature = 1; feature <= RBD_FEATURE_EXCLUSIVE_LOCK;
        feature <<= 1) {
     if (feature & features) {
       if (s.size())
@@ -188,7 +190,7 @@ static string features_str(uint64_t features)
 static void format_features(Formatter *f, uint64_t features)
 {
   f->open_array_section("features");
-  for (uint64_t feature = 1; feature <= RBD_FEATURE_STRIPINGV2;
+  for (uint64_t feature = 1; feature <= RBD_FEATURE_EXCLUSIVE_LOCK;
        feature <<= 1) {
     f->dump_string("feature", feature_str(feature));
   }
@@ -428,7 +430,7 @@ static int do_create(librbd::RBD &rbd, librados::IoCtx& io_ctx,
     r = rbd.create(io_ctx, imgname, size, order);
   } else {
     if (features == 0) {
-      features = RBD_FEATURE_LAYERING;
+      features = RBD_FEATURE_LAYERING | RBD_FEATURE_EXCLUSIVE_LOCK;
     }
     if ((stripe_unit || stripe_count) &&
        (stripe_unit != (1ull << *order) && stripe_count != 1)) {
index 72d435d9e743df84baa87f808bd4c44643081b10..e9bccfffb3ebcd1ae0134a96943d07665ece09d9 100644 (file)
@@ -1,16 +1,19 @@
+# vim: expandtab smarttab shiftwidth=4 softtabstop=4
 import functools
 import random
 import socket
 import struct
 import os
 
+from contextlib import nested
 from nose import with_setup, SkipTest
 from nose.tools import eq_ as eq, assert_raises
 from rados import Rados
 from rbd import (RBD, Image, ImageNotFound, InvalidArgument, ImageExists,
                  ImageBusy, ImageHasSnapshots, ReadOnlyImage,
                  FunctionNotSupported, ArgumentOutOfRange,
-                 RBD_FEATURE_LAYERING, RBD_FEATURE_STRIPINGV2)
+                 RBD_FEATURE_LAYERING, RBD_FEATURE_STRIPINGV2,
+                 RBD_FEATURE_EXCLUSIVE_LOCK)
 
 
 rados = None
@@ -121,7 +124,7 @@ def check_default_params(format, order=None, features=None, stripe_count=None,
 
                     expected_features = features
                     if expected_features is None or format == 1:
-                        expected_features = 0 if format == 1 else 3
+                        expected_features = 0 if format == 1 else 7
                     eq(expected_features, image.features())
 
                     expected_stripe_count = stripe_count
@@ -888,3 +891,27 @@ class TestClone(object):
         self.rbd.remove(ioctx, clone_name3)
         self.clone.unprotect_snap('snap2')
         self.clone.remove_snap('snap2')
+
+class TestExclusiveLock(object):
+
+    @require_features([RBD_FEATURE_EXCLUSIVE_LOCK])
+    def setUp(self):
+        global rados2
+        rados2 = Rados(conffile='')
+        rados2.connect()
+        global ioctx2
+        ioctx2 = rados2.open_ioctx(pool_name)
+        create_image()
+
+    def tearDown(self):
+        remove_image()
+        global ioctx2
+        ioctx2.__del__()
+        global rados2
+        rados2.shutdown()
+
+    def test_ownership(self):
+        with nested(Image(ioctx, image_name), Image(ioctx2, image_name)) as (
+                image1, image2):
+            eq(image1.is_exclusive_lock_owner(), False)
+            eq(image2.is_exclusive_lock_owner(), False)
index c06c11e8e61e48ddb2e7e5506819a185d4dede61..7cf9159b3eed19fb2abfd6086c6bb60573bb792a 100755 (executable)
@@ -35,7 +35,7 @@ run_cli_tests
 RBD_CREATE_ARGS="--format 2"
 run_cli_tests
 
-for i in 0 1
+for i in 0 1 5
 do
     RBD_FEATURES=$i
     run_api_tests
index b18156bb3deb775b5ef03620e9eaeb8fe8aaa60e..6b0580ac6a8326d99bdb6bfd4f0a3ceabec60686 100644 (file)
@@ -1393,6 +1393,26 @@ TRACEPOINT_EVENT(librbd, get_old_format_exit,
     )
 )
 
+TRACEPOINT_EVENT(librbd, is_exclusive_lock_owner_enter,
+    TP_ARGS(
+        void*, imagectx),
+    TP_FIELDS(
+      ctf_integer_hex(void*, imagectx, imagectx)
+    )
+)
+
+TRACEPOINT_EVENT(librbd, is_exclusive_lock_owner_exit,
+    TP_ARGS(
+        void*, imagectx,
+        int, retval,
+        char, is_owner),
+    TP_FIELDS(
+      ctf_integer_hex(void*, imagectx, imagectx)
+      ctf_integer(int, retval, retval)
+      ctf_integer(char, is_owner, is_owner)
+    )
+)
+
 TRACEPOINT_EVENT(librbd, stat_enter,
     TP_ARGS(
         void*, imagectx,