From b878f5ffc75e70b1f09eee461f93b1cb5031586e Mon Sep 17 00:00:00 2001 From: Ricardo Dias Date: Thu, 2 Jun 2016 10:04:41 +0100 Subject: [PATCH] rbd-mirror: image-sync: Periodically update sync point object number Fixes: http://tracker.ceph.com/issues/15108 Signed-off-by: Ricardo Dias (cherry picked from commit c2eedf4d27b73d7eaf3fda54f9b0ee74e455bc1d) --- src/common/config_opts.h | 5 + .../rbd_mirror/image_sync/ImageCopyRequest.cc | 104 ++++++++++++++++++ .../rbd_mirror/image_sync/ImageCopyRequest.h | 7 ++ 3 files changed, 116 insertions(+) diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 082a367c9505c..53e60bf58e4c7 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -1211,6 +1211,11 @@ OPTION(rbd_journal_object_flush_bytes, OPT_INT, 0) // maximum number of pending OPTION(rbd_journal_object_flush_age, OPT_DOUBLE, 0) // maximum age (in seconds) for pending commits OPTION(rbd_journal_pool, OPT_STR, "") // pool for journal objects +/** + * RBD Mirror options + */ +OPTION(rbd_mirror_sync_point_update_age, OPT_DOUBLE, 30) // number of seconds between each update of the image sync point object number + OPTION(nss_db_path, OPT_STR, "") // path to nss db diff --git a/src/tools/rbd_mirror/image_sync/ImageCopyRequest.cc b/src/tools/rbd_mirror/image_sync/ImageCopyRequest.cc index e037f8812608b..14c75cd6751c5 100644 --- a/src/tools/rbd_mirror/image_sync/ImageCopyRequest.cc +++ b/src/tools/rbd_mirror/image_sync/ImageCopyRequest.cc @@ -5,6 +5,7 @@ #include "ObjectCopyRequest.h" #include "include/stringify.h" #include "common/errno.h" +#include "common/Timer.h" #include "journal/Journaler.h" #include "librbd/Utils.h" #include "tools/rbd_mirror/ProgressContext.h" @@ -36,6 +37,8 @@ ImageCopyRequest::ImageCopyRequest(I *local_image_ctx, I *remote_image_ctx, m_client_meta(client_meta), m_sync_point(sync_point), m_progress_ctx(progress_ctx), m_lock(unique_lock_name("ImageCopyRequest::m_lock", this)), + m_updating_sync_point(false), m_update_sync_ctx(nullptr), + m_update_sync_point_interval(g_ceph_context->_conf->rbd_mirror_sync_point_update_age), m_client_meta_copy(*client_meta) { assert(!m_client_meta_copy.sync_points.empty()); assert(!m_client_meta_copy.snap_seqs.empty()); @@ -146,7 +149,22 @@ void ImageCopyRequest::send_object_copies() { } } complete = (m_current_ops == 0); + + if (!complete) { + m_update_sync_ctx = new FunctionContext([this](int r) { + this->send_update_sync_point(); + }); + } } + + { + Mutex::Locker timer_locker(*m_timer_lock); + if (m_update_sync_ctx) { + m_timer->add_event_after(m_update_sync_point_interval, + m_update_sync_ctx); + } + } + if (complete) { send_flush_sync_point(); } @@ -205,6 +223,92 @@ void ImageCopyRequest::handle_object_copy(int r) { update_progress("COPY_OBJECT " + stringify(percent) + "%", false); if (complete) { + bool do_flush = true; + { + Mutex::Locker timer_locker(*m_timer_lock); + Mutex::Locker locker(m_lock); + if (!m_updating_sync_point) { + if (m_update_sync_ctx != nullptr) { + m_timer->cancel_event(m_update_sync_ctx); + m_update_sync_ctx = nullptr; + } + } else { + do_flush = false; + } + } + + if (do_flush) { + send_flush_sync_point(); + } + } +} + +template +void ImageCopyRequest::send_update_sync_point() { + Mutex::Locker l(m_lock); + + m_update_sync_ctx = nullptr; + + if (m_canceled || m_ret_val < 0 || m_current_ops == 0) { + return; + } + + if (m_sync_point->object_number && + (m_object_no-1) == m_sync_point->object_number.get()) { + // update sync point did not progress since last sync + return; + } + + m_updating_sync_point = true; + + m_client_meta_copy = *m_client_meta; + m_sync_point->object_number = m_object_no - 1; + + CephContext *cct = m_local_image_ctx->cct; + ldout(cct, 20) << ": sync_point=" << *m_sync_point << dendl; + + bufferlist client_data_bl; + librbd::journal::ClientData client_data(*m_client_meta); + ::encode(client_data, client_data_bl); + + Context *ctx = create_context_callback< + ImageCopyRequest, &ImageCopyRequest::handle_update_sync_point>( + this); + m_journaler->update_client(client_data_bl, ctx); +} + +template +void ImageCopyRequest::handle_update_sync_point(int r) { + CephContext *cct = m_local_image_ctx->cct; + ldout(cct, 20) << ": r=" << r << dendl; + + if (r < 0) { + *m_client_meta = m_client_meta_copy; + lderr(cct) << ": failed to update client data: " << cpp_strerror(r) + << dendl; + } + + bool complete; + { + Mutex::Locker l(m_lock); + m_updating_sync_point = false; + + complete = m_current_ops == 0 || m_canceled || m_ret_val < 0; + + if (!complete) { + m_update_sync_ctx = new FunctionContext([this](int r) { + this->send_update_sync_point(); + }); + } + } + + if (!complete) { + Mutex::Locker timer_lock(*m_timer_lock); + if (m_update_sync_ctx) { + m_timer->add_event_after(m_update_sync_point_interval, + m_update_sync_ctx); + } + } else { send_flush_sync_point(); } } diff --git a/src/tools/rbd_mirror/image_sync/ImageCopyRequest.h b/src/tools/rbd_mirror/image_sync/ImageCopyRequest.h index 118b48d802352..85dfe9b28316f 100644 --- a/src/tools/rbd_mirror/image_sync/ImageCopyRequest.h +++ b/src/tools/rbd_mirror/image_sync/ImageCopyRequest.h @@ -100,6 +100,10 @@ private: uint64_t m_current_ops = 0; int m_ret_val = 0; + bool m_updating_sync_point; + Context *m_update_sync_ctx; + double m_update_sync_point_interval; + MirrorPeerClientMeta m_client_meta_copy; void send_update_max_object_count(); @@ -109,6 +113,9 @@ private: void send_next_object_copy(); void handle_object_copy(int r); + void send_update_sync_point(); + void handle_update_sync_point(int r); + void send_flush_sync_point(); void handle_flush_sync_point(int r); -- 2.39.5