]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: journaling unable request can not be sent to remote lock owner 24100/head
authorMykola Golub <mgolub@suse.com>
Mon, 20 Aug 2018 12:39:30 +0000 (15:39 +0300)
committerPrashant D <pdhange@redhat.com>
Fri, 14 Sep 2018 03:59:01 +0000 (23:59 -0400)
Fixes: http://tracker.ceph.com/issues/26939
Signed-off-by: Mykola Golub <mgolub@suse.com>
(cherry picked from commit 985535bae74106aec1938813bdb18661967f468f)

src/librbd/Operations.cc
src/test/librbd/test_librbd.cc

index 6a1bd3ec0257e143cf7d35c50feda0f77a07c389..bc118915dc40777bbc1e12b5747771879fb149e2 100644 (file)
@@ -1314,12 +1314,31 @@ int Operations<I>::update_features(uint64_t features, bool enabled) {
     }
   };
 
-  r = invoke_async_request("update_features", false,
-                           boost::bind(&Operations<I>::execute_update_features,
-                                       this, features, enabled, _1, 0),
-                           boost::bind(&ImageWatcher<I>::notify_update_features,
-                                       m_image_ctx.image_watcher, features,
-                                       enabled, _1));
+  // The journal options are not passed to the lock owner in the
+  // update features request. Therefore, if journaling is being
+  // enabled, the lock should be locally acquired instead of
+  // attempting to send the request to the peer.
+  if (enabled && (features & RBD_FEATURE_JOURNALING) != 0) {
+    C_SaferCond cond_ctx;
+    {
+      RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
+      r = prepare_image_update(true);
+      if (r < 0) {
+        return -EROFS;
+      }
+
+      execute_update_features(features, enabled, &cond_ctx, 0);
+    }
+
+    r = cond_ctx.wait();
+  } else {
+    r = invoke_async_request("update_features", false,
+                             boost::bind(&Operations<I>::execute_update_features,
+                                         this, features, enabled, _1, 0),
+                             boost::bind(&ImageWatcher<I>::notify_update_features,
+                                         m_image_ctx.image_watcher, features,
+                                         enabled, _1));
+  }
   ldout(cct, 2) << "update_features finished" << dendl;
   return r;
 }
index 16509ae9caf30e54fc84b4dc446ae0022dc85013..67e348a40cdc9267497ba3ca6cbdc2ccd9e4018a 100644 (file)
@@ -4262,6 +4262,47 @@ TEST_F(TestLibRBD, SnapRemoveViaLockOwner)
   ASSERT_TRUE(lock_owner);
 }
 
+TEST_F(TestLibRBD, EnableJournalingViaLockOwner)
+{
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librados::IoCtx ioctx;
+  ASSERT_EQ(0, _rados.ioctx_create(m_pool_name.c_str(), ioctx));
+
+  librbd::RBD rbd;
+  std::string name = get_temp_image_name();
+  uint64_t size = 2 << 20;
+  int order = 0;
+  ASSERT_EQ(0, create_image_pp(rbd, ioctx, name.c_str(), size, &order));
+
+  librbd::Image image1;
+  ASSERT_EQ(0, rbd.open(ioctx, image1, name.c_str(), NULL));
+
+  bufferlist bl;
+  ASSERT_EQ(0, image1.write(0, 0, bl));
+
+  bool lock_owner;
+  ASSERT_EQ(0, image1.is_exclusive_lock_owner(&lock_owner));
+  ASSERT_TRUE(lock_owner);
+
+  librbd::Image image2;
+  ASSERT_EQ(0, rbd.open(ioctx, image2, name.c_str(), NULL));
+
+  ASSERT_EQ(0, image2.update_features(RBD_FEATURE_JOURNALING, false));
+
+  ASSERT_EQ(0, image1.is_exclusive_lock_owner(&lock_owner));
+  ASSERT_TRUE(lock_owner);
+  ASSERT_EQ(0, image2.is_exclusive_lock_owner(&lock_owner));
+  ASSERT_FALSE(lock_owner);
+
+  ASSERT_EQ(0, image2.update_features(RBD_FEATURE_JOURNALING, true));
+
+  ASSERT_EQ(0, image1.is_exclusive_lock_owner(&lock_owner));
+  ASSERT_FALSE(lock_owner);
+  ASSERT_EQ(0, image2.is_exclusive_lock_owner(&lock_owner));
+  ASSERT_TRUE(lock_owner);
+}
+
 TEST_F(TestLibRBD, SnapRemove2)
 {
   REQUIRE_FEATURE(RBD_FEATURE_LAYERING);