]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/Watcher.h
update sources to 12.2.7
[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
FG
62 }
63
64protected:
65 enum WatchState {
28e407b8 66 WATCH_STATE_IDLE,
7c673cae 67 WATCH_STATE_REGISTERING,
7c673cae
FG
68 WATCH_STATE_REWATCHING
69 };
70
71 librados::IoCtx& m_ioctx;
72 ContextWQ *m_work_queue;
73 std::string m_oid;
74 CephContext *m_cct;
75 mutable RWLock m_watch_lock;
76 uint64_t m_watch_handle;
77 watcher::Notifier m_notifier;
78 WatchState m_watch_state;
31f18b77 79 AsyncOpTracker m_async_op_tracker;
7c673cae 80
28e407b8
AA
81 bool is_registered(const RWLock&) const {
82 return (m_watch_state == WATCH_STATE_IDLE && m_watch_handle != 0);
83 }
84 bool is_unregistered(const RWLock&) const {
85 return (m_watch_state == WATCH_STATE_IDLE && m_watch_handle == 0);
86 }
87
7c673cae
FG
88 void send_notify(bufferlist &payload,
89 watcher::NotifyResponse *response = nullptr,
90 Context *on_finish = nullptr);
91
92 virtual void handle_notify(uint64_t notify_id, uint64_t handle,
93 uint64_t notifier_id, bufferlist &bl) = 0;
94
95 virtual void handle_error(uint64_t cookie, int err);
96
97 void acknowledge_notify(uint64_t notify_id, uint64_t handle,
98 bufferlist &out);
99
100 virtual void handle_rewatch_complete(int r) { }
101
102private:
103 /**
104 * @verbatim
105 *
106 * <start>
107 * |
108 * v
109 * UNREGISTERED
110 * |
111 * | (register_watch)
112 * |
113 * REGISTERING
114 * |
115 * v (watch error)
116 * REGISTERED * * * * * * * > ERROR
117 * | ^ |
118 * | | | (rewatch)
119 * | | v
120 * | | REWATCHING
121 * | | |
122 * | | |
123 * | \---------------------/
124 * |
125 * | (unregister_watch)
126 * |
127 * v
128 * UNREGISTERED
129 * |
130 * v
131 * <finish>
132 *
133 * @endverbatim
134 */
135
136 struct WatchCtx : public librados::WatchCtx2 {
137 Watcher &watcher;
138
139 WatchCtx(Watcher &parent) : watcher(parent) {}
140
141 void handle_notify(uint64_t notify_id,
142 uint64_t handle,
143 uint64_t notifier_id,
144 bufferlist& bl) override;
145 void handle_error(uint64_t handle, int err) override;
146 };
147
148 struct C_RegisterWatch : public Context {
149 Watcher *watcher;
150 Context *on_finish;
151
152 C_RegisterWatch(Watcher *watcher, Context *on_finish)
153 : watcher(watcher), on_finish(on_finish) {
154 }
155 void finish(int r) override {
156 watcher->handle_register_watch(r, on_finish);
157 }
158 };
159
160 WatchCtx m_watch_ctx;
161 Context *m_unregister_watch_ctx = nullptr;
162
28e407b8
AA
163 bool m_watch_error = false;
164
31f18b77
FG
165 uint32_t m_blocked_count = 0;
166
7c673cae
FG
167 void handle_register_watch(int r, Context *on_finish);
168
169 void rewatch();
170 void handle_rewatch(int r);
28e407b8 171 void handle_rewatch_callback(int r);
7c673cae
FG
172
173};
174
175} // namespace librbd
176
177#endif // CEPH_LIBRBD_WATCHER_H