]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: complete pool watcher initialization if object missing
authorJason Dillaman <dillaman@redhat.com>
Fri, 22 Feb 2019 15:59:26 +0000 (10:59 -0500)
committerJason Dillaman <dillaman@redhat.com>
Fri, 17 May 2019 14:59:31 +0000 (10:59 -0400)
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 <dillaman@redhat.com>
(cherry picked from commit 80954cd914c86e11ffb6a8cbfcb21202cb8131b5)

Conflicts:
src/tools/rbd_mirror/PoolReplayer.cc: missing handle_init_remote_pool_watcher

src/test/rbd_mirror/test_mock_PoolWatcher.cc
src/tools/rbd_mirror/PoolReplayer.cc
src/tools/rbd_mirror/PoolReplayer.h
src/tools/rbd_mirror/PoolWatcher.cc

index 4c7463d660c552df8e20ad29371c031f5035149e..3c241d8e7c38e449c4f15587d3e460b2b8046ebd 100644 (file)
@@ -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);
index c766e8609038189444610a1d3ebf68893700b92e..1edd145b332d0580328a29725c3f14449f4d1370 100644 (file)
@@ -734,9 +734,29 @@ void PoolReplayer::init_remote_pool_watcher(Context *on_finish) {
   assert(!m_remote_pool_watcher);
   m_remote_pool_watcher.reset(new PoolWatcher<>(
     m_threads, m_remote_io_ctx, m_remote_pool_watcher_listener));
+  auto ctx = new FunctionContext([this, on_finish](int r) {
+      handle_init_remote_pool_watcher(r, on_finish);
+    });
   m_remote_pool_watcher->init(create_async_context_callback(
-    m_threads->work_queue, on_finish));
+    m_threads->work_queue, ctx));
+}
 
+void PoolReplayer::handle_init_remote_pool_watcher(int r, Context *on_finish) {
+  dout(10) << "r=" << r << dendl;
+  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;
+    r = 0;
+  } else if (r < 0) {
+    derr << "failed to retrieve remote images: " << cpp_strerror(r) << dendl;
+  }
+
+  on_finish->complete(r);
+
+  Mutex::Locker locker(m_lock);
   m_cond.Signal();
 }
 
index 49aaee3c4ae764c0a5d7c3c401a4ba100d507aeb..9a581756d5e44e415213fd1e55ac7e046338866f 100644 (file)
@@ -99,6 +99,7 @@ private:
   void handle_init_local_pool_watcher(int r, Context *on_finish);
 
   void init_remote_pool_watcher(Context *on_finish);
+  void handle_init_remote_pool_watcher(int r, Context *on_finish);
 
   void shut_down_pool_watchers(Context *on_finish);
   void handle_shut_down_pool_watchers(int r, Context *on_finish);
index 8d60aa4f47a8c6a440a3b89545381c57a8bbaae3..316329e0967c5fcd5365903259b8f4ba83ec4786 100644 (file)
@@ -174,6 +174,9 @@ void PoolWatcher<I>::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;