]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: helper methods to allocate tags associated to remote journals
authorJason Dillaman <dillaman@redhat.com>
Tue, 22 Mar 2016 02:01:05 +0000 (22:01 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 29 Mar 2016 19:12:29 +0000 (15:12 -0400)
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 <dillaman@redhat.com>
src/librbd/Journal.cc
src/librbd/Journal.h
src/librbd/journal/StandardPolicy.cc

index ec000f986518789d30db3300e29c4a51550267b1..ad8900d1d06e5a5aaa5aacba80cfd5cc7fa44c48 100644 (file)
@@ -501,9 +501,21 @@ int Journal<I>::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<I>::is_tag_owner() const {
   return (m_tag_data.mirror_uuid == LOCAL_MIRROR_UUID);
 }
 
+template <typename I>
+void Journal<I>::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 <typename I>
 void Journal<I>::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);
index fe9ccf9ae3ffcf15ae2b92e14e4996956aee9903..ca294fe27d17ca4066cdde0d6d36f480c054d5b0 100644 (file)
@@ -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);
 
index 3f7e3df7ecc8bfbcfceecac41b5ed6fdbf82ecdf..9e718288706e8b5f1ed5300a87685e80e400951a 100644 (file)
@@ -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) {