From: Jason Dillaman Date: Tue, 8 May 2018 21:09:58 +0000 (-0400) Subject: rbd-mirror: cancel image replayer status timer task at shut down X-Git-Tag: v13.1.1~1^2~19 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=59db540323a6126b64dff2dab10918a866576c4d;p=ceph.git rbd-mirror: cancel image replayer status timer task at shut down Also avoid attempting to send status using an invalid librados::IoCtx handle due to a deleted pool. Signed-off-by: Jason Dillaman (cherry picked from commit e2a00887c1a2c08cab8566d930dede1dac186b9b) --- diff --git a/src/tools/rbd_mirror/ImageReplayer.cc b/src/tools/rbd_mirror/ImageReplayer.cc index f8209603f01..471cf82169f 100644 --- a/src/tools/rbd_mirror/ImageReplayer.cc +++ b/src/tools/rbd_mirror/ImageReplayer.cc @@ -379,6 +379,8 @@ void ImageReplayer::start(Context *on_finish, bool manual) m_local_ioctx.reset(new librados::IoCtx{}); r = m_local->ioctx_create2(m_local_pool_id, *m_local_ioctx); if (r < 0) { + m_local_ioctx.reset(); + derr << "error opening ioctx for local pool " << m_local_pool_id << ": " << cpp_strerror(r) << dendl; on_start_fail(r, "error opening local pool"); @@ -686,7 +688,9 @@ void ImageReplayer::on_start_fail(int r, const std::string &desc) } set_state_description(r, desc); - update_mirror_image_status(false, boost::none); + if (m_local_ioctx) { + update_mirror_image_status(false, boost::none); + } reschedule_update_status_task(-1); shut_down(r); }); @@ -702,7 +706,7 @@ bool ImageReplayer::on_start_interrupted() return false; } - on_start_fail(-ECANCELED); + on_start_fail(-ECANCELED, ""); return true; } @@ -1270,8 +1274,8 @@ bool ImageReplayer::start_mirror_image_status_update(bool force, } } - dout(20) << dendl; ++m_in_flight_status_updates; + dout(15) << "in-flight updates=" << m_in_flight_status_updates << dendl; return true; } @@ -1284,7 +1288,7 @@ void ImageReplayer::finish_mirror_image_status_update() { Mutex::Locker locker(m_lock); assert(m_in_flight_status_updates > 0); if (--m_in_flight_status_updates > 0) { - dout(20) << "waiting on " << m_in_flight_status_updates << " in-flight " + dout(15) << "waiting on " << m_in_flight_status_updates << " in-flight " << "updates" << dendl; return; } @@ -1292,7 +1296,7 @@ void ImageReplayer::finish_mirror_image_status_update() { std::swap(on_finish, m_on_update_status_finish); } - dout(20) << dendl; + dout(15) << dendl; if (on_finish != nullptr) { on_finish->complete(0); } @@ -1372,6 +1376,7 @@ void ImageReplayer::send_mirror_status_update(const OptionalState &opt_state) }); std::string desc; + assert(m_replay_status_formatter != nullptr); if (!m_replay_status_formatter->get_or_send_update(&desc, on_req_finish)) { dout(20) << "waiting for replay status" << dendl; @@ -1423,6 +1428,7 @@ void ImageReplayer::send_mirror_status_update(const OptionalState &opt_state) librados::ObjectWriteOperation op; librbd::cls_client::mirror_image_status_set(&op, m_global_image_id, status); + assert(m_local_ioctx); librados::AioCompletion *aio_comp = create_rados_callback< ImageReplayer, &ImageReplayer::handle_mirror_status_update>(this); int r = m_local_ioctx->aio_operate(RBD_MIRRORING, aio_comp, &op); @@ -1452,7 +1458,7 @@ void ImageReplayer::handle_mirror_status_update(int r) { if (started) { queue_mirror_image_status_update(boost::none); } else if (running) { - reschedule_update_status_task(); + reschedule_update_status_task(0); } // mark committed status update as no longer in-flight @@ -1461,14 +1467,14 @@ void ImageReplayer::handle_mirror_status_update(int r) { template void ImageReplayer::reschedule_update_status_task(int new_interval) { - dout(20) << dendl; - bool canceled_task = false; { Mutex::Locker locker(m_lock); Mutex::Locker timer_locker(m_threads->timer_lock); if (m_update_status_task) { + dout(15) << "canceling existing status update task" << dendl; + canceled_task = m_threads->timer->cancel_event(m_update_status_task); m_update_status_task = nullptr; } @@ -1487,13 +1493,14 @@ void ImageReplayer::reschedule_update_status_task(int new_interval) { queue_mirror_image_status_update(boost::none); }); + dout(15) << "scheduling status update task after " + << m_update_status_interval << " seconds" << dendl; m_threads->timer->add_event_after(m_update_status_interval, m_update_status_task); } } if (canceled_task) { - dout(20) << "canceled task" << dendl; finish_mirror_image_status_update(); } } @@ -1517,6 +1524,8 @@ void ImageReplayer::shut_down(int r) { m_event_replay_tracker.finish_op(); } + reschedule_update_status_task(-1); + { Mutex::Locker locker(m_lock); assert(m_state == STATE_STOPPING); @@ -1542,7 +1551,9 @@ void ImageReplayer::shut_down(int r) { // chain the shut down sequence (reverse order) Context *ctx = new FunctionContext( [this, r](int _r) { - update_mirror_image_status(true, STATE_STOPPED); + if (m_local_ioctx) { + update_mirror_image_status(true, STATE_STOPPED); + } handle_shut_down(r); }); diff --git a/src/tools/rbd_mirror/ImageReplayer.h b/src/tools/rbd_mirror/ImageReplayer.h index 1b24376146b..b769d32b0c4 100644 --- a/src/tools/rbd_mirror/ImageReplayer.h +++ b/src/tools/rbd_mirror/ImageReplayer.h @@ -196,7 +196,7 @@ protected: * @endverbatim */ - virtual void on_start_fail(int r, const std::string &desc = ""); + virtual void on_start_fail(int r, const std::string &desc); virtual bool on_start_interrupted(); virtual void on_stop_journal_replay(int r = 0, const std::string &desc = ""); @@ -378,7 +378,7 @@ private: void queue_mirror_image_status_update(const OptionalState &state); void send_mirror_status_update(const OptionalState &state); void handle_mirror_status_update(int r); - void reschedule_update_status_task(int new_interval = 0); + void reschedule_update_status_task(int new_interval); void shut_down(int r); void handle_shut_down(int r);