1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_LIBRBD_MANAGED_LOCK_H
5 #define CEPH_LIBRBD_MANAGED_LOCK_H
7 #include "include/int_types.h"
8 #include "include/Context.h"
9 #include "include/rados/librados.hpp"
10 #include "common/AsyncOpTracker.h"
11 #include "common/Mutex.h"
12 #include "cls/lock/cls_lock_types.h"
13 #include "librbd/watcher/Types.h"
14 #include "librbd/managed_lock/Types.h"
25 namespace managed_lock
{ struct Locker
; }
27 template <typename ImageCtxT
= librbd::ImageCtx
>
30 typedef watcher::Traits
<ImageCtxT
> TypeTraits
;
31 typedef typename
TypeTraits::Watcher Watcher
;
34 static ManagedLock
*create(librados::IoCtx
& ioctx
, ContextWQ
*work_queue
,
35 const std::string
& oid
, Watcher
*watcher
,
36 managed_lock::Mode mode
,
37 bool blacklist_on_break_lock
,
38 uint32_t blacklist_expire_seconds
) {
39 return new ManagedLock(ioctx
, work_queue
, oid
, watcher
, mode
,
40 blacklist_on_break_lock
, blacklist_expire_seconds
);
46 ManagedLock(librados::IoCtx
& ioctx
, ContextWQ
*work_queue
,
47 const std::string
& oid
, Watcher
*watcher
,
48 managed_lock::Mode mode
, bool blacklist_on_break_lock
,
49 uint32_t blacklist_expire_seconds
);
50 virtual ~ManagedLock();
52 bool is_lock_owner() const;
54 void shut_down(Context
*on_shutdown
);
55 void acquire_lock(Context
*on_acquired
);
56 void try_acquire_lock(Context
*on_acquired
);
57 void release_lock(Context
*on_released
);
58 void reacquire_lock(Context
*on_reacquired
= nullptr);
59 void get_locker(managed_lock::Locker
*locker
, Context
*on_finish
);
60 void break_lock(const managed_lock::Locker
&locker
, bool force_break_lock
,
63 int assert_header_locked();
65 bool is_shutdown() const {
66 Mutex::Locker
l(m_lock
);
67 return is_state_shutdown();
73 inline void set_state_uninitialized() {
74 assert(m_lock
.is_locked());
75 assert(m_state
== STATE_UNLOCKED
);
76 m_state
= STATE_UNINITIALIZED
;
78 inline void set_state_initializing() {
79 assert(m_lock
.is_locked());
80 assert(m_state
== STATE_UNINITIALIZED
);
81 m_state
= STATE_INITIALIZING
;
83 inline void set_state_unlocked() {
84 assert(m_lock
.is_locked());
85 assert(m_state
== STATE_INITIALIZING
|| m_state
== STATE_RELEASING
);
86 m_state
= STATE_UNLOCKED
;
88 inline void set_state_waiting_for_lock() {
89 assert(m_lock
.is_locked());
90 assert(m_state
== STATE_ACQUIRING
);
91 m_state
= STATE_WAITING_FOR_LOCK
;
93 inline void set_state_post_acquiring() {
94 assert(m_lock
.is_locked());
95 assert(m_state
== STATE_ACQUIRING
);
96 m_state
= STATE_POST_ACQUIRING
;
99 bool is_state_shutdown() const;
100 inline bool is_state_acquiring() const {
101 assert(m_lock
.is_locked());
102 return m_state
== STATE_ACQUIRING
;
104 inline bool is_state_post_acquiring() const {
105 assert(m_lock
.is_locked());
106 return m_state
== STATE_POST_ACQUIRING
;
108 inline bool is_state_releasing() const {
109 assert(m_lock
.is_locked());
110 return m_state
== STATE_RELEASING
;
112 inline bool is_state_pre_releasing() const {
113 assert(m_lock
.is_locked());
114 return m_state
== STATE_PRE_RELEASING
;
116 inline bool is_state_locked() const {
117 assert(m_lock
.is_locked());
118 return m_state
== STATE_LOCKED
;
120 inline bool is_state_waiting_for_lock() const {
121 assert(m_lock
.is_locked());
122 return m_state
== STATE_WAITING_FOR_LOCK
;
125 inline bool is_action_acquire_lock() const {
126 assert(m_lock
.is_locked());
127 return get_active_action() == ACTION_ACQUIRE_LOCK
;
130 virtual void shutdown_handler(int r
, Context
*on_finish
);
131 virtual void pre_acquire_lock_handler(Context
*on_finish
);
132 virtual void post_acquire_lock_handler(int r
, Context
*on_finish
);
133 virtual void pre_release_lock_handler(bool shutting_down
,
135 virtual void post_release_lock_handler(bool shutting_down
, int r
,
137 virtual void post_reacquire_lock_handler(int r
, Context
*on_finish
);
139 void execute_next_action();
149 * UNLOCKED -----------------------------------------> ACQUIRING
156 * PRE_RELEASING <----------------------------------------- LOCKED
161 * REACQUIRING -------------------------------------> <finish>
164 * . . . > <RELEASE action> ---> <ACQUIRE action> ---/
166 * <UNLOCKED/LOCKED states>
170 * PRE_SHUTTING_DOWN ---> SHUTTING_DOWN ---> SHUTDOWN ---> <finish>
180 STATE_POST_ACQUIRING
,
181 STATE_WAITING_FOR_REGISTER
,
182 STATE_WAITING_FOR_LOCK
,
186 STATE_PRE_SHUTTING_DOWN
,
194 ACTION_REACQUIRE_LOCK
,
199 typedef std::list
<Context
*> Contexts
;
200 typedef std::pair
<Action
, Contexts
> ActionContexts
;
201 typedef std::list
<ActionContexts
> ActionsContexts
;
203 struct C_ShutDownRelease
: public Context
{
205 C_ShutDownRelease(ManagedLock
*lock
)
208 void finish(int r
) override
{
209 lock
->send_shutdown_release();
213 librados::IoCtx
& m_ioctx
;
215 ContextWQ
*m_work_queue
;
218 managed_lock::Mode m_mode
;
219 bool m_blacklist_on_break_lock
;
220 uint32_t m_blacklist_expire_seconds
;
222 std::string m_cookie
;
223 std::string m_new_cookie
;
226 State m_post_next_state
;
228 ActionsContexts m_actions_contexts
;
229 AsyncOpTracker m_async_op_tracker
;
231 bool is_lock_owner(Mutex
&lock
) const;
232 bool is_transition_state() const;
234 void append_context(Action action
, Context
*ctx
);
235 void execute_action(Action action
, Context
*ctx
);
237 Action
get_active_action() const;
238 void complete_active_action(State next_state
, int r
);
240 void send_acquire_lock();
241 void handle_pre_acquire_lock(int r
);
242 void handle_acquire_lock(int r
);
243 void handle_post_acquire_lock(int r
);
244 void revert_to_unlock_state(int r
);
246 void send_reacquire_lock();
247 void handle_reacquire_lock(int r
);
249 void send_release_lock();
250 void handle_pre_release_lock(int r
);
251 void handle_release_lock(int r
);
252 void handle_post_release_lock(int r
);
254 void send_shutdown();
255 void handle_shutdown(int r
);
256 void send_shutdown_release();
257 void handle_shutdown_pre_release(int r
);
258 void handle_shutdown_post_release(int r
);
259 void wait_for_tracked_ops(int r
);
260 void complete_shutdown(int r
);
263 } // namespace librbd
265 extern template class librbd::ManagedLock
<librbd::ImageCtx
>;
267 #endif // CEPH_LIBRBD_MANAGED_LOCK_H