1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_LIBRBD_WATCHER_H
5 #define CEPH_LIBRBD_WATCHER_H
7 #include "common/AsyncOpTracker.h"
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"
20 namespace watcher { struct NotifyResponse; }
24 struct C_NotifyAck : public Context {
31 C_NotifyAck(Watcher *watcher, uint64_t notify_id, uint64_t handle);
32 void finish(int r) override;
35 Watcher(librados::IoCtx& ioctx, ContextWQ *work_queue,
36 const std::string& oid);
39 void register_watch(Context *on_finish);
40 virtual void unregister_watch(Context *on_finish);
41 void flush(Context *on_finish);
43 bool notifications_blocked() const;
44 virtual void block_notifies(Context *on_finish);
45 void unblock_notifies();
47 std::string get_oid() const;
48 void set_oid(const string& oid);
50 uint64_t get_watch_handle() const {
51 RWLock::RLocker watch_locker(m_watch_lock);
52 return m_watch_handle;
55 bool is_registered() const {
56 RWLock::RLocker locker(m_watch_lock);
57 return m_watch_state == WATCH_STATE_REGISTERED;
59 bool is_unregistered() const {
60 RWLock::RLocker locker(m_watch_lock);
61 return m_watch_state == WATCH_STATE_UNREGISTERED;
66 WATCH_STATE_UNREGISTERED,
67 WATCH_STATE_REGISTERING,
68 WATCH_STATE_REGISTERED,
70 WATCH_STATE_REWATCHING
73 librados::IoCtx& m_ioctx;
74 ContextWQ *m_work_queue;
77 mutable RWLock m_watch_lock;
78 uint64_t m_watch_handle;
79 watcher::Notifier m_notifier;
80 WatchState m_watch_state;
81 AsyncOpTracker m_async_op_tracker;
83 void send_notify(bufferlist &payload,
84 watcher::NotifyResponse *response = nullptr,
85 Context *on_finish = nullptr);
87 virtual void handle_notify(uint64_t notify_id, uint64_t handle,
88 uint64_t notifier_id, bufferlist &bl) = 0;
90 virtual void handle_error(uint64_t cookie, int err);
92 void acknowledge_notify(uint64_t notify_id, uint64_t handle,
95 virtual void handle_rewatch_complete(int r) { }
111 * REGISTERED * * * * * * * > ERROR
118 * | \---------------------/
120 * | (unregister_watch)
131 struct WatchCtx : public librados::WatchCtx2 {
134 WatchCtx(Watcher &parent) : watcher(parent) {}
136 void handle_notify(uint64_t notify_id,
138 uint64_t notifier_id,
139 bufferlist& bl) override;
140 void handle_error(uint64_t handle, int err) override;
143 struct C_RegisterWatch : public Context {
147 C_RegisterWatch(Watcher *watcher, Context *on_finish)
148 : watcher(watcher), on_finish(on_finish) {
150 void finish(int r) override {
151 watcher->handle_register_watch(r, on_finish);
155 WatchCtx m_watch_ctx;
156 Context *m_unregister_watch_ctx = nullptr;
158 uint32_t m_blocked_count = 0;
160 void handle_register_watch(int r, Context *on_finish);
163 void handle_rewatch(int r);
167 } // namespace librbd
169 #endif // CEPH_LIBRBD_WATCHER_H