}));
}
+template <typename I>
+void ManagedLock<I>::handle_no_op_reacquire_lock(int r) {
+ ldout(m_cct, 10) << "r=" << r << dendl;
+ assert(r >= 0);
+ complete_active_action(STATE_LOCKED, 0);
+}
+
template <typename I>
void ManagedLock<I>::handle_post_acquire_lock(int r) {
ldout(m_cct, 10) << "r=" << r << dendl;
if (m_cookie == m_new_cookie) {
ldout(m_cct, 10) << "skipping reacquire since cookie still valid"
<< dendl;
- complete_active_action(STATE_LOCKED, 0);
+ auto ctx = create_context_callback<
+ ManagedLock, &ManagedLock<I>::handle_no_op_reacquire_lock>(this);
+ post_reacquire_lock_handler(0, ctx);
return;
}
};
}
+struct MockMockManagedLock : public ManagedLock<MockManagedLockImageCtx> {
+ MockMockManagedLock(librados::IoCtx& ioctx, ContextWQ *work_queue,
+ const std::string& oid, librbd::MockImageWatcher *watcher,
+ managed_lock::Mode mode, bool blacklist_on_break_lock,
+ uint32_t blacklist_expire_seconds)
+ : ManagedLock<MockManagedLockImageCtx>(ioctx, work_queue, oid, watcher,
+ librbd::managed_lock::EXCLUSIVE, true, 0) {
+ };
+ virtual ~MockMockManagedLock() = default;
+ MOCK_METHOD2(post_reacquire_lock_handler, void(int, Context*));
+};
+
namespace managed_lock {
template<typename T>
.WillOnce(CompleteContext(0, (ContextWQ *)nullptr));
}
+ void expect_post_reacquired_lock_handler(MockImageWatcher& watcher,
+ MockMockManagedLock &managed_lock, uint64_t &client_id) {
+ expect_get_watch_handle(watcher);
+ EXPECT_CALL(managed_lock, post_reacquire_lock_handler(_, _))
+ .WillOnce(Invoke([&watcher, &client_id](int r, Context *on_finish){
+ if (r >= 0) {
+ client_id = 98765;
+ }
+ on_finish->complete(r);}));
+ }
+
int when_acquire_lock(MockManagedLock &managed_lock) {
C_SaferCond ctx;
{
ASSERT_FALSE(is_lock_owner(managed_lock));
}
+TEST_F(TestMockManagedLock, ReacquireWithSameCookie) {
+ librbd::ImageCtx *ictx;
+ ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+ MockManagedLockImageCtx mock_image_ctx(*ictx);
+ MockMockManagedLock managed_lock(ictx->md_ctx, ictx->op_work_queue,
+ ictx->header_oid, mock_image_ctx.image_watcher,
+ librbd::managed_lock::EXCLUSIVE, true, 0);
+ InSequence seq;
+
+ MockAcquireRequest request_lock_acquire;
+ expect_acquire_lock(*mock_image_ctx.image_watcher, ictx->op_work_queue, request_lock_acquire, 0);
+ ASSERT_EQ(0, when_acquire_lock(managed_lock));
+ ASSERT_TRUE(is_lock_owner(managed_lock));
+
+ // watcher with same cookie after rewatch
+ uint64_t client_id = 0;
+ C_SaferCond reacquire_ctx;
+ expect_post_reacquired_lock_handler(*mock_image_ctx.image_watcher, managed_lock, client_id);
+ managed_lock.reacquire_lock(&reacquire_ctx);
+ ASSERT_LT(0, client_id);
+ ASSERT_TRUE(is_lock_owner(managed_lock));
+
+ MockReleaseRequest shutdown_release;
+ expect_release_lock(ictx->op_work_queue, shutdown_release, 0);
+ //ASSERT_EQ(0, when_release_lock(managed_lock));
+ ASSERT_EQ(0, when_shut_down(managed_lock));
+}
+
} // namespace librbd