]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | #ifndef CEPH_LIBRBD_IMAGECTX_H | |
4 | #define CEPH_LIBRBD_IMAGECTX_H | |
5 | ||
6 | #include "include/int_types.h" | |
7 | ||
9f95a23c | 8 | #include <atomic> |
7c673cae FG |
9 | #include <list> |
10 | #include <map> | |
f67539c2 | 11 | #include <memory> |
11fdf7f2 | 12 | #include <set> |
7c673cae FG |
13 | #include <string> |
14 | #include <vector> | |
15 | ||
a4b75251 | 16 | #include "common/Timer.h" |
9f95a23c | 17 | #include "common/ceph_mutex.h" |
11fdf7f2 | 18 | #include "common/config_proxy.h" |
7c673cae | 19 | #include "common/event_socket.h" |
7c673cae | 20 | #include "common/Readahead.h" |
7c673cae | 21 | #include "common/snap_types.h" |
31f18b77 | 22 | #include "common/zipkin_trace.h" |
7c673cae | 23 | |
9f95a23c | 24 | #include "include/common_fwd.h" |
7c673cae FG |
25 | #include "include/buffer_fwd.h" |
26 | #include "include/rbd/librbd.hpp" | |
27 | #include "include/rbd_types.h" | |
28 | #include "include/types.h" | |
29 | #include "include/xlist.h" | |
7c673cae FG |
30 | |
31 | #include "cls/rbd/cls_rbd_types.h" | |
32 | #include "cls/rbd/cls_rbd_client.h" | |
33 | #include "librbd/AsyncRequest.h" | |
34 | #include "librbd/Types.h" | |
35 | ||
9f95a23c TL |
36 | #include <boost/lockfree/policies.hpp> |
37 | #include <boost/lockfree/queue.hpp> | |
38 | ||
f67539c2 TL |
39 | namespace neorados { |
40 | class IOContext; | |
41 | class RADOS; | |
42 | } // namespace neorados | |
43 | ||
7c673cae FG |
44 | namespace librbd { |
45 | ||
f67539c2 | 46 | struct AsioEngine; |
f6b5b4d7 | 47 | template <typename> class ConfigWatcher; |
7c673cae FG |
48 | template <typename> class ExclusiveLock; |
49 | template <typename> class ImageState; | |
50 | template <typename> class ImageWatcher; | |
51 | template <typename> class Journal; | |
52 | class LibrbdAdminSocketHook; | |
53 | template <typename> class ObjectMap; | |
54 | template <typename> class Operations; | |
f67539c2 | 55 | template <typename> class PluginRegistry; |
7c673cae | 56 | |
f67539c2 TL |
57 | namespace asio { struct ContextWQ; } |
58 | namespace crypto { class CryptoInterface; } | |
7c673cae FG |
59 | namespace exclusive_lock { struct Policy; } |
60 | namespace io { | |
61 | class AioCompletion; | |
31f18b77 | 62 | class AsyncOperation; |
b32b8144 | 63 | template <typename> class CopyupRequest; |
f67539c2 TL |
64 | struct ImageDispatcherInterface; |
65 | struct ObjectDispatcherInterface; | |
7c673cae FG |
66 | } |
67 | namespace journal { struct Policy; } | |
68 | ||
69 | namespace operation { | |
70 | template <typename> class ResizeRequest; | |
71 | } | |
72 | ||
73 | struct ImageCtx { | |
9f95a23c TL |
74 | typedef std::pair<cls::rbd::SnapshotNamespace, std::string> SnapKey; |
75 | struct SnapKeyComparator { | |
76 | inline bool operator()(const SnapKey& lhs, const SnapKey& rhs) const { | |
77 | // only compare by namespace type and name | |
78 | if (lhs.first.which() != rhs.first.which()) { | |
79 | return lhs.first.which() < rhs.first.which(); | |
80 | } | |
81 | return lhs.second < rhs.second; | |
82 | } | |
83 | }; | |
84 | ||
20effc67 | 85 | static const std::string METADATA_CONF_PREFIX; |
11fdf7f2 | 86 | |
7c673cae | 87 | CephContext *cct; |
11fdf7f2 TL |
88 | ConfigProxy config; |
89 | std::set<std::string> config_overrides; | |
90 | ||
7c673cae FG |
91 | PerfCounters *perfcounter; |
92 | struct rbd_obj_header_ondisk header; | |
93 | ::SnapContext snapc; | |
94 | std::vector<librados::snap_t> snaps; // this mirrors snapc.snaps, but is in | |
95 | // a format librados can understand | |
96 | std::map<librados::snap_t, SnapInfo> snap_info; | |
9f95a23c | 97 | std::map<SnapKey, librados::snap_t, SnapKeyComparator> snap_ids; |
11fdf7f2 | 98 | uint64_t open_snap_id = CEPH_NOSNAP; |
7c673cae FG |
99 | uint64_t snap_id; |
100 | bool snap_exists; // false if our snap_id was deleted | |
101 | // whether the image was opened read-only. cannot be changed after opening | |
102 | bool read_only; | |
9f95a23c TL |
103 | uint32_t read_only_flags = 0U; |
104 | uint32_t read_only_mask = ~0U; | |
7c673cae FG |
105 | |
106 | std::map<rados::cls::lock::locker_id_t, | |
107 | rados::cls::lock::locker_info_t> lockers; | |
108 | bool exclusive_locked; | |
109 | std::string lock_tag; | |
110 | ||
111 | std::string name; | |
112 | cls::rbd::SnapshotNamespace snap_namespace; | |
113 | std::string snap_name; | |
f67539c2 TL |
114 | |
115 | std::shared_ptr<AsioEngine> asio_engine; | |
116 | ||
117 | // New ASIO-style RADOS API | |
118 | neorados::RADOS& rados_api; | |
119 | ||
120 | // Legacy RADOS API | |
121 | librados::IoCtx data_ctx; | |
122 | librados::IoCtx md_ctx; | |
f6b5b4d7 TL |
123 | |
124 | ConfigWatcher<ImageCtx> *config_watcher = nullptr; | |
7c673cae FG |
125 | ImageWatcher<ImageCtx> *image_watcher; |
126 | Journal<ImageCtx> *journal; | |
127 | ||
128 | /** | |
129 | * Lock ordering: | |
130 | * | |
9f95a23c TL |
131 | * owner_lock, image_lock |
132 | * async_op_lock, timestamp_lock | |
7c673cae | 133 | */ |
9f95a23c TL |
134 | ceph::shared_mutex owner_lock; // protects exclusive lock leadership updates |
135 | mutable ceph::shared_mutex image_lock; // protects snapshot-related member variables, | |
136 | // features (and associated helper classes), and flags | |
137 | // protects access to the mutable image metadata that | |
138 | // isn't guarded by other locks below, and blocks writes | |
139 | // when held exclusively, so snapshots can be consistent. | |
140 | // Fields guarded include: | |
141 | // total_bytes_read | |
142 | // exclusive_locked | |
143 | // lock_tag | |
144 | // lockers | |
145 | // object_map | |
146 | // parent_md and parent | |
147 | ||
148 | ceph::shared_mutex timestamp_lock; // protects (create/access/modify)_timestamp | |
149 | ceph::mutex async_ops_lock; // protects async_ops and async_requests | |
150 | ceph::mutex copyup_list_lock; // protects copyup_waiting_list | |
7c673cae | 151 | |
e306af50 | 152 | unsigned extra_read_flags; // librados::OPERATION_* |
7c673cae FG |
153 | |
154 | bool old_format; | |
155 | uint8_t order; | |
156 | uint64_t size; | |
157 | uint64_t features; | |
158 | std::string object_prefix; | |
159 | char *format_string; | |
160 | std::string header_oid; | |
161 | std::string id; // only used for new-format images | |
11fdf7f2 | 162 | ParentImageInfo parent_md; |
7c673cae | 163 | ImageCtx *parent; |
b32b8144 | 164 | ImageCtx *child = nullptr; |
11fdf7f2 | 165 | MigrationInfo migration_info; |
7c673cae FG |
166 | cls::rbd::GroupSpec group_spec; |
167 | uint64_t stripe_unit, stripe_count; | |
168 | uint64_t flags; | |
11fdf7f2 TL |
169 | uint64_t op_features = 0; |
170 | bool operations_disabled = false; | |
31f18b77 | 171 | utime_t create_timestamp; |
11fdf7f2 TL |
172 | utime_t access_timestamp; |
173 | utime_t modify_timestamp; | |
7c673cae FG |
174 | |
175 | file_layout_t layout; | |
176 | ||
7c673cae | 177 | Readahead readahead; |
9f95a23c | 178 | std::atomic<uint64_t> total_bytes_read = {0}; |
7c673cae | 179 | |
b32b8144 | 180 | std::map<uint64_t, io::CopyupRequest<ImageCtx>*> copyup_list; |
7c673cae | 181 | |
31f18b77 | 182 | xlist<io::AsyncOperation*> async_ops; |
7c673cae FG |
183 | xlist<AsyncRequest<>*> async_requests; |
184 | std::list<Context*> async_requests_waiters; | |
185 | ||
186 | ImageState<ImageCtx> *state; | |
187 | Operations<ImageCtx> *operations; | |
188 | ||
189 | ExclusiveLock<ImageCtx> *exclusive_lock; | |
190 | ObjectMap<ImageCtx> *object_map; | |
191 | ||
192 | xlist<operation::ResizeRequest<ImageCtx>*> resize_reqs; | |
193 | ||
f67539c2 TL |
194 | io::ImageDispatcherInterface *io_image_dispatcher = nullptr; |
195 | io::ObjectDispatcherInterface *io_object_dispatcher = nullptr; | |
11fdf7f2 | 196 | |
f67539c2 TL |
197 | asio::ContextWQ *op_work_queue; |
198 | ||
199 | PluginRegistry<ImageCtx>* plugin_registry; | |
7c673cae | 200 | |
20effc67 | 201 | using Completions = boost::lockfree::queue<io::AioCompletion*>; |
9f95a23c | 202 | |
9f95a23c TL |
203 | Completions event_socket_completions; |
204 | EventSocket event_socket; | |
205 | ||
11fdf7f2 | 206 | bool ignore_migrating = false; |
9f95a23c TL |
207 | bool disable_zero_copy = false; |
208 | bool enable_sparse_copyup = false; | |
11fdf7f2 TL |
209 | |
210 | /// Cached latency-sensitive configuration settings | |
7c673cae FG |
211 | bool non_blocking_aio; |
212 | bool cache; | |
b32b8144 | 213 | uint64_t sparse_read_threshold_bytes; |
f67539c2 TL |
214 | uint64_t readahead_max_bytes = 0; |
215 | uint64_t readahead_disable_after_bytes = 0; | |
7c673cae | 216 | bool clone_copy_on_read; |
7c673cae | 217 | bool enable_alloc_hint; |
92f5a8d4 | 218 | uint32_t alloc_hint_flags = 0U; |
e306af50 | 219 | uint32_t read_flags = 0U; // librados::OPERATION_* |
11fdf7f2 | 220 | uint32_t discard_granularity_bytes = 0; |
181888fb | 221 | bool blkin_trace_all; |
11fdf7f2 TL |
222 | uint64_t mirroring_replay_delay; |
223 | uint64_t mtime_update_interval; | |
224 | uint64_t atime_update_interval; | |
7c673cae FG |
225 | |
226 | LibrbdAdminSocketHook *asok_hook; | |
227 | ||
228 | exclusive_lock::Policy *exclusive_lock_policy = nullptr; | |
229 | journal::Policy *journal_policy = nullptr; | |
230 | ||
31f18b77 FG |
231 | ZTracer::Endpoint trace_endpoint; |
232 | ||
f67539c2 TL |
233 | crypto::CryptoInterface* crypto = nullptr; |
234 | ||
7c673cae FG |
235 | // unit test mock helpers |
236 | static ImageCtx* create(const std::string &image_name, | |
237 | const std::string &image_id, | |
238 | const char *snap, IoCtx& p, bool read_only) { | |
239 | return new ImageCtx(image_name, image_id, snap, p, read_only); | |
240 | } | |
11fdf7f2 TL |
241 | static ImageCtx* create(const std::string &image_name, |
242 | const std::string &image_id, | |
243 | librados::snap_t snap_id, IoCtx& p, | |
244 | bool read_only) { | |
245 | return new ImageCtx(image_name, image_id, snap_id, p, read_only); | |
246 | } | |
7c673cae FG |
247 | |
248 | /** | |
249 | * Either image_name or image_id must be set. | |
250 | * If id is not known, pass the empty std::string, | |
251 | * and init() will look it up. | |
252 | */ | |
253 | ImageCtx(const std::string &image_name, const std::string &image_id, | |
254 | const char *snap, IoCtx& p, bool read_only); | |
11fdf7f2 TL |
255 | ImageCtx(const std::string &image_name, const std::string &image_id, |
256 | librados::snap_t snap_id, IoCtx& p, bool read_only); | |
7c673cae FG |
257 | ~ImageCtx(); |
258 | void init(); | |
259 | void shutdown(); | |
eafe8130 | 260 | void init_layout(int64_t pool_id); |
7c673cae FG |
261 | void perf_start(std::string name); |
262 | void perf_stop(); | |
263 | void set_read_flag(unsigned flag); | |
264 | int get_read_flags(librados::snap_t snap_id); | |
11fdf7f2 | 265 | int snap_set(uint64_t snap_id); |
7c673cae | 266 | void snap_unset(); |
11fdf7f2 TL |
267 | librados::snap_t get_snap_id(const cls::rbd::SnapshotNamespace& in_snap_namespace, |
268 | const std::string& in_snap_name) const; | |
7c673cae FG |
269 | const SnapInfo* get_snap_info(librados::snap_t in_snap_id) const; |
270 | int get_snap_name(librados::snap_t in_snap_id, | |
271 | std::string *out_snap_name) const; | |
272 | int get_snap_namespace(librados::snap_t in_snap_id, | |
273 | cls::rbd::SnapshotNamespace *out_snap_namespace) const; | |
274 | int get_parent_spec(librados::snap_t in_snap_id, | |
11fdf7f2 | 275 | cls::rbd::ParentImageSpec *pspec) const; |
7c673cae FG |
276 | int is_snap_protected(librados::snap_t in_snap_id, |
277 | bool *is_protected) const; | |
278 | int is_snap_unprotected(librados::snap_t in_snap_id, | |
279 | bool *is_unprotected) const; | |
280 | ||
281 | uint64_t get_current_size() const; | |
282 | uint64_t get_object_size() const; | |
20effc67 | 283 | std::string get_object_name(uint64_t num) const; |
7c673cae FG |
284 | uint64_t get_stripe_unit() const; |
285 | uint64_t get_stripe_count() const; | |
286 | uint64_t get_stripe_period() const; | |
31f18b77 | 287 | utime_t get_create_timestamp() const; |
11fdf7f2 TL |
288 | utime_t get_access_timestamp() const; |
289 | utime_t get_modify_timestamp() const; | |
290 | ||
291 | void set_access_timestamp(utime_t at); | |
292 | void set_modify_timestamp(utime_t at); | |
7c673cae FG |
293 | |
294 | void add_snap(cls::rbd::SnapshotNamespace in_snap_namespace, | |
295 | std::string in_snap_name, | |
296 | librados::snap_t id, | |
11fdf7f2 | 297 | uint64_t in_size, const ParentImageInfo &parent, |
7c673cae FG |
298 | uint8_t protection_status, uint64_t flags, utime_t timestamp); |
299 | void rm_snap(cls::rbd::SnapshotNamespace in_snap_namespace, | |
300 | std::string in_snap_name, | |
301 | librados::snap_t id); | |
302 | uint64_t get_image_size(librados::snap_t in_snap_id) const; | |
f67539c2 | 303 | uint64_t get_effective_image_size(librados::snap_t in_snap_id) const; |
7c673cae FG |
304 | uint64_t get_object_count(librados::snap_t in_snap_id) const; |
305 | bool test_features(uint64_t test_features) const; | |
306 | bool test_features(uint64_t test_features, | |
9f95a23c | 307 | const ceph::shared_mutex &in_image_lock) const; |
11fdf7f2 TL |
308 | bool test_op_features(uint64_t op_features) const; |
309 | bool test_op_features(uint64_t op_features, | |
9f95a23c | 310 | const ceph::shared_mutex &in_image_lock) const; |
7c673cae | 311 | int get_flags(librados::snap_t in_snap_id, uint64_t *flags) const; |
91327a77 AA |
312 | int test_flags(librados::snap_t in_snap_id, |
313 | uint64_t test_flags, bool *flags_set) const; | |
314 | int test_flags(librados::snap_t in_snap_id, | |
9f95a23c | 315 | uint64_t test_flags, const ceph::shared_mutex &in_image_lock, |
31f18b77 | 316 | bool *flags_set) const; |
7c673cae FG |
317 | int update_flags(librados::snap_t in_snap_id, uint64_t flag, bool enabled); |
318 | ||
11fdf7f2 | 319 | const ParentImageInfo* get_parent_info(librados::snap_t in_snap_id) const; |
7c673cae FG |
320 | int64_t get_parent_pool_id(librados::snap_t in_snap_id) const; |
321 | std::string get_parent_image_id(librados::snap_t in_snap_id) const; | |
322 | uint64_t get_parent_snap_id(librados::snap_t in_snap_id) const; | |
323 | int get_parent_overlap(librados::snap_t in_snap_id, | |
324 | uint64_t *overlap) const; | |
7c673cae | 325 | void register_watch(Context *on_finish); |
20effc67 | 326 | uint64_t prune_parent_extents(std::vector<std::pair<uint64_t,uint64_t> >& objectx, |
7c673cae FG |
327 | uint64_t overlap); |
328 | ||
7c673cae FG |
329 | void cancel_async_requests(); |
330 | void cancel_async_requests(Context *on_finish); | |
331 | ||
b32b8144 FG |
332 | void apply_metadata(const std::map<std::string, bufferlist> &meta, |
333 | bool thread_safe); | |
7c673cae FG |
334 | |
335 | ExclusiveLock<ImageCtx> *create_exclusive_lock(); | |
336 | ObjectMap<ImageCtx> *create_object_map(uint64_t snap_id); | |
337 | Journal<ImageCtx> *create_journal(); | |
338 | ||
7c673cae FG |
339 | void set_image_name(const std::string &name); |
340 | ||
341 | void notify_update(); | |
342 | void notify_update(Context *on_finish); | |
343 | ||
344 | exclusive_lock::Policy *get_exclusive_lock_policy() const; | |
345 | void set_exclusive_lock_policy(exclusive_lock::Policy *policy); | |
346 | ||
347 | journal::Policy *get_journal_policy() const; | |
348 | void set_journal_policy(journal::Policy *policy); | |
349 | ||
f67539c2 TL |
350 | void rebuild_data_io_context(); |
351 | IOContext get_data_io_context() const; | |
352 | IOContext duplicate_data_io_context() const; | |
353 | ||
7c673cae | 354 | static void get_timer_instance(CephContext *cct, SafeTimer **timer, |
9f95a23c | 355 | ceph::mutex **timer_lock); |
f67539c2 TL |
356 | |
357 | private: | |
358 | std::shared_ptr<neorados::IOContext> data_io_context; | |
7c673cae FG |
359 | }; |
360 | } | |
361 | ||
362 | #endif |