]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/ImageWatcher.h
import 15.2.0 Octopus source
[ceph.git] / ceph / src / librbd / ImageWatcher.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_IMAGE_WATCHER_H
5#define CEPH_LIBRBD_IMAGE_WATCHER_H
6
7#include "cls/rbd/cls_rbd_types.h"
9f95a23c 8#include "common/ceph_mutex.h"
7c673cae
FG
9#include "include/Context.h"
10#include "include/rbd/librbd.hpp"
11#include "librbd/Watcher.h"
12#include "librbd/WatchNotifyTypes.h"
13#include <set>
14#include <string>
15#include <utility>
16
17class entity_name_t;
18
19namespace librbd {
20
21namespace watcher {
22namespace util {
23template <typename> struct HandlePayloadVisitor;
24}
25}
26
27class ImageCtx;
28template <typename> class TaskFinisher;
29
30template <typename ImageCtxT = ImageCtx>
31class ImageWatcher : public Watcher {
32 friend struct watcher::util::HandlePayloadVisitor<ImageWatcher<ImageCtxT>>;
33
34public:
35 ImageWatcher(ImageCtxT& image_ctx);
36 ~ImageWatcher() override;
37
31f18b77
FG
38 void unregister_watch(Context *on_finish) override;
39 void block_notifies(Context *on_finish) override;
7c673cae
FG
40
41 void notify_flatten(uint64_t request_id, ProgressContext &prog_ctx,
42 Context *on_finish);
43 void notify_resize(uint64_t request_id, uint64_t size, bool allow_shrink,
44 ProgressContext &prog_ctx, Context *on_finish);
45 void notify_snap_create(const cls::rbd::SnapshotNamespace &snap_namespace,
46 const std::string &snap_name,
47 Context *on_finish);
48 void notify_snap_rename(const snapid_t &src_snap_id,
49 const std::string &dst_snap_name,
50 Context *on_finish);
51 void notify_snap_remove(const cls::rbd::SnapshotNamespace &snap_namespace,
52 const std::string &snap_name,
53 Context *on_finish);
54 void notify_snap_protect(const cls::rbd::SnapshotNamespace &snap_namespace,
55 const std::string &snap_name,
56 Context *on_finish);
57 void notify_snap_unprotect(const cls::rbd::SnapshotNamespace &snap_namespace,
58 const std::string &snap_name,
59 Context *on_finish);
60 void notify_rebuild_object_map(uint64_t request_id,
61 ProgressContext &prog_ctx, Context *on_finish);
62 void notify_rename(const std::string &image_name, Context *on_finish);
63
64 void notify_update_features(uint64_t features, bool enabled,
65 Context *on_finish);
66
11fdf7f2
TL
67 void notify_migrate(uint64_t request_id, ProgressContext &prog_ctx,
68 Context *on_finish);
69
70 void notify_sparsify(uint64_t request_id, size_t sparse_size,
71 ProgressContext &prog_ctx, Context *on_finish);
72
7c673cae
FG
73 void notify_acquired_lock();
74 void notify_released_lock();
75 void notify_request_lock();
76
77 void notify_header_update(Context *on_finish);
78 static void notify_header_update(librados::IoCtx &io_ctx,
79 const std::string &oid);
80
81private:
82 enum TaskCode {
83 TASK_CODE_REQUEST_LOCK,
84 TASK_CODE_CANCEL_ASYNC_REQUESTS,
85 TASK_CODE_REREGISTER_WATCH,
86 TASK_CODE_ASYNC_REQUEST,
87 TASK_CODE_ASYNC_PROGRESS
88 };
89
90 typedef std::pair<Context *, ProgressContext *> AsyncRequest;
91
92 class Task {
93 public:
94 Task(TaskCode task_code) : m_task_code(task_code) {}
95 Task(TaskCode task_code, const watch_notify::AsyncRequestId &id)
96 : m_task_code(task_code), m_async_request_id(id) {}
97
98 inline bool operator<(const Task& rhs) const {
99 if (m_task_code != rhs.m_task_code) {
100 return m_task_code < rhs.m_task_code;
101 } else if ((m_task_code == TASK_CODE_ASYNC_REQUEST ||
102 m_task_code == TASK_CODE_ASYNC_PROGRESS) &&
103 m_async_request_id != rhs.m_async_request_id) {
104 return m_async_request_id < rhs.m_async_request_id;
105 }
106 return false;
107 }
108 private:
109 TaskCode m_task_code;
110 watch_notify::AsyncRequestId m_async_request_id;
111 };
112
113 class RemoteProgressContext : public ProgressContext {
114 public:
115 RemoteProgressContext(ImageWatcher &image_watcher,
116 const watch_notify::AsyncRequestId &id)
117 : m_image_watcher(image_watcher), m_async_request_id(id)
118 {
119 }
120
121 int update_progress(uint64_t offset, uint64_t total) override {
122 m_image_watcher.schedule_async_progress(m_async_request_id, offset,
123 total);
124 return 0;
125 }
126
127 private:
128 ImageWatcher &m_image_watcher;
129 watch_notify::AsyncRequestId m_async_request_id;
130 };
131
132 class RemoteContext : public Context {
133 public:
134 RemoteContext(ImageWatcher &image_watcher,
135 const watch_notify::AsyncRequestId &id,
136 ProgressContext *prog_ctx)
137 : m_image_watcher(image_watcher), m_async_request_id(id),
138 m_prog_ctx(prog_ctx)
139 {
140 }
141
142 ~RemoteContext() override {
143 delete m_prog_ctx;
144 }
145
146 void finish(int r) override;
147
148 private:
149 ImageWatcher &m_image_watcher;
150 watch_notify::AsyncRequestId m_async_request_id;
151 ProgressContext *m_prog_ctx;
152 };
153
31f18b77 154 struct C_ProcessPayload;
7c673cae
FG
155 struct C_ResponseMessage : public Context {
156 C_NotifyAck *notify_ack;
157
158 C_ResponseMessage(C_NotifyAck *notify_ack) : notify_ack(notify_ack) {
159 }
160 void finish(int r) override;
161 };
162
163 ImageCtxT &m_image_ctx;
164
165 TaskFinisher<Task> *m_task_finisher;
166
9f95a23c 167 ceph::shared_mutex m_async_request_lock;
7c673cae
FG
168 std::map<watch_notify::AsyncRequestId, AsyncRequest> m_async_requests;
169 std::set<watch_notify::AsyncRequestId> m_async_pending;
170
9f95a23c 171 ceph::mutex m_owner_client_id_lock;
7c673cae
FG
172 watch_notify::ClientId m_owner_client_id;
173
174 void handle_register_watch(int r);
175
176 void schedule_cancel_async_requests();
177 void cancel_async_requests();
178
179 void set_owner_client_id(const watch_notify::ClientId &client_id);
180 watch_notify::ClientId get_client_id();
181
182 void handle_request_lock(int r);
183 void schedule_request_lock(bool use_timer, int timer_delay = -1);
184
185 void notify_lock_owner(const watch_notify::Payload& payload,
186 Context *on_finish);
187
188 Context *remove_async_request(const watch_notify::AsyncRequestId &id);
189 void schedule_async_request_timed_out(const watch_notify::AsyncRequestId &id);
190 void async_request_timed_out(const watch_notify::AsyncRequestId &id);
191 void notify_async_request(const watch_notify::AsyncRequestId &id,
192 const watch_notify::Payload &payload,
193 ProgressContext& prog_ctx,
194 Context *on_finish);
195
196 void schedule_async_progress(const watch_notify::AsyncRequestId &id,
197 uint64_t offset, uint64_t total);
198 int notify_async_progress(const watch_notify::AsyncRequestId &id,
199 uint64_t offset, uint64_t total);
200 void schedule_async_complete(const watch_notify::AsyncRequestId &id, int r);
201 void notify_async_complete(const watch_notify::AsyncRequestId &id, int r);
202 void handle_async_complete(const watch_notify::AsyncRequestId &request, int r,
203 int ret_val);
204
205 int prepare_async_request(const watch_notify::AsyncRequestId& id,
206 bool* new_request, Context** ctx,
207 ProgressContext** prog_ctx);
208
209 bool handle_payload(const watch_notify::HeaderUpdatePayload& payload,
210 C_NotifyAck *ctx);
211 bool handle_payload(const watch_notify::AcquiredLockPayload& payload,
212 C_NotifyAck *ctx);
213 bool handle_payload(const watch_notify::ReleasedLockPayload& payload,
214 C_NotifyAck *ctx);
215 bool handle_payload(const watch_notify::RequestLockPayload& payload,
216 C_NotifyAck *ctx);
217 bool handle_payload(const watch_notify::AsyncProgressPayload& payload,
218 C_NotifyAck *ctx);
219 bool handle_payload(const watch_notify::AsyncCompletePayload& payload,
220 C_NotifyAck *ctx);
221 bool handle_payload(const watch_notify::FlattenPayload& payload,
222 C_NotifyAck *ctx);
223 bool handle_payload(const watch_notify::ResizePayload& payload,
224 C_NotifyAck *ctx);
225 bool handle_payload(const watch_notify::SnapCreatePayload& payload,
226 C_NotifyAck *ctx);
227 bool handle_payload(const watch_notify::SnapRenamePayload& payload,
228 C_NotifyAck *ctx);
229 bool handle_payload(const watch_notify::SnapRemovePayload& payload,
230 C_NotifyAck *ctx);
231 bool handle_payload(const watch_notify::SnapProtectPayload& payload,
232 C_NotifyAck *ctx);
233 bool handle_payload(const watch_notify::SnapUnprotectPayload& payload,
234 C_NotifyAck *ctx);
235 bool handle_payload(const watch_notify::RebuildObjectMapPayload& payload,
236 C_NotifyAck *ctx);
237 bool handle_payload(const watch_notify::RenamePayload& payload,
238 C_NotifyAck *ctx);
239 bool handle_payload(const watch_notify::UpdateFeaturesPayload& payload,
240 C_NotifyAck *ctx);
11fdf7f2
TL
241 bool handle_payload(const watch_notify::MigratePayload& payload,
242 C_NotifyAck *ctx);
243 bool handle_payload(const watch_notify::SparsifyPayload& payload,
244 C_NotifyAck *ctx);
7c673cae
FG
245 bool handle_payload(const watch_notify::UnknownPayload& payload,
246 C_NotifyAck *ctx);
247 void process_payload(uint64_t notify_id, uint64_t handle,
31f18b77 248 const watch_notify::Payload &payload);
7c673cae
FG
249
250 void handle_notify(uint64_t notify_id, uint64_t handle,
251 uint64_t notifier_id, bufferlist &bl) override;
252 void handle_error(uint64_t cookie, int err) override;
253 void handle_rewatch_complete(int r) override;
254
255 void send_notify(const watch_notify::Payload& payload,
256 Context *ctx = nullptr);
257
258};
259
260} // namespace librbd
261
262extern template class librbd::ImageWatcher<librbd::ImageCtx>;
263
264#endif // CEPH_LIBRBD_IMAGE_WATCHER_H