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) {
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));
}
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());
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;
-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);