}
// if stalled in request state machine -- abort
- handle_peer_notification();
+ handle_peer_notification(0);
}
template <typename I>
}
template <typename I>
-void ExclusiveLock<I>::handle_peer_notification() {
- Mutex::Locker locker(m_lock);
- if (m_state != STATE_WAITING_FOR_PEER) {
- return;
+void ExclusiveLock<I>::handle_peer_notification(int r) {
+ {
+ Mutex::Locker locker(m_lock);
+ if (m_state != STATE_WAITING_FOR_PEER) {
+ return;
+ }
+
+ ldout(m_image_ctx.cct, 10) << this << " " << __func__ << dendl;
+ assert(get_active_action() == ACTION_REQUEST_LOCK);
+
+ if (r >= 0) {
+ execute_next_action();
+ return;
+ }
}
- ldout(m_image_ctx.cct, 10) << this << " " << __func__ << dendl;
- assert(get_active_action() == ACTION_REQUEST_LOCK);
- execute_next_action();
+ handle_acquire_lock(r);
}
template <typename I>
{
m_lock.Lock();
assert(m_state == STATE_ACQUIRING ||
- m_state == STATE_POST_ACQUIRING);
+ m_state == STATE_POST_ACQUIRING ||
+ m_state == STATE_WAITING_FOR_PEER);
Action action = get_active_action();
assert(action == ACTION_TRY_LOCK || action == ACTION_REQUEST_LOCK);
if (action == ACTION_REQUEST_LOCK && r < 0 && r != -EBLACKLISTED &&
- r != -EPERM) {
+ r != -EPERM && r != -EROFS) {
m_state = STATE_WAITING_FOR_PEER;
m_lock.Unlock();
void reacquire_lock(Context *on_reacquired = nullptr);
- void handle_peer_notification();
+ void handle_peer_notification(int r);
static bool decode_lock_cookie(const std::string &cookie, uint64_t *handle);
<< dendl;
// treat this is a dead client -- so retest acquiring the lock
- m_image_ctx.exclusive_lock->handle_peer_notification();
+ m_image_ctx.exclusive_lock->handle_peer_notification(0);
+ } else if (r == -EROFS) {
+ ldout(m_image_ctx.cct, 5) << this << " peer will not release lock" << dendl;
+ m_image_ctx.exclusive_lock->handle_peer_notification(r);
} else if (r < 0) {
lderr(m_image_ctx.cct) << this << " error requesting lock: "
<< cpp_strerror(r) << dendl;
if (m_image_ctx.exclusive_lock != nullptr) {
// potentially wake up the exclusive lock state machine now that
// a lock owner has advertised itself
- m_image_ctx.exclusive_lock->handle_peer_notification();
+ m_image_ctx.exclusive_lock->handle_peer_notification(0);
}
if (cancel_async_requests &&
(m_image_ctx.exclusive_lock == nullptr ||
if (m_image_ctx.exclusive_lock != nullptr &&
!m_image_ctx.exclusive_lock->is_lock_owner()) {
m_task_finisher->cancel(TASK_CODE_REQUEST_LOCK);
- m_image_ctx.exclusive_lock->handle_peer_notification();
+ m_image_ctx.exclusive_lock->handle_peer_notification(0);
}
return true;
}
}
std::cout << m_id << ": acquiring exclusive lock" << std::endl;
- EXPECT_EQ(0, rbd_lock_acquire(m_image, RBD_LOCK_MODE_EXCLUSIVE));
+ int r;
+ do {
+ r = rbd_lock_acquire(m_image, RBD_LOCK_MODE_EXCLUSIVE);
+ if (r == -EROFS) {
+ usleep(1000);
+ }
+ } while (r == -EROFS);
+ EXPECT_EQ(0, r);
+
int lock_owner;
EXPECT_EQ(0, rbd_is_exclusive_lock_owner(m_image, &lock_owner));
EXPECT_TRUE(lock_owner);
void expect_notify_request_lock(MockExclusiveLockImageCtx &mock_image_ctx,
MockExclusiveLock &mock_exclusive_lock) {
EXPECT_CALL(*mock_image_ctx.image_watcher, notify_request_lock())
- .WillRepeatedly(Invoke(&mock_exclusive_lock,
- &MockExclusiveLock::handle_peer_notification));
+ .WillRepeatedly(Invoke([&mock_exclusive_lock]() {
+ mock_exclusive_lock.handle_peer_notification(0);
+ }));
}
void expect_notify_acquired_lock(MockExclusiveLockImageCtx &mock_image_ctx) {