From: Mykola Golub Date: Tue, 5 May 2020 14:23:59 +0000 (+0100) Subject: rbd-mirror: make stop properly cancel restart X-Git-Tag: v16.1.0~2237^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0a3794e56256be33a71e363da34ee84ffc34fef7;p=ceph.git rbd-mirror: make stop properly cancel restart Previously, if stop was issued when restart was at "stopping" stage, the stop was just ignored. Signed-off-by: Mykola Golub --- diff --git a/src/tools/rbd_mirror/ImageReplayer.cc b/src/tools/rbd_mirror/ImageReplayer.cc index 3123c9730764..2d57a98d2f9c 100644 --- a/src/tools/rbd_mirror/ImageReplayer.cc +++ b/src/tools/rbd_mirror/ImageReplayer.cc @@ -288,7 +288,7 @@ void ImageReplayer::set_state_description(int r, const std::string &desc) { } template -void ImageReplayer::start(Context *on_finish, bool manual) +void ImageReplayer::start(Context *on_finish, bool manual, bool restart) { dout(10) << "on_finish=" << on_finish << dendl; @@ -302,12 +302,16 @@ void ImageReplayer::start(Context *on_finish, bool manual) dout(5) << "stopped manually, ignoring start without manual flag" << dendl; r = -EPERM; + } else if (restart && !m_restart_requested) { + dout(10) << "canceled restart" << dendl; + r = -ECANCELED; } else { m_state = STATE_STARTING; m_last_r = 0; m_state_desc.clear(); m_manual_stop = false; m_delete_requested = false; + m_restart_requested = false; if (on_finish != nullptr) { ceph_assert(m_on_start_finish == nullptr); @@ -509,11 +513,10 @@ bool ImageReplayer::on_start_interrupted(ceph::mutex& lock) { } template -void ImageReplayer::stop(Context *on_finish, bool manual, int r, - const std::string& desc) +void ImageReplayer::stop(Context *on_finish, bool manual, bool restart) { dout(10) << "on_finish=" << on_finish << ", manual=" << manual - << ", desc=" << desc << dendl; + << ", restart=" << restart << dendl; image_replayer::BootstrapRequest *bootstrap_request = nullptr; bool shut_down_replay = false; @@ -521,8 +524,16 @@ void ImageReplayer::stop(Context *on_finish, bool manual, int r, { std::lock_guard locker{m_lock}; + if (restart) { + m_restart_requested = true; + } + if (!is_running_()) { running = false; + if (!restart && m_restart_requested) { + dout(10) << "canceling restart" << dendl; + m_restart_requested = false; + } } else { if (!is_stopped_()) { if (m_state == STATE_STARTING) { @@ -560,7 +571,7 @@ void ImageReplayer::stop(Context *on_finish, bool manual, int r, } if (shut_down_replay) { - on_stop_journal_replay(r, desc); + on_stop_journal_replay(); } else if (on_finish != nullptr) { on_finish->complete(0); } @@ -591,14 +602,19 @@ void ImageReplayer::on_stop_journal_replay(int r, const std::string &desc) template void ImageReplayer::restart(Context *on_finish) { + { + std::lock_guard locker{m_lock}; + m_restart_requested = true; + } + auto ctx = new LambdaContext( [this, on_finish](int r) { if (r < 0) { // Try start anyway. } - start(on_finish, true); + start(on_finish, true, true); }); - stop(ctx); + stop(ctx, false, true); } template diff --git a/src/tools/rbd_mirror/ImageReplayer.h b/src/tools/rbd_mirror/ImageReplayer.h index 493d38d9d284..9569f025bea2 100644 --- a/src/tools/rbd_mirror/ImageReplayer.h +++ b/src/tools/rbd_mirror/ImageReplayer.h @@ -101,9 +101,10 @@ public: return m_global_image_id; } - void start(Context *on_finish = nullptr, bool manual = false); + void start(Context *on_finish = nullptr, bool manual = false, + bool restart = false); void stop(Context *on_finish = nullptr, bool manual = false, - int r = 0, const std::string& desc = ""); + bool restart = false); void restart(Context *on_finish = nullptr); void flush(); @@ -139,11 +140,11 @@ protected: * @endverbatim */ - virtual void on_start_fail(int r, const std::string &desc); - virtual bool on_start_interrupted(); - virtual bool on_start_interrupted(ceph::mutex& lock); + void on_start_fail(int r, const std::string &desc); + bool on_start_interrupted(); + bool on_start_interrupted(ceph::mutex& lock); - virtual void on_stop_journal_replay(int r = 0, const std::string &desc = ""); + void on_stop_journal_replay(int r = 0, const std::string &desc = ""); bool on_replay_interrupted(); @@ -205,6 +206,7 @@ private: bool m_finished = false; bool m_delete_requested = false; bool m_resync_requested = false; + bool m_restart_requested = false; image_replayer::StateBuilder* m_state_builder = nullptr; image_replayer::Replayer* m_replayer = nullptr;