]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: reacquire lock should update lock owner client id 15093/head
authorJason Dillaman <dillaman@redhat.com>
Mon, 15 May 2017 16:12:12 +0000 (12:12 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 15 May 2017 16:12:12 +0000 (12:12 -0400)
Fixes: http://tracker.ceph.com/issues/19929
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/ExclusiveLock.cc
src/librbd/ExclusiveLock.h
src/librbd/ManagedLock.cc
src/librbd/ManagedLock.h
src/test/librbd/test_mock_ExclusiveLock.cc

index 19ca6e42e1306cf66d9799396f4d1100ab7a9504..a6f8b08cf36cbbf2237f9bfa4e0e4704aa7f3973 100644 (file)
@@ -293,6 +293,16 @@ void ExclusiveLock<I>::post_release_lock_handler(bool shutting_down, int r,
   on_finish->complete(r);
 }
 
+template <typename I>
+void ExclusiveLock<I>::post_reacquire_lock_handler(int r, Context *on_finish) {
+  ldout(m_image_ctx.cct, 10) << dendl;
+  if (r >= 0) {
+    m_image_ctx.image_watcher->notify_acquired_lock();
+  }
+
+  on_finish->complete(r);
+}
+
 template <typename I>
 struct ExclusiveLock<I>::C_InitComplete : public Context {
   ExclusiveLock *exclusive_lock;
index 092f7094a6c6ffb78c5ed3e1bf4bc9ad4e479008..7b2e63c2bcbdce0edef9a29f0f72e40e8f1fd6ba 100644 (file)
@@ -36,6 +36,7 @@ protected:
                                 Context *on_finish) override;
   void post_release_lock_handler(bool shutting_down, int r,
                                  Context *on_finish) override;
+  void post_reacquire_lock_handler(int r, Context *on_finish) override;
 
 private:
 
index 71f5dab4df6508bbc7a80c9993ee17f701fa5190..ee321bf93adea28662eaf0e749f4cfacd55b894d 100644 (file)
@@ -329,6 +329,11 @@ void  ManagedLock<I>::post_release_lock_handler(bool shutting_down, int r,
   on_finish->complete(r);
 }
 
+template <typename I>
+void ManagedLock<I>::post_reacquire_lock_handler(int r, Context *on_finish) {
+  on_finish->complete(r);
+}
+
 template <typename I>
 bool ManagedLock<I>::is_transition_state() const {
   switch (m_state) {
@@ -565,11 +570,15 @@ void ManagedLock<I>::send_reacquire_lock() {
   ldout(m_cct, 10) << dendl;
   m_state = STATE_REACQUIRING;
 
+  auto ctx = create_context_callback<
+    ManagedLock, &ManagedLock<I>::handle_reacquire_lock>(this);
+  ctx = new FunctionContext([this, ctx](int r) {
+      post_reacquire_lock_handler(r, ctx);
+    });
+
   using managed_lock::ReacquireRequest;
   ReacquireRequest<I>* req = ReacquireRequest<I>::create(m_ioctx, m_oid,
-      m_cookie, m_new_cookie, m_mode == EXCLUSIVE,
-      create_context_callback<
-        ManagedLock, &ManagedLock<I>::handle_reacquire_lock>(this));
+      m_cookie, m_new_cookie, m_mode == EXCLUSIVE, ctx);
   m_work_queue->queue(new C_SendLockRequest<ReacquireRequest<I>>(req));
 }
 
index d18cfbef15602cf418b8be6ddadf5de86388d1b7..c619f4823dd226adc5776c454b76b9019c38396e 100644 (file)
@@ -134,6 +134,7 @@ protected:
                                         Context *on_finish);
   virtual void post_release_lock_handler(bool shutting_down, int r,
                                           Context *on_finish);
+  virtual void post_reacquire_lock_handler(int r, Context *on_finish);
 
   void execute_next_action();
 
index f593f834803e5438ff77e83b2731959ff3809055..eeb62f63ea5d2a5370b20a971b09f1cec865720e 100644 (file)
@@ -52,6 +52,7 @@ struct ManagedLock<MockExclusiveLockImageCtx> {
   virtual void post_acquire_lock_handler(int, Context *) = 0;
   virtual void pre_release_lock_handler(bool, Context *) = 0;
   virtual void post_release_lock_handler(bool, int, Context *) = 0;
+  virtual void post_reacquire_lock_handler(int, Context *) = 0;
 
   MOCK_CONST_METHOD0(is_lock_owner, bool());
 
@@ -322,6 +323,12 @@ public:
     return ctx.wait();
   }
 
+  int when_post_reacquire_lock_handler(MockManagedLock &managed_lock, int r) {
+    C_SaferCond ctx;
+    managed_lock.post_reacquire_lock_handler(r, &ctx);
+    return ctx.wait();
+  }
+
   int when_shut_down(MockExclusiveLockImageCtx &mock_image_ctx,
                      MockExclusiveLock &exclusive_lock) {
     C_SaferCond ctx;
@@ -599,6 +606,52 @@ TEST_F(TestMockExclusiveLock, PreReleaseLockError) {
                                                     -EINVAL));
 }
 
+TEST_F(TestMockExclusiveLock, ReacquireLock) {
+  REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockExclusiveLockImageCtx mock_image_ctx(*ictx);
+  MockExclusiveLock exclusive_lock(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  expect_set_state_initializing(exclusive_lock);
+  expect_block_writes(mock_image_ctx);
+  expect_set_state_unlocked(exclusive_lock);
+  ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock));
+
+  // (try) acquire lock
+  MockPreAcquireRequest try_lock_pre_acquire;
+  expect_pre_acquire_request(try_lock_pre_acquire, 0);
+  ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock));
+
+  MockPostAcquireRequest try_lock_post_acquire;
+  expect_post_acquire_request(try_lock_post_acquire, 0);
+  expect_is_state_acquiring(exclusive_lock, true);
+  expect_notify_acquired_lock(mock_image_ctx);
+  expect_unblock_writes(mock_image_ctx);
+  ASSERT_EQ(0, when_post_acquire_lock_handler(exclusive_lock, 0));
+
+  // reacquire lock
+  expect_notify_acquired_lock(mock_image_ctx);
+  ASSERT_EQ(0, when_post_reacquire_lock_handler(exclusive_lock, 0));
+
+  // shut down (and release)
+  expect_shut_down(exclusive_lock);
+  expect_is_state_waiting_for_lock(exclusive_lock, false);
+  ASSERT_EQ(0, when_shut_down(mock_image_ctx, exclusive_lock));
+
+  MockPreReleaseRequest shutdown_pre_release;
+  expect_pre_release_request(shutdown_pre_release, 0);
+  ASSERT_EQ(0, when_pre_release_lock_handler(exclusive_lock, true));
+
+  expect_unblock_writes(mock_image_ctx);
+  expect_notify_released_lock(mock_image_ctx);
+  ASSERT_EQ(0, when_post_release_lock_handler(exclusive_lock, true, 0));
+}
+
 TEST_F(TestMockExclusiveLock, BlockRequests) {
   REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);