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_WATCHER_H
5 #define CEPH_LIBRBD_WATCHER_H
7 #include "common/AsyncOpTracker.h"
8 #include "common/ceph_mutex.h"
9 #include "common/RWLock.h"
10 #include "include/rados/librados.hpp"
11 #include "librbd/watcher/Notifier.h"
12 #include "librbd/watcher/Types.h"
20 namespace watcher
{ struct NotifyResponse
; }
24 struct C_NotifyAck
: public Context
{
31 C_NotifyAck(Watcher
*watcher
, uint64_t notify_id
, uint64_t handle
);
32 void finish(int r
) override
;
35 Watcher(librados::IoCtx
& ioctx
, ContextWQ
*work_queue
,
36 const std::string
& oid
);
39 void register_watch(Context
*on_finish
);
40 virtual void unregister_watch(Context
*on_finish
);
41 void flush(Context
*on_finish
);
43 bool notifications_blocked() const;
44 virtual void block_notifies(Context
*on_finish
);
45 void unblock_notifies();
47 std::string
get_oid() const;
48 void set_oid(const string
& oid
);
50 uint64_t get_watch_handle() const {
51 std::shared_lock watch_locker
{m_watch_lock
};
52 return m_watch_handle
;
55 bool is_registered() const {
56 std::shared_lock locker
{m_watch_lock
};
57 return is_registered(m_watch_lock
);
59 bool is_unregistered() const {
60 std::shared_lock locker
{m_watch_lock
};
61 return is_unregistered(m_watch_lock
);
63 bool is_blacklisted() const {
64 std::shared_lock locker
{m_watch_lock
};
65 return m_watch_blacklisted
;
71 WATCH_STATE_REGISTERING
,
72 WATCH_STATE_REWATCHING
75 librados::IoCtx
& m_ioctx
;
76 ContextWQ
*m_work_queue
;
79 mutable ceph::shared_mutex m_watch_lock
;
80 uint64_t m_watch_handle
;
81 watcher::Notifier m_notifier
;
83 WatchState m_watch_state
;
84 bool m_watch_blacklisted
= false;
86 AsyncOpTracker m_async_op_tracker
;
88 bool is_registered(const ceph::shared_mutex
&) const {
89 return (m_watch_state
== WATCH_STATE_IDLE
&& m_watch_handle
!= 0);
91 bool is_unregistered(const ceph::shared_mutex
&) const {
92 return (m_watch_state
== WATCH_STATE_IDLE
&& m_watch_handle
== 0);
95 void send_notify(bufferlist
&payload
,
96 watcher::NotifyResponse
*response
= nullptr,
97 Context
*on_finish
= nullptr);
99 virtual void handle_notify(uint64_t notify_id
, uint64_t handle
,
100 uint64_t notifier_id
, bufferlist
&bl
) = 0;
102 virtual void handle_error(uint64_t cookie
, int err
);
104 void acknowledge_notify(uint64_t notify_id
, uint64_t handle
,
107 virtual void handle_rewatch_complete(int r
) { }
123 * REGISTERED * * * * * * * > ERROR
130 * | \---------------------/
132 * | (unregister_watch)
143 struct WatchCtx
: public librados::WatchCtx2
{
146 WatchCtx(Watcher
&parent
) : watcher(parent
) {}
148 void handle_notify(uint64_t notify_id
,
150 uint64_t notifier_id
,
151 bufferlist
& bl
) override
;
152 void handle_error(uint64_t handle
, int err
) override
;
155 struct C_RegisterWatch
: public Context
{
159 C_RegisterWatch(Watcher
*watcher
, Context
*on_finish
)
160 : watcher(watcher
), on_finish(on_finish
) {
162 void finish(int r
) override
{
163 watcher
->handle_register_watch(r
, on_finish
);
167 WatchCtx m_watch_ctx
;
168 Context
*m_unregister_watch_ctx
= nullptr;
170 bool m_watch_error
= false;
172 uint32_t m_blocked_count
= 0;
174 void handle_register_watch(int r
, Context
*on_finish
);
177 void handle_rewatch(int r
);
178 void handle_rewatch_callback(int r
);
182 } // namespace librbd
184 #endif // CEPH_LIBRBD_WATCHER_H