]>
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 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2011 New Dream Network | |
7 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License version 2.1, as published by the Free Software | |
11 | * Foundation. See file COPYING. | |
12 | * | |
13 | */ | |
14 | ||
15 | #ifndef __LIBRBD_HPP | |
16 | #define __LIBRBD_HPP | |
17 | ||
18 | #include <stdbool.h> | |
19 | #include <string> | |
20 | #include <list> | |
21 | #include <map> | |
22 | #include <vector> | |
23 | #include "../rados/buffer.h" | |
24 | #include "../rados/librados.hpp" | |
25 | #include "librbd.h" | |
26 | ||
27 | namespace librbd { | |
28 | ||
29 | using librados::IoCtx; | |
30 | ||
31 | class Image; | |
32 | class ImageOptions; | |
33 | typedef void *image_ctx_t; | |
34 | typedef void *completion_t; | |
35 | typedef void (*callback_t)(completion_t cb, void *arg); | |
36 | ||
37 | typedef struct { | |
38 | uint64_t id; | |
39 | uint64_t size; | |
40 | std::string name; | |
41 | } snap_info_t; | |
42 | ||
43 | typedef struct { | |
44 | std::string client; | |
45 | std::string cookie; | |
46 | std::string address; | |
47 | } locker_t; | |
48 | ||
49 | typedef struct { | |
50 | std::string uuid; | |
51 | std::string cluster_name; | |
52 | std::string client_name; | |
53 | } mirror_peer_t; | |
54 | ||
55 | typedef rbd_mirror_image_state_t mirror_image_state_t; | |
56 | ||
57 | typedef struct { | |
58 | std::string global_id; | |
59 | mirror_image_state_t state; | |
60 | bool primary; | |
61 | } mirror_image_info_t; | |
62 | ||
63 | typedef rbd_mirror_image_status_state_t mirror_image_status_state_t; | |
64 | ||
65 | typedef struct { | |
66 | std::string name; | |
67 | mirror_image_info_t info; | |
68 | mirror_image_status_state_t state; | |
69 | std::string description; | |
70 | time_t last_update; | |
71 | bool up; | |
72 | } mirror_image_status_t; | |
73 | ||
74 | typedef rbd_group_image_state_t group_image_state_t; | |
75 | ||
76 | typedef struct { | |
77 | std::string name; | |
78 | int64_t pool; | |
79 | group_image_state_t state; | |
80 | } group_image_status_t; | |
81 | ||
82 | typedef struct { | |
83 | std::string name; | |
84 | int64_t pool; | |
85 | } group_spec_t; | |
86 | ||
87 | typedef rbd_image_info_t image_info_t; | |
88 | ||
89 | class CEPH_RBD_API ProgressContext | |
90 | { | |
91 | public: | |
92 | virtual ~ProgressContext(); | |
93 | virtual int update_progress(uint64_t offset, uint64_t total) = 0; | |
94 | }; | |
95 | ||
96 | typedef struct { | |
97 | std::string id; | |
98 | std::string name; | |
99 | rbd_trash_image_source_t source; | |
100 | time_t deletion_time; | |
101 | time_t deferment_end_time; | |
102 | } trash_image_info_t; | |
103 | ||
104 | class CEPH_RBD_API RBD | |
105 | { | |
106 | public: | |
107 | RBD(); | |
108 | ~RBD(); | |
109 | ||
110 | // This must be dynamically allocated with new, and | |
111 | // must be released with release(). | |
112 | // Do not use delete. | |
113 | struct AioCompletion { | |
114 | void *pc; | |
115 | AioCompletion(void *cb_arg, callback_t complete_cb); | |
116 | bool is_complete(); | |
117 | int wait_for_complete(); | |
118 | ssize_t get_return_value(); | |
119 | void *get_arg(); | |
120 | void release(); | |
121 | }; | |
122 | ||
123 | void version(int *major, int *minor, int *extra); | |
124 | ||
125 | int open(IoCtx& io_ctx, Image& image, const char *name); | |
126 | int open(IoCtx& io_ctx, Image& image, const char *name, const char *snapname); | |
127 | int open_by_id(IoCtx& io_ctx, Image& image, const char *id); | |
128 | int open_by_id(IoCtx& io_ctx, Image& image, const char *id, const char *snapname); | |
129 | int aio_open(IoCtx& io_ctx, Image& image, const char *name, | |
130 | const char *snapname, RBD::AioCompletion *c); | |
131 | int aio_open_by_id(IoCtx& io_ctx, Image& image, const char *id, | |
132 | const char *snapname, RBD::AioCompletion *c); | |
133 | // see librbd.h | |
134 | int open_read_only(IoCtx& io_ctx, Image& image, const char *name, | |
135 | const char *snapname); | |
136 | int open_by_id_read_only(IoCtx& io_ctx, Image& image, const char *id, | |
137 | const char *snapname); | |
138 | int aio_open_read_only(IoCtx& io_ctx, Image& image, const char *name, | |
139 | const char *snapname, RBD::AioCompletion *c); | |
140 | int aio_open_by_id_read_only(IoCtx& io_ctx, Image& image, const char *id, | |
141 | const char *snapname, RBD::AioCompletion *c); | |
142 | int list(IoCtx& io_ctx, std::vector<std::string>& names); | |
143 | int create(IoCtx& io_ctx, const char *name, uint64_t size, int *order); | |
144 | int create2(IoCtx& io_ctx, const char *name, uint64_t size, | |
145 | uint64_t features, int *order); | |
146 | int create3(IoCtx& io_ctx, const char *name, uint64_t size, | |
147 | uint64_t features, int *order, | |
148 | uint64_t stripe_unit, uint64_t stripe_count); | |
149 | int create4(IoCtx& io_ctx, const char *name, uint64_t size, | |
150 | ImageOptions& opts); | |
151 | int clone(IoCtx& p_ioctx, const char *p_name, const char *p_snapname, | |
152 | IoCtx& c_ioctx, const char *c_name, uint64_t features, | |
153 | int *c_order); | |
154 | int clone2(IoCtx& p_ioctx, const char *p_name, const char *p_snapname, | |
155 | IoCtx& c_ioctx, const char *c_name, uint64_t features, | |
156 | int *c_order, uint64_t stripe_unit, int stripe_count); | |
157 | int clone3(IoCtx& p_ioctx, const char *p_name, const char *p_snapname, | |
158 | IoCtx& c_ioctx, const char *c_name, ImageOptions& opts); | |
159 | int remove(IoCtx& io_ctx, const char *name); | |
160 | int remove_with_progress(IoCtx& io_ctx, const char *name, ProgressContext& pctx); | |
161 | int rename(IoCtx& src_io_ctx, const char *srcname, const char *destname); | |
162 | ||
163 | int trash_move(IoCtx &io_ctx, const char *name, uint64_t delay); | |
164 | int trash_get(IoCtx &io_ctx, const char *id, trash_image_info_t *info); | |
165 | int trash_list(IoCtx &io_ctx, std::vector<trash_image_info_t> &entries); | |
166 | int trash_remove(IoCtx &io_ctx, const char *image_id, bool force); | |
167 | int trash_remove_with_progress(IoCtx &io_ctx, const char *image_id, | |
168 | bool force, ProgressContext &pctx); | |
169 | int trash_restore(IoCtx &io_ctx, const char *id, const char *name); | |
170 | ||
171 | // RBD pool mirroring support functions | |
172 | int mirror_mode_get(IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode); | |
173 | int mirror_mode_set(IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode); | |
174 | int mirror_peer_add(IoCtx& io_ctx, std::string *uuid, | |
175 | const std::string &cluster_name, | |
176 | const std::string &client_name); | |
177 | int mirror_peer_remove(IoCtx& io_ctx, const std::string &uuid); | |
178 | int mirror_peer_list(IoCtx& io_ctx, std::vector<mirror_peer_t> *peers); | |
179 | int mirror_peer_set_client(IoCtx& io_ctx, const std::string &uuid, | |
180 | const std::string &client_name); | |
181 | int mirror_peer_set_cluster(IoCtx& io_ctx, const std::string &uuid, | |
182 | const std::string &cluster_name); | |
183 | int mirror_image_status_list(IoCtx& io_ctx, const std::string &start_id, | |
184 | size_t max, std::map<std::string, mirror_image_status_t> *images); | |
185 | int mirror_image_status_summary(IoCtx& io_ctx, | |
186 | std::map<mirror_image_status_state_t, int> *states); | |
187 | ||
188 | // RBD consistency groups support functions | |
189 | int group_create(IoCtx& io_ctx, const char *group_name); | |
190 | int group_remove(IoCtx& io_ctx, const char *group_name); | |
191 | int group_list(IoCtx& io_ctx, std::vector<std::string> *names); | |
192 | ||
193 | int group_image_add(IoCtx& io_ctx, const char *group_name, | |
194 | IoCtx& image_io_ctx, const char *image_name); | |
195 | int group_image_remove(IoCtx& io_ctx, const char *group_name, | |
196 | IoCtx& image_io_ctx, const char *image_name); | |
197 | int group_image_remove_by_id(IoCtx& io_ctx, const char *group_name, | |
198 | IoCtx& image_io_ctx, const char *image_id); | |
199 | int group_image_list(IoCtx& io_ctx, const char *group_name, | |
200 | std::vector<group_image_status_t> *images); | |
201 | ||
202 | private: | |
203 | /* We don't allow assignment or copying */ | |
204 | RBD(const RBD& rhs); | |
205 | const RBD& operator=(const RBD& rhs); | |
206 | }; | |
207 | ||
208 | class CEPH_RBD_API ImageOptions { | |
209 | public: | |
210 | ImageOptions(); | |
211 | ImageOptions(rbd_image_options_t opts); | |
212 | ImageOptions(const ImageOptions &imgopts); | |
213 | ~ImageOptions(); | |
214 | ||
215 | int set(int optname, const std::string& optval); | |
216 | int set(int optname, uint64_t optval); | |
217 | int get(int optname, std::string* optval) const; | |
218 | int get(int optname, uint64_t* optval) const; | |
219 | int is_set(int optname, bool* is_set); | |
220 | int unset(int optname); | |
221 | void clear(); | |
222 | bool empty() const; | |
223 | ||
224 | private: | |
225 | friend class RBD; | |
226 | friend class Image; | |
227 | ||
228 | rbd_image_options_t opts; | |
229 | }; | |
230 | ||
231 | class CEPH_RBD_API UpdateWatchCtx { | |
232 | public: | |
233 | virtual ~UpdateWatchCtx() {} | |
234 | /** | |
235 | * Callback activated when we receive a notify event. | |
236 | */ | |
237 | virtual void handle_notify() = 0; | |
238 | }; | |
239 | ||
240 | class CEPH_RBD_API Image | |
241 | { | |
242 | public: | |
243 | Image(); | |
244 | ~Image(); | |
245 | ||
246 | int close(); | |
247 | int aio_close(RBD::AioCompletion *c); | |
248 | ||
249 | int resize(uint64_t size); | |
250 | int resize2(uint64_t size, bool allow_shrink, ProgressContext& pctx); | |
251 | int resize_with_progress(uint64_t size, ProgressContext& pctx); | |
252 | int stat(image_info_t &info, size_t infosize); | |
253 | int get_id(std::string *id); | |
254 | std::string get_block_name_prefix(); | |
255 | int64_t get_data_pool_id(); | |
256 | int parent_info(std::string *parent_poolname, std::string *parent_name, | |
257 | std::string *parent_snapname); | |
258 | int parent_info2(std::string *parent_poolname, std::string *parent_name, | |
259 | std::string *parent_id, std::string *parent_snapname); | |
260 | int old_format(uint8_t *old); | |
261 | int size(uint64_t *size); | |
262 | int get_group(group_spec_t *group_spec); | |
263 | int features(uint64_t *features); | |
264 | int update_features(uint64_t features, bool enabled); | |
265 | int overlap(uint64_t *overlap); | |
266 | int get_flags(uint64_t *flags); | |
267 | int set_image_notification(int fd, int type); | |
268 | ||
269 | /* exclusive lock feature */ | |
270 | int is_exclusive_lock_owner(bool *is_owner); | |
271 | int lock_acquire(rbd_lock_mode_t lock_mode); | |
272 | int lock_release(); | |
273 | int lock_get_owners(rbd_lock_mode_t *lock_mode, | |
274 | std::list<std::string> *lock_owners); | |
275 | int lock_break(rbd_lock_mode_t lock_mode, const std::string &lock_owner); | |
276 | ||
277 | /* object map feature */ | |
278 | int rebuild_object_map(ProgressContext &prog_ctx); | |
279 | ||
280 | int check_object_map(ProgressContext &prog_ctx); | |
281 | ||
282 | int copy(IoCtx& dest_io_ctx, const char *destname); | |
283 | int copy2(Image& dest); | |
284 | int copy3(IoCtx& dest_io_ctx, const char *destname, ImageOptions& opts); | |
285 | int copy4(IoCtx& dest_io_ctx, const char *destname, ImageOptions& opts, | |
286 | size_t sparse_size); | |
287 | int copy_with_progress(IoCtx& dest_io_ctx, const char *destname, | |
288 | ProgressContext &prog_ctx); | |
289 | int copy_with_progress2(Image& dest, ProgressContext &prog_ctx); | |
290 | int copy_with_progress3(IoCtx& dest_io_ctx, const char *destname, | |
291 | ImageOptions& opts, ProgressContext &prog_ctx); | |
292 | int copy_with_progress4(IoCtx& dest_io_ctx, const char *destname, | |
293 | ImageOptions& opts, ProgressContext &prog_ctx, | |
294 | size_t sparse_size); | |
295 | ||
296 | /* striping */ | |
297 | uint64_t get_stripe_unit() const; | |
298 | uint64_t get_stripe_count() const; | |
299 | ||
300 | int flatten(); | |
301 | int flatten_with_progress(ProgressContext &prog_ctx); | |
302 | /** | |
303 | * Returns a pair of poolname, imagename for each clone | |
304 | * of this image at the currently set snapshot. | |
305 | */ | |
306 | int list_children(std::set<std::pair<std::string, std::string> > *children); | |
307 | ||
308 | /* advisory locking (see librbd.h for details) */ | |
309 | int list_lockers(std::list<locker_t> *lockers, | |
310 | bool *exclusive, std::string *tag); | |
311 | int lock_exclusive(const std::string& cookie); | |
312 | int lock_shared(const std::string& cookie, const std::string& tag); | |
313 | int unlock(const std::string& cookie); | |
314 | int break_lock(const std::string& client, const std::string& cookie); | |
315 | ||
316 | /* snapshots */ | |
317 | int snap_list(std::vector<snap_info_t>& snaps); | |
318 | /* DEPRECATED; use snap_exists2 */ | |
319 | bool snap_exists(const char *snapname) __attribute__ ((deprecated)); | |
320 | int snap_exists2(const char *snapname, bool *exists); | |
321 | int snap_create(const char *snapname); | |
322 | int snap_remove(const char *snapname); | |
323 | int snap_remove2(const char *snapname, uint32_t flags, ProgressContext& pctx); | |
324 | int snap_rollback(const char *snap_name); | |
325 | int snap_rollback_with_progress(const char *snap_name, ProgressContext& pctx); | |
326 | int snap_protect(const char *snap_name); | |
327 | int snap_unprotect(const char *snap_name); | |
328 | int snap_is_protected(const char *snap_name, bool *is_protected); | |
329 | int snap_set(const char *snap_name); | |
330 | int snap_rename(const char *srcname, const char *dstname); | |
331 | int snap_get_limit(uint64_t *limit); | |
332 | int snap_set_limit(uint64_t limit); | |
333 | int snap_get_timestamp(uint64_t snap_id, struct timespec *timestamp); | |
334 | ||
335 | /* I/O */ | |
336 | ssize_t read(uint64_t ofs, size_t len, ceph::bufferlist& bl); | |
337 | /* @param op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */ | |
338 | ssize_t read2(uint64_t ofs, size_t len, ceph::bufferlist& bl, int op_flags); | |
339 | int64_t read_iterate(uint64_t ofs, size_t len, | |
340 | int (*cb)(uint64_t, size_t, const char *, void *), void *arg); | |
341 | int read_iterate2(uint64_t ofs, uint64_t len, | |
342 | int (*cb)(uint64_t, size_t, const char *, void *), void *arg); | |
343 | /** | |
344 | * get difference between two versions of an image | |
345 | * | |
346 | * This will return the differences between two versions of an image | |
347 | * via a callback, which gets the offset and length and a flag | |
348 | * indicating whether the extent exists (1), or is known/defined to | |
349 | * be zeros (a hole, 0). If the source snapshot name is NULL, we | |
350 | * interpret that as the beginning of time and return all allocated | |
351 | * regions of the image. The end version is whatever is currently | |
352 | * selected for the image handle (either a snapshot or the writeable | |
353 | * head). | |
354 | * | |
355 | * @param fromsnapname start snapshot name, or NULL | |
356 | * @param ofs start offset | |
357 | * @param len len in bytes of region to report on | |
358 | * @param include_parent true if full history diff should include parent | |
359 | * @param whole_object 1 if diff extents should cover whole object | |
360 | * @param cb callback to call for each allocated region | |
361 | * @param arg argument to pass to the callback | |
362 | * @returns 0 on success, or negative error code on error | |
363 | */ | |
364 | int diff_iterate(const char *fromsnapname, | |
365 | uint64_t ofs, uint64_t len, | |
366 | int (*cb)(uint64_t, size_t, int, void *), void *arg); | |
367 | int diff_iterate2(const char *fromsnapname, | |
368 | uint64_t ofs, uint64_t len, | |
369 | bool include_parent, bool whole_object, | |
370 | int (*cb)(uint64_t, size_t, int, void *), void *arg); | |
371 | ||
372 | ssize_t write(uint64_t ofs, size_t len, ceph::bufferlist& bl); | |
373 | /* @param op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */ | |
374 | ssize_t write2(uint64_t ofs, size_t len, ceph::bufferlist& bl, int op_flags); | |
375 | int discard(uint64_t ofs, uint64_t len); | |
376 | ssize_t writesame(uint64_t ofs, size_t len, ceph::bufferlist &bl, int op_flags); | |
377 | ||
378 | int aio_write(uint64_t off, size_t len, ceph::bufferlist& bl, RBD::AioCompletion *c); | |
379 | /* @param op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */ | |
380 | int aio_write2(uint64_t off, size_t len, ceph::bufferlist& bl, | |
381 | RBD::AioCompletion *c, int op_flags); | |
382 | int aio_writesame(uint64_t off, size_t len, ceph::bufferlist& bl, | |
383 | RBD::AioCompletion *c, int op_flags); | |
384 | /** | |
385 | * read async from image | |
386 | * | |
387 | * The target bufferlist is populated with references to buffers | |
388 | * that contain the data for the given extent of the image. | |
389 | * | |
390 | * NOTE: If caching is enabled, the bufferlist will directly | |
391 | * reference buffers in the cache to avoid an unnecessary data copy. | |
392 | * As a result, if the user intends to modify the buffer contents | |
393 | * directly, they should make a copy first (unconditionally, or when | |
394 | * the reference count on ther underlying buffer is more than 1). | |
395 | * | |
396 | * @param off offset in image | |
397 | * @param len length of read | |
398 | * @param bl bufferlist to read into | |
399 | * @param c aio completion to notify when read is complete | |
400 | */ | |
401 | int aio_read(uint64_t off, size_t len, ceph::bufferlist& bl, RBD::AioCompletion *c); | |
402 | /* @param op_flags see librados.h constants beginning with LIBRADOS_OP_FLAG */ | |
403 | int aio_read2(uint64_t off, size_t len, ceph::bufferlist& bl, | |
404 | RBD::AioCompletion *c, int op_flags); | |
405 | int aio_discard(uint64_t off, uint64_t len, RBD::AioCompletion *c); | |
406 | ||
407 | int flush(); | |
408 | /** | |
409 | * Start a flush if caching is enabled. Get a callback when | |
410 | * the currently pending writes are on disk. | |
411 | * | |
412 | * @param image the image to flush writes to | |
413 | * @param c what to call when flushing is complete | |
414 | * @returns 0 on success, negative error code on failure | |
415 | */ | |
416 | int aio_flush(RBD::AioCompletion *c); | |
417 | ||
418 | /** | |
419 | * Drop any cached data for this image | |
420 | * | |
421 | * @returns 0 on success, negative error code on failure | |
422 | */ | |
423 | int invalidate_cache(); | |
424 | ||
425 | int poll_io_events(RBD::AioCompletion **comps, int numcomp); | |
426 | ||
427 | int metadata_get(const std::string &key, std::string *value); | |
428 | int metadata_set(const std::string &key, const std::string &value); | |
429 | int metadata_remove(const std::string &key); | |
430 | /** | |
431 | * Returns a pair of key/value for this image | |
432 | */ | |
433 | int metadata_list(const std::string &start, uint64_t max, std::map<std::string, ceph::bufferlist> *pairs); | |
434 | ||
435 | // RBD image mirroring support functions | |
436 | int mirror_image_enable(); | |
437 | int mirror_image_disable(bool force); | |
438 | int mirror_image_promote(bool force); | |
439 | int mirror_image_demote(); | |
440 | int mirror_image_resync(); | |
441 | int mirror_image_get_info(mirror_image_info_t *mirror_image_info, | |
442 | size_t info_size); | |
443 | int mirror_image_get_status(mirror_image_status_t *mirror_image_status, | |
444 | size_t status_size); | |
445 | int aio_mirror_image_promote(bool force, RBD::AioCompletion *c); | |
446 | int aio_mirror_image_demote(RBD::AioCompletion *c); | |
447 | int aio_mirror_image_get_info(mirror_image_info_t *mirror_image_info, | |
448 | size_t info_size, RBD::AioCompletion *c); | |
449 | int aio_mirror_image_get_status(mirror_image_status_t *mirror_image_status, | |
450 | size_t status_size, RBD::AioCompletion *c); | |
451 | ||
452 | int update_watch(UpdateWatchCtx *ctx, uint64_t *handle); | |
453 | int update_unwatch(uint64_t handle); | |
454 | ||
455 | private: | |
456 | friend class RBD; | |
457 | ||
458 | Image(const Image& rhs); | |
459 | const Image& operator=(const Image& rhs); | |
460 | ||
461 | image_ctx_t ctx; | |
462 | }; | |
463 | ||
464 | } | |
465 | ||
466 | #endif |