]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #ifndef CEPH_LIBRBD_WATCHER_H | |
5 | #define CEPH_LIBRBD_WATCHER_H | |
6 | ||
7 | #include "common/Mutex.h" | |
8 | #include "common/RWLock.h" | |
9 | #include "include/rados/librados.hpp" | |
10 | #include "librbd/watcher/Notifier.h" | |
11 | #include "librbd/watcher/Types.h" | |
12 | #include <string> | |
13 | #include <utility> | |
14 | ||
15 | class ContextWQ; | |
16 | ||
17 | namespace librbd { | |
18 | ||
19 | namespace watcher { struct NotifyResponse; } | |
20 | ||
21 | class Watcher { | |
22 | public: | |
23 | struct C_NotifyAck : public Context { | |
24 | Watcher *watcher; | |
25 | CephContext *cct; | |
26 | uint64_t notify_id; | |
27 | uint64_t handle; | |
28 | bufferlist out; | |
29 | ||
30 | C_NotifyAck(Watcher *watcher, uint64_t notify_id, uint64_t handle); | |
31 | void finish(int r) override; | |
32 | }; | |
33 | ||
34 | Watcher(librados::IoCtx& ioctx, ContextWQ *work_queue, | |
35 | const std::string& oid); | |
36 | virtual ~Watcher(); | |
37 | ||
38 | void register_watch(Context *on_finish); | |
39 | void unregister_watch(Context *on_finish); | |
40 | void flush(Context *on_finish); | |
41 | ||
42 | std::string get_oid() const; | |
43 | void set_oid(const string& oid); | |
44 | ||
45 | uint64_t get_watch_handle() const { | |
46 | RWLock::RLocker watch_locker(m_watch_lock); | |
47 | return m_watch_handle; | |
48 | } | |
49 | ||
50 | bool is_registered() const { | |
51 | RWLock::RLocker locker(m_watch_lock); | |
52 | return m_watch_state == WATCH_STATE_REGISTERED; | |
53 | } | |
54 | bool is_unregistered() const { | |
55 | RWLock::RLocker locker(m_watch_lock); | |
56 | return m_watch_state == WATCH_STATE_UNREGISTERED; | |
57 | } | |
58 | ||
59 | protected: | |
60 | enum WatchState { | |
61 | WATCH_STATE_UNREGISTERED, | |
62 | WATCH_STATE_REGISTERING, | |
63 | WATCH_STATE_REGISTERED, | |
64 | WATCH_STATE_ERROR, | |
65 | WATCH_STATE_REWATCHING | |
66 | }; | |
67 | ||
68 | librados::IoCtx& m_ioctx; | |
69 | ContextWQ *m_work_queue; | |
70 | std::string m_oid; | |
71 | CephContext *m_cct; | |
72 | mutable RWLock m_watch_lock; | |
73 | uint64_t m_watch_handle; | |
74 | watcher::Notifier m_notifier; | |
75 | WatchState m_watch_state; | |
76 | ||
77 | void send_notify(bufferlist &payload, | |
78 | watcher::NotifyResponse *response = nullptr, | |
79 | Context *on_finish = nullptr); | |
80 | ||
81 | virtual void handle_notify(uint64_t notify_id, uint64_t handle, | |
82 | uint64_t notifier_id, bufferlist &bl) = 0; | |
83 | ||
84 | virtual void handle_error(uint64_t cookie, int err); | |
85 | ||
86 | void acknowledge_notify(uint64_t notify_id, uint64_t handle, | |
87 | bufferlist &out); | |
88 | ||
89 | virtual void handle_rewatch_complete(int r) { } | |
90 | ||
91 | private: | |
92 | /** | |
93 | * @verbatim | |
94 | * | |
95 | * <start> | |
96 | * | | |
97 | * v | |
98 | * UNREGISTERED | |
99 | * | | |
100 | * | (register_watch) | |
101 | * | | |
102 | * REGISTERING | |
103 | * | | |
104 | * v (watch error) | |
105 | * REGISTERED * * * * * * * > ERROR | |
106 | * | ^ | | |
107 | * | | | (rewatch) | |
108 | * | | v | |
109 | * | | REWATCHING | |
110 | * | | | | |
111 | * | | | | |
112 | * | \---------------------/ | |
113 | * | | |
114 | * | (unregister_watch) | |
115 | * | | |
116 | * v | |
117 | * UNREGISTERED | |
118 | * | | |
119 | * v | |
120 | * <finish> | |
121 | * | |
122 | * @endverbatim | |
123 | */ | |
124 | ||
125 | struct WatchCtx : public librados::WatchCtx2 { | |
126 | Watcher &watcher; | |
127 | ||
128 | WatchCtx(Watcher &parent) : watcher(parent) {} | |
129 | ||
130 | void handle_notify(uint64_t notify_id, | |
131 | uint64_t handle, | |
132 | uint64_t notifier_id, | |
133 | bufferlist& bl) override; | |
134 | void handle_error(uint64_t handle, int err) override; | |
135 | }; | |
136 | ||
137 | struct C_RegisterWatch : public Context { | |
138 | Watcher *watcher; | |
139 | Context *on_finish; | |
140 | ||
141 | C_RegisterWatch(Watcher *watcher, Context *on_finish) | |
142 | : watcher(watcher), on_finish(on_finish) { | |
143 | } | |
144 | void finish(int r) override { | |
145 | watcher->handle_register_watch(r, on_finish); | |
146 | } | |
147 | }; | |
148 | ||
149 | WatchCtx m_watch_ctx; | |
150 | Context *m_unregister_watch_ctx = nullptr; | |
151 | ||
152 | void handle_register_watch(int r, Context *on_finish); | |
153 | ||
154 | void rewatch(); | |
155 | void handle_rewatch(int r); | |
156 | ||
157 | }; | |
158 | ||
159 | } // namespace librbd | |
160 | ||
161 | #endif // CEPH_LIBRBD_WATCHER_H |