From: Jason Dillaman Date: Tue, 22 Mar 2016 02:01:05 +0000 (-0400) Subject: librbd: helper methods to allocate tags associated to remote journals X-Git-Tag: v10.1.1~64^2~29 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7d10eb01c0f4dfedd153f492f06451ea2bcdda60;p=ceph.git 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 --- diff --git a/src/librbd/Journal.cc b/src/librbd/Journal.cc index ec000f986518..ad8900d1d06e 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 fe9ccf9ae3ff..ca294fe27d17 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 3f7e3df7ecc8..9e718288706e 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) {