From: Mykola Golub Date: Mon, 17 Feb 2020 12:11:59 +0000 (+0000) Subject: rbd-mirror: don't expect image map is always initialized X-Git-Tag: v15.1.1~343^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d916b0948bf8a5a06afb9a63188f6efa2121510d;p=ceph.git rbd-mirror: don't expect image map is always initialized 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 --- diff --git a/src/tools/rbd_mirror/NamespaceReplayer.cc b/src/tools/rbd_mirror/NamespaceReplayer.cc index 582b875835ee..637e252a9b6f 100644 --- a/src/tools/rbd_mirror/NamespaceReplayer.cc +++ b/src/tools/rbd_mirror/NamespaceReplayer.cc @@ -245,7 +245,10 @@ void NamespaceReplayer::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::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 void NamespaceReplayer::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::create(m_local_io_ctx, m_threads, - m_instance_watcher->get_instance_id(), - m_image_map_listener)); + auto image_map = ImageMap::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 -void NamespaceReplayer::handle_init_image_map(int r, Context *on_finish) { +void NamespaceReplayer::handle_init_image_map(int r, ImageMap *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); } diff --git a/src/tools/rbd_mirror/NamespaceReplayer.h b/src/tools/rbd_mirror/NamespaceReplayer.h index 4fbf4c53bec4..5396106e175b 100644 --- a/src/tools/rbd_mirror/NamespaceReplayer.h +++ b/src/tools/rbd_mirror/NamespaceReplayer.h @@ -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 *image_map, + Context *on_finish); void init_local_pool_watcher(Context *on_finish); void handle_init_local_pool_watcher(int r, Context *on_finish);