From 2afb2c31ed9e18d07decd40b8265804bfbdb62c5 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Mon, 21 Mar 2016 17:50:10 -0400 Subject: [PATCH] librbd: basic policy for controlling the release of the exclusive lock The rbd-mirror daemon will need to interlock with the request for the lock from another client with the successful sync of remote journal events. Signed-off-by: Jason Dillaman --- src/librbd/ImageCtx.cc | 17 ++++++++++++ src/librbd/ImageCtx.h | 7 +++++ src/librbd/ImageWatcher.cc | 3 ++- src/librbd/Makefile.am | 3 +++ src/librbd/exclusive_lock/Policy.h | 20 ++++++++++++++ src/librbd/exclusive_lock/StandardPolicy.cc | 21 +++++++++++++++ src/librbd/exclusive_lock/StandardPolicy.h | 30 +++++++++++++++++++++ 7 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/librbd/exclusive_lock/Policy.h create mode 100644 src/librbd/exclusive_lock/StandardPolicy.cc create mode 100644 src/librbd/exclusive_lock/StandardPolicy.h diff --git a/src/librbd/ImageCtx.cc b/src/librbd/ImageCtx.cc index 0f9b5a5d40d9b..d4c257d0e760c 100644 --- a/src/librbd/ImageCtx.cc +++ b/src/librbd/ImageCtx.cc @@ -15,6 +15,7 @@ #include "librbd/AsyncOperation.h" #include "librbd/AsyncRequest.h" #include "librbd/ExclusiveLock.h" +#include "librbd/exclusive_lock/StandardPolicy.h" #include "librbd/internal.h" #include "librbd/ImageCtx.h" #include "librbd/ImageState.h" @@ -187,6 +188,8 @@ struct C_InvalidateCache : public Context { op_work_queue = new ContextWQ("librbd::op_work_queue", cct->_conf->rbd_op_thread_timeout, thread_pool_singleton); + + exclusive_lock_policy = new exclusive_lock::StandardPolicy(this); } ImageCtx::~ImageCtx() { @@ -218,6 +221,7 @@ struct C_InvalidateCache : public Context { op_work_queue->drain(); aio_work_queue->drain(); + delete exclusive_lock_policy; delete op_work_queue; delete aio_work_queue; delete operations; @@ -1046,4 +1050,17 @@ struct C_InvalidateCache : public Context { state->handle_update_notification(); image_watcher->notify_header_update(on_finish); } + + exclusive_lock::Policy *ImageCtx::get_exclusive_lock_policy() const { + assert(owner_lock.is_locked()); + assert(exclusive_lock_policy != nullptr); + return exclusive_lock_policy; + } + + void ImageCtx::set_exclusive_lock_policy(exclusive_lock::Policy *policy) { + assert(owner_lock.is_wlocked()); + assert(policy != nullptr); + delete exclusive_lock_policy; + exclusive_lock_policy = policy; + } } diff --git a/src/librbd/ImageCtx.h b/src/librbd/ImageCtx.h index a302a1467c787..98dcd42d4d3da 100644 --- a/src/librbd/ImageCtx.h +++ b/src/librbd/ImageCtx.h @@ -52,6 +52,8 @@ namespace librbd { class ObjectMap; template class Operations; + namespace exclusive_lock { struct Policy; } + namespace operation { template class ResizeRequest; } @@ -185,6 +187,8 @@ namespace librbd { LibrbdAdminSocketHook *asok_hook; + exclusive_lock::Policy *exclusive_lock_policy = nullptr; + static bool _filter_metadata_confs(const string &prefix, std::map &configs, map &pairs, map *res); @@ -281,6 +285,9 @@ namespace librbd { void notify_update(); void notify_update(Context *on_finish); + + exclusive_lock::Policy *get_exclusive_lock_policy() const; + void set_exclusive_lock_policy(exclusive_lock::Policy *policy); }; } diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc index 0734490c9f5ae..8bb16c4e1b5ab 100644 --- a/src/librbd/ImageWatcher.cc +++ b/src/librbd/ImageWatcher.cc @@ -11,6 +11,7 @@ #include "librbd/Operations.h" #include "librbd/TaskFinisher.h" #include "librbd/Utils.h" +#include "librbd/exclusive_lock/Policy.h" #include "librbd/image_watcher/Notifier.h" #include "librbd/image_watcher/NotifyLockOwner.h" #include "include/encoding.h" @@ -615,7 +616,7 @@ bool ImageWatcher::handle_payload(const RequestLockPayload &payload, ldout(m_image_ctx.cct, 10) << this << " queuing release of exclusive lock" << dendl; - m_image_ctx.exclusive_lock->release_lock(nullptr); + m_image_ctx.get_exclusive_lock_policy()->lock_requested(false); } return true; } diff --git a/src/librbd/Makefile.am b/src/librbd/Makefile.am index 141135e2f0f6d..233ec80d98bc4 100644 --- a/src/librbd/Makefile.am +++ b/src/librbd/Makefile.am @@ -30,6 +30,7 @@ librbd_internal_la_SOURCES = \ librbd/Utils.cc \ librbd/exclusive_lock/AcquireRequest.cc \ librbd/exclusive_lock/ReleaseRequest.cc \ + librbd/exclusive_lock/StandardPolicy.cc \ librbd/image/CloseRequest.cc \ librbd/image/OpenRequest.cc \ librbd/image/RefreshParentRequest.cc \ @@ -110,7 +111,9 @@ noinst_HEADERS += \ librbd/Utils.h \ librbd/WatchNotifyTypes.h \ librbd/exclusive_lock/AcquireRequest.h \ + librbd/exclusive_lock/Policy.h \ librbd/exclusive_lock/ReleaseRequest.h \ + librbd/exclusive_lock/StandardPolicy.h \ librbd/image/CloseRequest.h \ librbd/image/OpenRequest.h \ librbd/image/RefreshParentRequest.h \ diff --git a/src/librbd/exclusive_lock/Policy.h b/src/librbd/exclusive_lock/Policy.h new file mode 100644 index 0000000000000..2ff8418b5ed91 --- /dev/null +++ b/src/librbd/exclusive_lock/Policy.h @@ -0,0 +1,20 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_EXCLUSIVE_LOCK_POLICY_H +#define CEPH_LIBRBD_EXCLUSIVE_LOCK_POLICY_H + +namespace librbd { +namespace exclusive_lock { + +struct Policy { + virtual ~Policy() { + } + + virtual void lock_requested(bool force) = 0; +}; + +} // namespace exclusive_lock +} // namespace librbd + +#endif // CEPH_LIBRBD_EXCLUSIVE_LOCK_POLICY_H diff --git a/src/librbd/exclusive_lock/StandardPolicy.cc b/src/librbd/exclusive_lock/StandardPolicy.cc new file mode 100644 index 0000000000000..22f0434d80320 --- /dev/null +++ b/src/librbd/exclusive_lock/StandardPolicy.cc @@ -0,0 +1,21 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "librbd/exclusive_lock/StandardPolicy.h" +#include "librbd/ImageCtx.h" +#include "librbd/ExclusiveLock.h" + +namespace librbd { +namespace exclusive_lock { + +void StandardPolicy::lock_requested(bool force) { + assert(m_image_ctx->owner_lock.is_locked()); + assert(m_image_ctx->exclusive_lock != nullptr); + + // release the lock upon request (ignore forced requests) + m_image_ctx->exclusive_lock->release_lock(nullptr); +} + +} // namespace exclusive_lock +} // namespace librbd + diff --git a/src/librbd/exclusive_lock/StandardPolicy.h b/src/librbd/exclusive_lock/StandardPolicy.h new file mode 100644 index 0000000000000..ddc78cc10594f --- /dev/null +++ b/src/librbd/exclusive_lock/StandardPolicy.h @@ -0,0 +1,30 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_EXCLUSIVE_LOCK_STANDARD_POLICY_H +#define CEPH_LIBRBD_EXCLUSIVE_LOCK_STANDARD_POLICY_H + +#include "librbd/exclusive_lock/Policy.h" + +namespace librbd { + +struct ImageCtx; + +namespace exclusive_lock { + +class StandardPolicy : public Policy{ +public: + StandardPolicy(ImageCtx *image_ctx) : m_image_ctx(image_ctx) { + } + + virtual void lock_requested(bool force); + +private: + ImageCtx *m_image_ctx; + +}; + +} // namespace exclusive_lock +} // namespace librbd + +#endif // CEPH_LIBRBD_EXCLUSIVE_LOCK_STANDARD_POLICY_H -- 2.39.5