]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: don't acquire lock for primary local images
authorJason Dillaman <dillaman@redhat.com>
Wed, 23 Mar 2016 22:00:52 +0000 (18:00 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 29 Mar 2016 19:12:29 +0000 (15:12 -0400)
Abort the image replay for any local images that are marked as primary.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc
src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc
src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h

index 18f9bf4718d31ee9b6e5bd06df6fdc48305d3c24..cd0646b0abc6a1e55721d9120d42af0be6cb9f8a 100644 (file)
@@ -208,6 +208,12 @@ void BootstrapRequest<I>::handle_open_local_image(int r) {
     dout(10) << ": local image missing" << dendl;
     create_local_image();
     return;
+  } else if (r == -EREMOTEIO) {
+    assert(*m_local_image_ctx == nullptr);
+    dout(10) << "local image is primary -- skipping image replay" << dendl;
+    m_ret_val = r;
+    close_remote_image();
+    return;
   } else if (r < 0) {
     assert(*m_local_image_ctx == nullptr);
     derr << ": failed to open local image: " << cpp_strerror(r) << dendl;
index 3f4f483707e12a95bb222ec57edbc60026f91a85..4bdb85285ff96840710b99b2e1ec7f1e8aa59380 100644 (file)
@@ -8,14 +8,16 @@
 #include "librbd/ExclusiveLock.h"
 #include "librbd/ImageCtx.h"
 #include "librbd/ImageState.h"
+#include "librbd/Journal.h"
 #include "librbd/Utils.h"
 #include "librbd/exclusive_lock/Policy.h"
 #include "librbd/journal/Policy.h"
+#include <type_traits>
 
 #define dout_subsys ceph_subsys_rbd_mirror
 #undef dout_prefix
 #define dout_prefix *_dout << "rbd::mirror::image_replayer::OpenLocalImageRequest: " \
-                           << this << " " << __func__
+                           << this << " " << __func__ << " "
 
 namespace rbd {
 namespace mirror {
@@ -79,10 +81,14 @@ void OpenLocalImageRequest<I>::send_open_image() {
 
   *m_local_image_ctx = I::create(m_local_image_name, m_local_image_id, nullptr,
                                  m_local_io_ctx, false);
-  (*m_local_image_ctx)->set_exclusive_lock_policy(
-    new MirrorExclusiveLockPolicy());
-  (*m_local_image_ctx)->set_journal_policy(
-    new MirrorJournalPolicy(m_work_queue));
+  {
+    RWLock::WLocker owner_locker((*m_local_image_ctx)->owner_lock);
+    RWLock::WLocker snap_locker((*m_local_image_ctx)->snap_lock);
+    (*m_local_image_ctx)->set_exclusive_lock_policy(
+      new MirrorExclusiveLockPolicy());
+    (*m_local_image_ctx)->set_journal_policy(
+      new MirrorJournalPolicy(m_work_queue));
+  }
 
   Context *ctx = create_context_callback<
     OpenLocalImageRequest<I>, &OpenLocalImageRequest<I>::handle_open_image>(
@@ -99,10 +105,6 @@ void OpenLocalImageRequest<I>::handle_open_image(int r) {
          << cpp_strerror(r) << dendl;
     send_close_image(true, r);
     return;
-  } else if ((*m_local_image_ctx)->exclusive_lock == nullptr) {
-    derr << "image does not support exclusive lock" << dendl;
-    send_close_image(false, -EINVAL);
-    return;
   }
 
   send_lock_image();
@@ -110,13 +112,39 @@ void OpenLocalImageRequest<I>::handle_open_image(int r) {
 
 template <typename I>
 void OpenLocalImageRequest<I>::send_lock_image() {
+  // deduce the class type for the journal to support unit tests
+  typedef typename std::decay<decltype(*I::journal)>::type Journal;
+
   dout(20) << dendl;
 
+  RWLock::RLocker owner_locker((*m_local_image_ctx)->owner_lock);
+  if ((*m_local_image_ctx)->exclusive_lock == nullptr) {
+    derr << "image does not support exclusive lock" << dendl;
+    send_close_image(false, -EINVAL);
+    return;
+  }
+
+  // TODO: make an async version
+  bool tag_owner;
+  int r = Journal::is_tag_owner(*m_local_image_ctx, &tag_owner);
+  if (r < 0) {
+    derr << "failed to query journal: " << cpp_strerror(r) << dendl;
+    send_close_image(false, r);
+    return;
+  }
+
+  // if the local image owns the tag -- don't steal the lock since
+  // we aren't going to mirror peer data into this image anyway
+  if (tag_owner) {
+    dout(10) << "local image is primary -- skipping image replay" << dendl;
+    send_close_image(false, -EREMOTEIO);
+    return;
+  }
+
   Context *ctx = create_context_callback<
     OpenLocalImageRequest<I>, &OpenLocalImageRequest<I>::handle_lock_image>(
       this);
 
-  RWLock::RLocker owner_locker((*m_local_image_ctx)->owner_lock);
   (*m_local_image_ctx)->exclusive_lock->request_lock(ctx);
 }
 
index a8db813bcabe6e5553c576e99b3641aae6446e75..e40b1c2a06226b59b4ee438e4d91aa3b66f7d13f 100644 (file)
@@ -46,13 +46,13 @@ private:
    * <start>
    *    |
    *    v
-   * OPEN_IMAGE * * * * * * *
-   *    |                   *
-   *    v                   v
+   * OPEN_IMAGE * * * * * * * *
+   *    |                     *
+   *    v (skip if primary)   v
    * LOCK_IMAGE * * * > CLOSE_IMAGE
-   *    |                   |
-   *    v                   |
-   * <finish> <-------------/
+   *    |                     |
+   *    v                     |
+   * <finish> <---------------/
    *
    * @endverbatim
    */