expect_construct(mock_managed_lock);
MockLeaderWatcher leader_watcher(m_mock_threads, m_local_io_ctx, &listener);
- // Inint
+ // Init
+ expect_init(mock_mirror_status_watcher, 0);
C_SaferCond on_heartbeat_finish;
expect_is_leader(mock_managed_lock, false, false);
expect_try_acquire_lock(mock_managed_lock, 0);
- expect_init(mock_mirror_status_watcher, 0);
expect_init(mock_instances, 0);
expect_acquire_notify(mock_managed_lock, listener, 0);
expect_notify_heartbeat(mock_managed_lock, &on_heartbeat_finish);
// Shutdown
expect_release_notify(mock_managed_lock, listener, 0);
expect_shut_down(mock_instances, 0);
- expect_shut_down(mock_mirror_status_watcher, 0);
- expect_is_leader(mock_managed_lock, false, false);
expect_release_lock(mock_managed_lock, 0);
expect_shut_down(mock_managed_lock, true, 0);
+ expect_shut_down(mock_mirror_status_watcher, 0);
expect_is_leader(mock_managed_lock, false, false);
leader_watcher.shut_down();
expect_construct(mock_managed_lock);
MockLeaderWatcher leader_watcher(m_mock_threads, m_local_io_ctx, &listener);
- // Inint
+ // Init
+ expect_init(mock_mirror_status_watcher, 0);
C_SaferCond on_heartbeat_finish;
expect_is_leader(mock_managed_lock, false, false);
expect_try_acquire_lock(mock_managed_lock, 0);
- expect_init(mock_mirror_status_watcher, 0);
expect_init(mock_instances, 0);
expect_acquire_notify(mock_managed_lock, listener, 0);
expect_notify_heartbeat(mock_managed_lock, &on_heartbeat_finish);
expect_is_leader(mock_managed_lock, false, true);
expect_release_notify(mock_managed_lock, listener, 0);
expect_shut_down(mock_instances, 0);
- expect_shut_down(mock_mirror_status_watcher, 0);
- expect_is_leader(mock_managed_lock, false, false);
C_SaferCond on_release;
expect_release_lock(mock_managed_lock, 0, &on_release);
// Shutdown
expect_shut_down(mock_managed_lock, false, 0);
+ expect_shut_down(mock_mirror_status_watcher, 0);
expect_is_leader(mock_managed_lock, false, false);
leader_watcher.shut_down();
}
-TEST_F(TestMockLeaderWatcher, AcquireError) {
+TEST_F(TestMockLeaderWatcher, InitStatusWatcherError) {
MockManagedLock mock_managed_lock;
MockMirrorStatusWatcher mock_mirror_status_watcher;
MockInstances mock_instances;
expect_construct(mock_managed_lock);
MockLeaderWatcher leader_watcher(m_mock_threads, m_local_io_ctx, &listener);
- // Inint
- C_SaferCond on_heartbeat_finish;
- expect_is_leader(mock_managed_lock, false, false);
- expect_try_acquire_lock(mock_managed_lock, -EAGAIN);
- expect_get_locker(mock_managed_lock, librbd::managed_lock::Locker(), -ENOENT);
- expect_try_acquire_lock(mock_managed_lock, 0);
- expect_init(mock_mirror_status_watcher, 0);
- expect_init(mock_instances, 0);
- expect_acquire_notify(mock_managed_lock, listener, 0);
- expect_notify_heartbeat(mock_managed_lock, &on_heartbeat_finish);
-
- ASSERT_EQ(0, leader_watcher.init());
- ASSERT_EQ(0, on_heartbeat_finish.wait());
+ // Init
+ expect_init(mock_mirror_status_watcher, -EINVAL);
+ ASSERT_EQ(-EINVAL, leader_watcher.init());
// Shutdown
- expect_release_notify(mock_managed_lock, listener, 0);
- expect_shut_down(mock_instances, 0);
+ expect_shut_down(mock_managed_lock, false, 0);
expect_shut_down(mock_mirror_status_watcher, 0);
expect_is_leader(mock_managed_lock, false, false);
- expect_release_lock(mock_managed_lock, 0);
- expect_shut_down(mock_managed_lock, true, 0);
- expect_is_leader(mock_managed_lock, false, false);
leader_watcher.shut_down();
}
-TEST_F(TestMockLeaderWatcher, ReleaseError) {
+TEST_F(TestMockLeaderWatcher, AcquireError) {
MockManagedLock mock_managed_lock;
MockMirrorStatusWatcher mock_mirror_status_watcher;
MockInstances mock_instances;
MockListener listener;
expect_is_shutdown(mock_managed_lock);
+ expect_is_leader(mock_managed_lock);
expect_destroy(mock_managed_lock);
InSequence seq;
expect_construct(mock_managed_lock);
MockLeaderWatcher leader_watcher(m_mock_threads, m_local_io_ctx, &listener);
- // Inint
+ // Init
+ expect_init(mock_mirror_status_watcher, 0);
C_SaferCond on_heartbeat_finish;
expect_is_leader(mock_managed_lock, false, false);
+ expect_try_acquire_lock(mock_managed_lock, -EAGAIN);
+ expect_get_locker(mock_managed_lock, librbd::managed_lock::Locker(), -ENOENT);
expect_try_acquire_lock(mock_managed_lock, 0);
- expect_init(mock_mirror_status_watcher, 0);
expect_init(mock_instances, 0);
expect_acquire_notify(mock_managed_lock, listener, 0);
expect_notify_heartbeat(mock_managed_lock, &on_heartbeat_finish);
ASSERT_EQ(0, leader_watcher.init());
ASSERT_EQ(0, on_heartbeat_finish.wait());
- // Release
- expect_is_leader(mock_managed_lock, false, true);
- expect_release_notify(mock_managed_lock, listener, -EINVAL);
- expect_shut_down(mock_instances, 0);
- expect_shut_down(mock_mirror_status_watcher, -EINVAL);
- expect_is_leader(mock_managed_lock, false, false);
- C_SaferCond on_release;
- expect_release_lock(mock_managed_lock, -EINVAL, &on_release);
-
- leader_watcher.release_leader();
- ASSERT_EQ(0, on_release.wait());
-
// Shutdown
- expect_shut_down(mock_managed_lock, false, 0);
+ expect_release_notify(mock_managed_lock, listener, 0);
+ expect_shut_down(mock_instances, 0);
+ expect_release_lock(mock_managed_lock, 0);
+ expect_shut_down(mock_managed_lock, true, 0);
+ expect_shut_down(mock_mirror_status_watcher, 0);
expect_is_leader(mock_managed_lock, false, false);
leader_watcher.shut_down();
MockLeaderWatcher leader_watcher(m_mock_threads, m_local_io_ctx, &listener);
// Init
+ expect_init(mock_mirror_status_watcher, 0);
expect_is_leader(mock_managed_lock, false, false);
for (int i = 0; i < max_acquire_attempts; i++) {
expect_try_acquire_lock(mock_managed_lock, -EAGAIN);
expect_break_lock(mock_managed_lock, locker, 0, &on_break);
C_SaferCond on_heartbeat_finish;
expect_try_acquire_lock(mock_managed_lock, 0);
- expect_init(mock_mirror_status_watcher, 0);
expect_init(mock_instances, 0);
expect_acquire_notify(mock_managed_lock, listener, 0);
expect_notify_heartbeat(mock_managed_lock, &on_heartbeat_finish);
// Shutdown
expect_release_notify(mock_managed_lock, listener, 0);
expect_shut_down(mock_instances, 0);
- expect_shut_down(mock_mirror_status_watcher, 0);
- expect_is_leader(mock_managed_lock, false, false);
expect_release_lock(mock_managed_lock, 0);
expect_shut_down(mock_managed_lock, true, 0);
+ expect_shut_down(mock_mirror_status_watcher, 0);
expect_is_leader(mock_managed_lock, false, false);
leader_watcher.shut_down();
dout(20) << "r=" << r << dendl;
Context *on_finish = nullptr;
- {
- Mutex::Locker timer_locker(m_threads->timer_lock);
+ if (r < 0) {
Mutex::Locker locker(m_lock);
-
- if (r < 0) {
- derr << "error registering leader watcher for " << m_oid << " object: "
- << cpp_strerror(r) << dendl;
- } else {
- schedule_acquire_leader_lock(0);
- }
-
+ derr << "error registering leader watcher for " << m_oid << " object: "
+ << cpp_strerror(r) << dendl;
+ assert(m_on_finish != nullptr);
std::swap(on_finish, m_on_finish);
+ } else {
+ Mutex::Locker locker(m_lock);
+ init_status_watcher();
+ return;
}
+
on_finish->complete(r);
}
derr << "error shutting down leader lock: " << cpp_strerror(r) << dendl;
}
- unregister_watch();
+ shut_down_status_watcher();
}
template <typename I>
m_on_finish = on_finish;
m_ret_val = 0;
- init_status_watcher();
+ init_instances();
}
template <typename I>
Context *on_finish = nullptr;
{
+ Mutex::Locker timer_locker(m_threads->timer_lock);
Mutex::Locker locker(m_lock);
- if (r == 0) {
- init_instances();
- return;
+ if (r < 0) {
+ derr << "error initializing mirror status watcher: " << cpp_strerror(r)
+ << cpp_strerror(r) << dendl;
+ } else {
+ schedule_acquire_leader_lock(0);
}
- derr << "error initializing mirror status watcher: " << cpp_strerror(r)
- << dendl;
- m_status_watcher->destroy();
- m_status_watcher = nullptr;
assert(m_on_finish != nullptr);
- std::swap(m_on_finish, on_finish);
+ std::swap(on_finish, m_on_finish);
}
+
on_finish->complete(r);
}
void LeaderWatcher<I>::handle_shut_down_status_watcher(int r) {
dout(20) << "r=" << r << dendl;
- Context *on_finish = nullptr;
- {
- Mutex::Locker locker(m_lock);
-
- m_status_watcher->destroy();
- m_status_watcher = nullptr;
-
- if (r < 0) {
- derr << "error shutting mirror status watcher down: " << cpp_strerror(r)
- << dendl;
- }
-
- if (m_ret_val != 0) {
- r = m_ret_val;
- }
-
- if (!is_leader(m_lock)) {
- // ignore on releasing
- r = 0;
- }
+ Mutex::Locker locker(m_lock);
+ m_status_watcher->destroy();
+ m_status_watcher = nullptr;
- assert(m_on_finish != nullptr);
- std::swap(m_on_finish, on_finish);
+ if (r < 0) {
+ derr << "error shutting mirror status watcher down: " << cpp_strerror(r)
+ << dendl;
}
- on_finish->complete(r);
+
+ unregister_watch();
}
template <typename I>
void LeaderWatcher<I>::handle_init_instances(int r) {
dout(20) << "r=" << r << dendl;
- Mutex::Locker locker(m_lock);
-
+ Context *on_finish = nullptr;
if (r < 0) {
+ Mutex::Locker locker(m_lock);
derr << "error initializing instances: " << cpp_strerror(r) << dendl;
- m_ret_val = r;
m_instances->destroy();
m_instances = nullptr;
- shut_down_status_watcher();
+
+ assert(m_on_finish != nullptr);
+ std::swap(m_on_finish, on_finish);
+ } else {
+ Mutex::Locker locker(m_lock);
+ notify_listener();
return;
}
- notify_listener();
+ on_finish->complete(r);
}
template <typename I>
dout(20) << "r=" << r << dendl;
assert(r == 0);
- Mutex::Locker locker(m_lock);
+ Context *on_finish = nullptr;
+ {
+ Mutex::Locker locker(m_lock);
- m_instances->destroy();
- m_instances = nullptr;
+ m_instances->destroy();
+ m_instances = nullptr;
- shut_down_status_watcher();
+ assert(m_on_finish != nullptr);
+ std::swap(m_on_finish, on_finish);
+ }
+ on_finish->complete(r);
}
template <typename I>