]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: journaling unable request can not be sent to remote lock owner 23649/head
authorMykola Golub <mgolub@suse.com>
Mon, 20 Aug 2018 12:39:30 +0000 (15:39 +0300)
committerMykola Golub <mgolub@suse.com>
Mon, 20 Aug 2018 12:39:30 +0000 (15:39 +0300)
Fixes: http://tracker.ceph.com/issues/26939
Signed-off-by: Mykola Golub <mgolub@suse.com>
src/librbd/Operations.cc
src/test/librbd/test_librbd.cc

index b723a304db4ce6516d86efd5bb5f792ef7704870..531c1c0247d32f790c63fa764dccaa684658155d 100644 (file)
@@ -1365,12 +1365,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 950e008b306a26f9dd8384e974ce6eaddcc20c8a..c4b805baac0d898b77db3c4ef7eb14502bc91c7e 100644 (file)
@@ -4752,6 +4752,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);