]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: don't expect image map is always initialized 33368/head
authorMykola Golub <mgolub@suse.com>
Mon, 17 Feb 2020 12:11:59 +0000 (12:11 +0000)
committerMykola Golub <mgolub@suse.com>
Mon, 17 Feb 2020 12:11:59 +0000 (12:11 +0000)
in a namespace replayer when handling "instances added/removed"
event. It is possible an event comes when a pool replayer has
already created and initialized a new namespace replayer but has
not acquired leader for it (image_map is not initialized yet).

Also, make sure `m_image_map` is set only after its
initialization is complete.

Fixes: https://tracker.ceph.com/issues/44161
Signed-off-by: Mykola Golub <mgolub@suse.com>
src/tools/rbd_mirror/NamespaceReplayer.cc
src/tools/rbd_mirror/NamespaceReplayer.h

index 582b875835eeb3f0cc693b49554d3ff2f5afae54..637e252a9b6f2a462d8be7e12c40d8157952f6e0 100644 (file)
@@ -245,7 +245,10 @@ void NamespaceReplayer<I>::handle_instances_added(
 
   std::lock_guard locker{m_lock};
 
-  ceph_assert(m_image_map);
+  if (!m_image_map) {
+    return;
+  }
+
   m_image_map->update_instances_added(instance_ids);
 }
 
@@ -256,7 +259,10 @@ void NamespaceReplayer<I>::handle_instances_removed(
 
   std::lock_guard locker{m_lock};
 
-  ceph_assert(m_image_map);
+  if (!m_image_map) {
+    return;
+  }
+
   m_image_map->update_instances_removed(instance_ids);
 }
 
@@ -567,32 +573,35 @@ template <typename I>
 void NamespaceReplayer<I>::init_image_map(Context *on_finish) {
   dout(10) << dendl;
 
-  std::lock_guard locker{m_lock};
-  ceph_assert(!m_image_map);
-  m_image_map.reset(ImageMap<I>::create(m_local_io_ctx, m_threads,
-                                        m_instance_watcher->get_instance_id(),
-                                        m_image_map_listener));
+  auto image_map = ImageMap<I>::create(m_local_io_ctx, m_threads,
+                                       m_instance_watcher->get_instance_id(),
+                                       m_image_map_listener);
 
   auto ctx = new LambdaContext(
-      [this, on_finish](int r) {
-        handle_init_image_map(r, on_finish);
+      [this, image_map, on_finish](int r) {
+        handle_init_image_map(r, image_map, on_finish);
       });
-  m_image_map->init(create_async_context_callback(
+  image_map->init(create_async_context_callback(
     m_threads->work_queue, ctx));
 }
 
 template <typename I>
-void NamespaceReplayer<I>::handle_init_image_map(int r, Context *on_finish) {
+void NamespaceReplayer<I>::handle_init_image_map(int r, ImageMap<I> *image_map,
+                                                 Context *on_finish) {
   dout(10) << "r=" << r << dendl;
   if (r < 0) {
     derr << "failed to init image map: " << cpp_strerror(r) << dendl;
-    on_finish = new LambdaContext([on_finish, r](int) {
+    on_finish = new LambdaContext([image_map, on_finish, r](int) {
+        delete image_map;
         on_finish->complete(r);
       });
-    shut_down_image_map(on_finish);
+    image_map->shut_down(on_finish);
     return;
   }
 
+  ceph_assert(!m_image_map);
+  m_image_map.reset(image_map);
+
   init_local_pool_watcher(on_finish);
 }
 
index 4fbf4c53bec4dd6a1654befc5e96e643ab7a7407..5396106e175b12b64a40abaef6a216e8d1cca397 100644 (file)
@@ -233,7 +233,8 @@ private:
   void handle_shut_down_local_status_updater(int r);
 
   void init_image_map(Context *on_finish);
-  void handle_init_image_map(int r, Context *on_finish);
+  void handle_init_image_map(int r, ImageMap<ImageCtxT> *image_map,
+                             Context *on_finish);
 
   void init_local_pool_watcher(Context *on_finish);
   void handle_init_local_pool_watcher(int r, Context *on_finish);