]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/Watcher.h
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / librbd / Watcher.h
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