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