From 7d10eb01c0f4dfedd153f492f06451ea2bcdda60 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Mon, 21 Mar 2016 22:01:05 -0400 Subject: [PATCH] librbd: helper methods to allocate tags associated to remote journals Allocating tags for the local journal will always be based off the local commit position. For remote journals, the local commit position doesn't reflect actual events replayed by rbd-mirror, so it needs to provide the remote journal commit position. Signed-off-by: Jason Dillaman --- src/librbd/Journal.cc | 66 ++++++++++++++++++++++++---- src/librbd/Journal.h | 6 ++- src/librbd/journal/StandardPolicy.cc | 2 +- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/librbd/Journal.cc b/src/librbd/Journal.cc index ec000f98651..ad8900d1d06 100644 --- a/src/librbd/Journal.cc +++ b/src/librbd/Journal.cc @@ -501,9 +501,21 @@ int Journal::allocate_tag(I *image_ctx, const std::string &mirror_uuid) { return r; } - // TODO: inject current commit position into tag data + cls::journal::Client client; + r = journaler.get_cached_client(IMAGE_CLIENT_ID, &client); + if (r < 0) { + lderr(cct) << "failed to retrieve client" << cpp_strerror(r) << dendl; + return r; + } + + if (!client.commit_position.object_positions.empty()) { + auto position = client.commit_position.object_positions.front(); + tag_data.predecessor_commit_valid = true; + tag_data.predecessor_tag_tid = position.tag_tid; + tag_data.predecessor_entry_tid = position.entry_tid; + } + tag_data.predecessor_mirror_uuid = tag_data.mirror_uuid; tag_data.mirror_uuid = mirror_uuid; - tag_data.predecessor_mirror_uuid = mirror_uuid; bufferlist tag_bl; ::encode(tag_data, tag_bl); @@ -628,23 +640,61 @@ bool Journal::is_tag_owner() const { return (m_tag_data.mirror_uuid == LOCAL_MIRROR_UUID); } +template +void Journal::allocate_local_tag(Context *on_finish) { + CephContext *cct = m_image_ctx.cct; + ldout(cct, 20) << this << " " << __func__ << dendl; + + bool predecessor_commit_valid = false; + uint64_t predecessor_tag_tid = 0; + uint64_t predecessor_entry_tid = 0; + { + Mutex::Locker locker(m_lock); + assert(m_journaler != nullptr && is_tag_owner()); + + cls::journal::Client client; + int r = m_journaler->get_cached_client(IMAGE_CLIENT_ID, &client); + if (r < 0) { + lderr(cct) << "failed to retrieve client: " << cpp_strerror(r) << dendl; + m_image_ctx.op_work_queue->queue(on_finish, r); + return; + } + + // since we are primary, populate the predecessor with our known commit + // position + assert(m_tag_data.mirror_uuid == LOCAL_MIRROR_UUID); + if (!client.commit_position.object_positions.empty()) { + auto position = client.commit_position.object_positions.front(); + predecessor_commit_valid = true; + predecessor_tag_tid = position.tag_tid; + predecessor_entry_tid = position.entry_tid; + } + } + + allocate_tag(LOCAL_MIRROR_UUID, LOCAL_MIRROR_UUID, predecessor_commit_valid, + predecessor_tag_tid, predecessor_entry_tid, on_finish); +} + template void Journal::allocate_tag(const std::string &mirror_uuid, + const std::string &predecessor_mirror_uuid, + bool predecessor_commit_valid, + uint64_t predecessor_tag_tid, + uint64_t predecessor_entry_tid, Context *on_finish) { CephContext *cct = m_image_ctx.cct; ldout(cct, 20) << this << " " << __func__ << ": mirror_uuid=" << mirror_uuid << dendl; Mutex::Locker locker(m_lock); - assert(m_journaler != nullptr && is_tag_owner()); + assert(m_journaler != nullptr); - // NOTE: currently responsibility of caller to provide local mirror - // uuid constant or remote peer uuid journal::TagData tag_data; tag_data.mirror_uuid = mirror_uuid; - - // TODO: inject current commit position into tag data (need updated journaler PR) - tag_data.predecessor_mirror_uuid = m_tag_data.mirror_uuid; + tag_data.predecessor_mirror_uuid = predecessor_mirror_uuid; + tag_data.predecessor_commit_valid = predecessor_commit_valid; + tag_data.predecessor_tag_tid = predecessor_tag_tid; + tag_data.predecessor_entry_tid = predecessor_entry_tid; bufferlist tag_bl; ::encode(tag_data, tag_bl); diff --git a/src/librbd/Journal.h b/src/librbd/Journal.h index fe9ccf9ae3f..ca294fe27d1 100644 --- a/src/librbd/Journal.h +++ b/src/librbd/Journal.h @@ -113,7 +113,11 @@ public: void close(Context *on_finish); bool is_tag_owner() const; - void allocate_tag(const std::string &mirror_uuid, Context *on_finish); + void allocate_local_tag(Context *on_finish); + void allocate_tag(const std::string &mirror_uuid, + const std::string &predecessor_mirror_uuid, + bool predecessor_commit_valid, uint64_t predecessor_tag_tid, + uint64_t predecessor_entry_tid, Context *on_finish); void flush_commit_position(Context *on_finish); diff --git a/src/librbd/journal/StandardPolicy.cc b/src/librbd/journal/StandardPolicy.cc index 3f7e3df7ecc..9e718288706 100644 --- a/src/librbd/journal/StandardPolicy.cc +++ b/src/librbd/journal/StandardPolicy.cc @@ -22,7 +22,7 @@ void StandardPolicy::allocate_tag_on_lock(Context *on_finish) { return; } - m_image_ctx->journal->allocate_tag(Journal<>::LOCAL_MIRROR_UUID, on_finish); + m_image_ctx->journal->allocate_local_tag(on_finish); } void StandardPolicy::cancel_external_replay(Context *on_finish) { -- 2.39.5