]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/Watcher.h
update sources to 12.2.10
[ceph.git] / ceph / src / librbd / Watcher.h
CommitLineData
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
31f18b77 7#include "common/AsyncOpTracker.h"
7c673cae
FG
8#include "common/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"
13#include <string>
14#include <utility>
15
16class ContextWQ;
17
18namespace librbd {
19
20namespace watcher { struct NotifyResponse; }
21
22class Watcher {
23public:
24 struct C_NotifyAck : public Context {
25 Watcher *watcher;
26 CephContext *cct;
27 uint64_t notify_id;
28 uint64_t handle;
29 bufferlist out;
30
31 C_NotifyAck(Watcher *watcher, uint64_t notify_id, uint64_t handle);
32 void finish(int r) override;
33 };
34
35 Watcher(librados::IoCtx& ioctx, ContextWQ *work_queue,
36 const std::string& oid);
37 virtual ~Watcher();
38
39 void register_watch(Context *on_finish);
31f18b77 40 virtual void unregister_watch(Context *on_finish);
7c673cae
FG
41 void flush(Context *on_finish);
42
31f18b77
FG
43 bool notifications_blocked() const;
44 virtual void block_notifies(Context *on_finish);
45 void unblock_notifies();
46
7c673cae
FG
47 std::string get_oid() const;
48 void set_oid(const string& oid);
49
50 uint64_t get_watch_handle() const {
51 RWLock::RLocker watch_locker(m_watch_lock);
52 return m_watch_handle;
53 }
54
55 bool is_registered() const {
56 RWLock::RLocker locker(m_watch_lock);
28e407b8 57 return is_registered(m_watch_lock);
7c673cae
FG
58 }
59 bool is_unregistered() const {
60 RWLock::RLocker locker(m_watch_lock);
28e407b8 61 return is_unregistered(m_watch_lock);
7c673cae 62 }
91327a77
AA
63 bool is_blacklisted() const {
64 RWLock::RLocker locker(m_watch_lock);
65 return m_watch_blacklisted;
66 }
7c673cae
FG
67
68protected:
69 enum WatchState {
28e407b8 70 WATCH_STATE_IDLE,
7c673cae 71 WATCH_STATE_REGISTERING,
7c673cae
FG
72 WATCH_STATE_REWATCHING
73 };
74
75 librados::IoCtx& m_ioctx;
76 ContextWQ *m_work_queue;
77 std::string m_oid;
78 CephContext *m_cct;
79 mutable RWLock m_watch_lock;
80 uint64_t m_watch_handle;
81 watcher::Notifier m_notifier;
91327a77 82
7c673cae 83 WatchState m_watch_state;
91327a77
AA
84 bool m_watch_blacklisted = false;
85
31f18b77 86 AsyncOpTracker m_async_op_tracker;
7c673cae 87
28e407b8
AA
88 bool is_registered(const RWLock&) const {
89 return (m_watch_state == WATCH_STATE_IDLE && m_watch_handle != 0);
90 }
91 bool is_unregistered(const RWLock&) const {
92 return (m_watch_state == WATCH_STATE_IDLE && m_watch_handle == 0);
93 }
94
7c673cae
FG
95 void send_notify(bufferlist &payload,
96 watcher::NotifyResponse *response = nullptr,
97 Context *on_finish = nullptr);
98
99 virtual void handle_notify(uint64_t notify_id, uint64_t handle,
100 uint64_t notifier_id, bufferlist &bl) = 0;
101
102 virtual void handle_error(uint64_t cookie, int err);
103
104 void acknowledge_notify(uint64_t notify_id, uint64_t handle,
105 bufferlist &out);
106
107 virtual void handle_rewatch_complete(int r) { }
108
109private:
110 /**
111 * @verbatim
112 *
113 * <start>
114 * |
115 * v
116 * UNREGISTERED
117 * |
118 * | (register_watch)
119 * |
120 * REGISTERING
121 * |
122 * v (watch error)
123 * REGISTERED * * * * * * * > ERROR
124 * | ^ |
125 * | | | (rewatch)
126 * | | v
127 * | | REWATCHING
128 * | | |
129 * | | |
130 * | \---------------------/
131 * |
132 * | (unregister_watch)
133 * |
134 * v
135 * UNREGISTERED
136 * |
137 * v
138 * <finish>
139 *
140 * @endverbatim
141 */
142
143 struct WatchCtx : public librados::WatchCtx2 {
144 Watcher &watcher;
145
146 WatchCtx(Watcher &parent) : watcher(parent) {}
147
148 void handle_notify(uint64_t notify_id,
149 uint64_t handle,
150 uint64_t notifier_id,
151 bufferlist& bl) override;
152 void handle_error(uint64_t handle, int err) override;
153 };
154
155 struct C_RegisterWatch : public Context {
156 Watcher *watcher;
157 Context *on_finish;
158
159 C_RegisterWatch(Watcher *watcher, Context *on_finish)
160 : watcher(watcher), on_finish(on_finish) {
161 }
162 void finish(int r) override {
163 watcher->handle_register_watch(r, on_finish);
164 }
165 };
166
167 WatchCtx m_watch_ctx;
168 Context *m_unregister_watch_ctx = nullptr;
169
28e407b8
AA
170 bool m_watch_error = false;
171
31f18b77
FG
172 uint32_t m_blocked_count = 0;
173
7c673cae
FG
174 void handle_register_watch(int r, Context *on_finish);
175
176 void rewatch();
177 void handle_rewatch(int r);
28e407b8 178 void handle_rewatch_callback(int r);
7c673cae
FG
179
180};
181
182} // namespace librbd
183
184#endif // CEPH_LIBRBD_WATCHER_H