From: Jason Dillaman Date: Wed, 23 Mar 2016 22:00:52 +0000 (-0400) Subject: rbd-mirror: don't acquire lock for primary local images X-Git-Tag: v10.1.1~64^2~21 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f01efc8ce60d4fdbc7c3880dc73b5eb7b9334d73;p=ceph.git rbd-mirror: don't acquire lock for primary local images Abort the image replay for any local images that are marked as primary. Signed-off-by: Jason Dillaman --- diff --git a/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc index 18f9bf4718d3..cd0646b0abc6 100644 --- a/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc +++ b/src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc @@ -208,6 +208,12 @@ void BootstrapRequest::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; diff --git a/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc index 3f4f483707e1..4bdb85285ff9 100644 --- a/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc +++ b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc @@ -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 #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::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, &OpenLocalImageRequest::handle_open_image>( @@ -99,10 +105,6 @@ void OpenLocalImageRequest::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::handle_open_image(int r) { template void OpenLocalImageRequest::send_lock_image() { + // deduce the class type for the journal to support unit tests + typedef typename std::decay::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, &OpenLocalImageRequest::handle_lock_image>( this); - RWLock::RLocker owner_locker((*m_local_image_ctx)->owner_lock); (*m_local_image_ctx)->exclusive_lock->request_lock(ctx); } diff --git a/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h index a8db813bcabe..e40b1c2a0622 100644 --- a/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h +++ b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h @@ -46,13 +46,13 @@ private: * * | * v - * OPEN_IMAGE * * * * * * * - * | * - * v v + * OPEN_IMAGE * * * * * * * * + * | * + * v (skip if primary) v * LOCK_IMAGE * * * > CLOSE_IMAGE - * | | - * v | - * <-------------/ + * | | + * v | + * <---------------/ * * @endverbatim */