From 80954cd914c86e11ffb6a8cbfcb21202cb8131b5 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Fri, 22 Feb 2019 10:59:26 -0500 Subject: [PATCH] rbd-mirror: complete pool watcher initialization if object missing If the mirroring object is missing, complete the initialization and continue to retry in the background. This is useful for cases where the remote doesn't (yet) have mirroring enabled but the remote pool watcher initialization is delaying the leader watcher promotion to the point where the leader is blacklisted by its peers. Signed-off-by: Jason Dillaman --- src/test/rbd_mirror/test_mock_PoolWatcher.cc | 2 +- src/tools/rbd_mirror/PoolReplayer.cc | 8 +++++++- src/tools/rbd_mirror/PoolWatcher.cc | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/test/rbd_mirror/test_mock_PoolWatcher.cc b/src/test/rbd_mirror/test_mock_PoolWatcher.cc index 43c3e622fdaf8..b4dd66e8d8127 100644 --- a/src/test/rbd_mirror/test_mock_PoolWatcher.cc +++ b/src/test/rbd_mirror/test_mock_PoolWatcher.cc @@ -498,7 +498,7 @@ TEST_F(TestMockPoolWatcher, RegisterWatcherMissing) { mock_listener); C_SaferCond ctx; mock_pool_watcher.init(&ctx); - ASSERT_EQ(0, ctx.wait()); + ASSERT_EQ(-ENOENT, ctx.wait()); ASSERT_TRUE(wait_for_update(1)); expect_mirroring_watcher_unregister(mock_mirroring_watcher, 0); diff --git a/src/tools/rbd_mirror/PoolReplayer.cc b/src/tools/rbd_mirror/PoolReplayer.cc index c15f565b677e5..9f8e5e883595b 100644 --- a/src/tools/rbd_mirror/PoolReplayer.cc +++ b/src/tools/rbd_mirror/PoolReplayer.cc @@ -849,7 +849,13 @@ template void PoolReplayer::handle_init_remote_pool_watcher( int r, Context *on_finish) { dout(10) << "r=" << r << dendl; - if (r < 0) { + if (r == -ENOENT) { + // Technically nothing to do since the other side doesn't + // have mirroring enabled. Eventually the remote pool watcher will + // detect images (if mirroring is enabled), so no point propagating + // an error which would just busy-spin the state machines. + dout(0) << "remote peer does not have mirroring configured" << dendl; + } else if (r < 0) { derr << "failed to retrieve remote images: " << cpp_strerror(r) << dendl; on_finish = new FunctionContext([on_finish, r](int) { on_finish->complete(r); diff --git a/src/tools/rbd_mirror/PoolWatcher.cc b/src/tools/rbd_mirror/PoolWatcher.cc index 9b975b9cc0004..b5c62b7b2d646 100644 --- a/src/tools/rbd_mirror/PoolWatcher.cc +++ b/src/tools/rbd_mirror/PoolWatcher.cc @@ -174,6 +174,9 @@ void PoolWatcher::handle_register_watcher(int r) { } else if (r == -ENOENT) { dout(5) << "mirroring directory does not exist" << dendl; schedule_refresh_images(30); + + Mutex::Locker locker(m_lock); + std::swap(on_init_finish, m_on_init_finish); } else { derr << "unexpected error registering mirroring directory watch: " << cpp_strerror(r) << dendl; -- 2.39.5