From b38baa948918ee2c167143f76a5706bde37b49ea Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 27 Jul 2017 15:35:15 -0400 Subject: [PATCH] rbd-mirror: avoid silently failing to register image replayer admin sockets Signed-off-by: Jason Dillaman --- src/tools/rbd_mirror/ImageReplayer.cc | 81 ++++++++++++++++++++------- src/tools/rbd_mirror/ImageReplayer.h | 2 + 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/src/tools/rbd_mirror/ImageReplayer.cc b/src/tools/rbd_mirror/ImageReplayer.cc index cf3f0996d4bb1..ca036a98dffd4 100644 --- a/src/tools/rbd_mirror/ImageReplayer.cc +++ b/src/tools/rbd_mirror/ImageReplayer.cc @@ -161,46 +161,56 @@ class ImageReplayerAdminSocketHook : public AdminSocketHook { public: ImageReplayerAdminSocketHook(CephContext *cct, const std::string &name, ImageReplayer *replayer) - : admin_socket(cct->get_admin_socket()), + : admin_socket(cct->get_admin_socket()), name(name), replayer(replayer), lock("ImageReplayerAdminSocketHook::lock " + replayer->get_global_image_id()) { + } + + int register_commands() { std::string command; int r; command = "rbd mirror status " + name; r = admin_socket->register_command(command, command, this, "get status for rbd mirror " + name); - if (r == 0) { - commands[command] = new StatusCommand(replayer); + if (r < 0) { + return r; } + commands[command] = new StatusCommand(replayer); command = "rbd mirror start " + name; r = admin_socket->register_command(command, command, this, "start rbd mirror " + name); - if (r == 0) { - commands[command] = new StartCommand(replayer); + if (r < 0) { + return r; } + commands[command] = new StartCommand(replayer); command = "rbd mirror stop " + name; r = admin_socket->register_command(command, command, this, "stop rbd mirror " + name); - if (r == 0) { - commands[command] = new StopCommand(replayer); + if (r < 0) { + return r; } + commands[command] = new StopCommand(replayer); command = "rbd mirror restart " + name; r = admin_socket->register_command(command, command, this, "restart rbd mirror " + name); - if (r == 0) { - commands[command] = new RestartCommand(replayer); + if (r < 0) { + return r; } + commands[command] = new RestartCommand(replayer); command = "rbd mirror flush " + name; r = admin_socket->register_command(command, command, this, "flush rbd mirror " + name); - if (r == 0) { - commands[command] = new FlushCommand(replayer); + if (r < 0) { + return r; } + commands[command] = new FlushCommand(replayer); + + return 0; } ~ImageReplayerAdminSocketHook() override { @@ -230,6 +240,8 @@ private: typedef std::map Commands; AdminSocket *admin_socket; + std::string name; + ImageReplayer *replayer; Mutex lock; Commands commands; }; @@ -305,14 +317,13 @@ ImageReplayer::ImageReplayer(Threads *threads, } m_name = pool_name + "/" + m_global_image_id; - dout(20) << "registered asok hook: " << m_name << dendl; - m_asok_hook = new ImageReplayerAdminSocketHook(g_ceph_context, m_name, - this); + register_admin_socket_hook(); } template ImageReplayer::~ImageReplayer() { + unregister_admin_socket_hook(); assert(m_event_preprocessor == nullptr); assert(m_replay_status_formatter == nullptr); assert(m_local_image_ctx == nullptr); @@ -325,7 +336,6 @@ ImageReplayer::~ImageReplayer() assert(m_in_flight_status_updates == 0); delete m_journal_listener; - delete m_asok_hook; } template @@ -606,11 +616,7 @@ void ImageReplayer::handle_bootstrap(int r) { m_asok_hook = nullptr; } } - if (!m_asok_hook) { - dout(20) << "registered asok hook: " << m_name << dendl; - m_asok_hook = new ImageReplayerAdminSocketHook(g_ceph_context, m_name, - this); - } + register_admin_socket_hook(); } update_mirror_image_status(false, boost::none); @@ -1683,10 +1689,17 @@ void ImageReplayer::handle_shut_down(int r) { m_local_pool_id, m_global_image_id, m_resync_requested); + + m_local_image_id = ""; m_resync_requested = false; + if (m_delete_requested) { + unregister_admin_socket_hook(); + m_delete_requested = false; + } } else if (m_last_r == -ENOENT && m_local_image_id.empty() && m_remote_image.image_id.empty()) { dout(0) << "mirror image no longer exists" << dendl; + unregister_admin_socket_hook(); m_finished = true; } } @@ -1771,6 +1784,34 @@ void ImageReplayer::resync_image(Context *on_finish) { stop(on_finish); } +template +void ImageReplayer::register_admin_socket_hook() { + if (m_asok_hook != nullptr) { + return; + } + + dout(20) << "registered asok hook: " << m_name << dendl; + auto asok_hook = new ImageReplayerAdminSocketHook(g_ceph_context, m_name, + this); + int r = asok_hook->register_commands(); + if (r < 0) { + derr << "error registering admin socket commands" << dendl; + delete asok_hook; + asok_hook = nullptr; + return; + } + + m_asok_hook = asok_hook; +} + +template +void ImageReplayer::unregister_admin_socket_hook() { + dout(20) << dendl; + + delete m_asok_hook; + m_asok_hook = nullptr; +} + template std::ostream &operator<<(std::ostream &os, const ImageReplayer &replayer) { diff --git a/src/tools/rbd_mirror/ImageReplayer.h b/src/tools/rbd_mirror/ImageReplayer.h index e3c4b7b926205..3f2ab2fca74e8 100644 --- a/src/tools/rbd_mirror/ImageReplayer.h +++ b/src/tools/rbd_mirror/ImageReplayer.h @@ -423,6 +423,8 @@ private: void handle_process_entry_ready(int r); void handle_process_entry_safe(const ReplayEntry& replay_entry, int r); + void register_admin_socket_hook(); + void unregister_admin_socket_hook(); }; } // namespace mirror -- 2.39.5