]>
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 | #ifndef CEPH_RBD_UTILS_H | |
5 | #define CEPH_RBD_UTILS_H | |
6 | ||
1e59de90 | 7 | #include "include/compat.h" |
7c673cae FG |
8 | #include "include/int_types.h" |
9 | #include "include/rados/librados.hpp" | |
10 | #include "include/rbd/librbd.hpp" | |
11 | #include "tools/rbd/ArgumentTypes.h" | |
9f95a23c | 12 | #include <map> |
7c673cae FG |
13 | #include <string> |
14 | #include <boost/program_options.hpp> | |
15 | ||
16 | namespace rbd { | |
17 | namespace utils { | |
18 | ||
19 | namespace detail { | |
20 | ||
21 | template <typename T, void(T::*MF)(int)> | |
22 | void aio_completion_callback(librbd::completion_t completion, | |
23 | void *arg) { | |
24 | librbd::RBD::AioCompletion *aio_completion = | |
25 | reinterpret_cast<librbd::RBD::AioCompletion*>(completion); | |
26 | ||
27 | // complete the AIO callback in separate thread context | |
28 | T *t = reinterpret_cast<T *>(arg); | |
29 | int r = aio_completion->get_return_value(); | |
30 | aio_completion->release(); | |
31 | ||
32 | (t->*MF)(r); | |
33 | } | |
34 | ||
35 | } // namespace detail | |
36 | ||
37 | static const std::string RBD_DIFF_BANNER ("rbd diff v1\n"); | |
38 | static const size_t RBD_DEFAULT_SPARSE_SIZE = 4096; | |
39 | ||
40 | static const std::string RBD_IMAGE_BANNER_V2 ("rbd image v2\n"); | |
41 | static const std::string RBD_IMAGE_DIFFS_BANNER_V2 ("rbd image diffs v2\n"); | |
42 | static const std::string RBD_DIFF_BANNER_V2 ("rbd diff v2\n"); | |
43 | ||
44 | #define RBD_DIFF_FROM_SNAP 'f' | |
45 | #define RBD_DIFF_TO_SNAP 't' | |
46 | #define RBD_DIFF_IMAGE_SIZE 's' | |
47 | #define RBD_DIFF_WRITE 'w' | |
48 | #define RBD_DIFF_ZERO 'z' | |
49 | #define RBD_DIFF_END 'e' | |
50 | ||
28e407b8 AA |
51 | #define RBD_SNAP_PROTECTION_STATUS 'p' |
52 | ||
7c673cae FG |
53 | #define RBD_EXPORT_IMAGE_ORDER 'O' |
54 | #define RBD_EXPORT_IMAGE_FEATURES 'T' | |
55 | #define RBD_EXPORT_IMAGE_STRIPE_UNIT 'U' | |
56 | #define RBD_EXPORT_IMAGE_STRIPE_COUNT 'C' | |
28e407b8 | 57 | #define RBD_EXPORT_IMAGE_META 'M' |
7c673cae FG |
58 | #define RBD_EXPORT_IMAGE_END 'E' |
59 | ||
60 | enum SnapshotPresence { | |
61 | SNAPSHOT_PRESENCE_NONE, | |
62 | SNAPSHOT_PRESENCE_PERMITTED, | |
63 | SNAPSHOT_PRESENCE_REQUIRED | |
64 | }; | |
65 | ||
66 | enum SpecValidation { | |
67 | SPEC_VALIDATION_FULL, | |
68 | SPEC_VALIDATION_SNAP, | |
69 | SPEC_VALIDATION_NONE | |
70 | }; | |
71 | ||
72 | struct ProgressContext : public librbd::ProgressContext { | |
73 | const char *operation; | |
74 | bool progress; | |
75 | int last_pc; | |
76 | ||
77 | ProgressContext(const char *o, bool no_progress) | |
78 | : operation(o), progress(!no_progress), last_pc(0) { | |
79 | } | |
80 | ||
81 | int update_progress(uint64_t offset, uint64_t total) override; | |
82 | void finish(); | |
83 | void fail(); | |
84 | }; | |
85 | ||
33c7a0ef TL |
86 | int get_percentage(uint64_t part, uint64_t whole); |
87 | ||
1e59de90 TL |
88 | struct EncryptionOptions { |
89 | std::vector<librbd::encryption_spec_t> specs; | |
90 | ||
91 | ~EncryptionOptions() { | |
92 | for (auto& spec : specs) { | |
93 | switch (spec.format) { | |
94 | case RBD_ENCRYPTION_FORMAT_LUKS: { | |
95 | auto opts = | |
96 | static_cast<librbd::encryption_luks_format_options_t*>(spec.opts); | |
97 | ceph_memzero_s(opts->passphrase.data(), opts->passphrase.size(), | |
98 | opts->passphrase.size()); | |
99 | delete opts; | |
100 | break; | |
101 | } | |
102 | case RBD_ENCRYPTION_FORMAT_LUKS1: { | |
103 | auto opts = | |
104 | static_cast<librbd::encryption_luks1_format_options_t*>(spec.opts); | |
105 | ceph_memzero_s(opts->passphrase.data(), opts->passphrase.size(), | |
106 | opts->passphrase.size()); | |
107 | delete opts; | |
108 | break; | |
109 | } | |
110 | case RBD_ENCRYPTION_FORMAT_LUKS2: { | |
111 | auto opts = | |
112 | static_cast<librbd::encryption_luks2_format_options_t*>(spec.opts); | |
113 | ceph_memzero_s(opts->passphrase.data(), opts->passphrase.size(), | |
114 | opts->passphrase.size()); | |
115 | delete opts; | |
116 | break; | |
117 | } | |
118 | default: | |
119 | ceph_abort(); | |
120 | } | |
121 | } | |
122 | } | |
123 | }; | |
124 | ||
7c673cae FG |
125 | template <typename T, void(T::*MF)(int)> |
126 | librbd::RBD::AioCompletion *create_aio_completion(T *t) { | |
127 | return new librbd::RBD::AioCompletion( | |
128 | t, &detail::aio_completion_callback<T, MF>); | |
129 | } | |
130 | ||
131 | void aio_context_callback(librbd::completion_t completion, void *arg); | |
132 | ||
133 | int read_string(int fd, unsigned max, std::string *out); | |
134 | ||
135 | int extract_spec(const std::string &spec, std::string *pool_name, | |
11fdf7f2 TL |
136 | std::string *namespace_name, std::string *name, |
137 | std::string *snap_name, SpecValidation spec_validation); | |
7c673cae FG |
138 | |
139 | std::string get_positional_argument( | |
140 | const boost::program_options::variables_map &vm, size_t index); | |
141 | ||
f67539c2 | 142 | void normalize_pool_name(std::string* pool_name); |
31f18b77 | 143 | std::string get_default_pool_name(); |
f67539c2 | 144 | |
39ae355f TL |
145 | int get_image_or_snap_spec(const boost::program_options::variables_map &vm, |
146 | std::string *spec); | |
147 | ||
148 | void append_options_as_args(const std::vector<std::string> &options, | |
149 | std::vector<std::string> *args); | |
150 | ||
11fdf7f2 | 151 | int get_pool_and_namespace_names( |
2a845540 | 152 | const boost::program_options::variables_map &vm, bool validate_pool_name, |
11fdf7f2 | 153 | std::string* pool_name, std::string* namespace_name, size_t *arg_index); |
7c673cae FG |
154 | |
155 | int get_pool_image_snapshot_names( | |
156 | const boost::program_options::variables_map &vm, | |
157 | argument_types::ArgumentModifier mod, size_t *spec_arg_index, | |
11fdf7f2 TL |
158 | std::string *pool_name, std::string *namespace_name, |
159 | std::string *image_name, std::string *snap_name, bool image_name_required, | |
160 | SnapshotPresence snapshot_presence, SpecValidation spec_validation); | |
7c673cae | 161 | |
11fdf7f2 | 162 | int get_pool_generic_snapshot_names( |
7c673cae FG |
163 | const boost::program_options::variables_map &vm, |
164 | argument_types::ArgumentModifier mod, size_t *spec_arg_index, | |
11fdf7f2 TL |
165 | const std::string& pool_key, std::string *pool_name, |
166 | std::string *namespace_name, const std::string& generic_key, | |
167 | const std::string& generic_key_desc, std::string *generic_name, | |
168 | std::string *snap_name, bool generic_name_required, | |
169 | SnapshotPresence snapshot_presence, SpecValidation spec_validation); | |
170 | ||
171 | int get_pool_image_id(const boost::program_options::variables_map &vm, | |
172 | size_t *spec_arg_index, | |
173 | std::string *pool_name, | |
174 | std::string *namespace_name, | |
175 | std::string *image_id); | |
7c673cae FG |
176 | |
177 | int validate_snapshot_name(argument_types::ArgumentModifier mod, | |
178 | const std::string &snap_name, | |
179 | SnapshotPresence snapshot_presence, | |
180 | SpecValidation spec_validation); | |
181 | ||
182 | int get_image_options(const boost::program_options::variables_map &vm, | |
183 | bool get_format, librbd::ImageOptions* opts); | |
184 | ||
185 | int get_journal_options(const boost::program_options::variables_map &vm, | |
186 | librbd::ImageOptions *opts); | |
187 | ||
11fdf7f2 TL |
188 | int get_flatten_option(const boost::program_options::variables_map &vm, |
189 | librbd::ImageOptions *opts); | |
190 | ||
7c673cae FG |
191 | int get_image_size(const boost::program_options::variables_map &vm, |
192 | uint64_t *size); | |
193 | ||
194 | int get_path(const boost::program_options::variables_map &vm, | |
11fdf7f2 | 195 | size_t *arg_index, std::string *path); |
7c673cae FG |
196 | |
197 | int get_formatter(const boost::program_options::variables_map &vm, | |
198 | argument_types::Format::Formatter *formatter); | |
199 | ||
f67539c2 TL |
200 | int get_snap_create_flags(const boost::program_options::variables_map &vm, |
201 | uint32_t *flags); | |
202 | ||
1e59de90 TL |
203 | int get_encryption_options(const boost::program_options::variables_map &vm, |
204 | EncryptionOptions* result); | |
205 | ||
7c673cae FG |
206 | void init_context(); |
207 | ||
11fdf7f2 | 208 | int init_rados(librados::Rados *rados); |
7c673cae | 209 | |
f67539c2 | 210 | int init(const std::string& pool_name, const std::string& namespace_name, |
11fdf7f2 | 211 | librados::Rados *rados, librados::IoCtx *io_ctx); |
f67539c2 | 212 | int init_io_ctx(librados::Rados &rados, std::string pool_name, |
11fdf7f2 TL |
213 | const std::string& namespace_name, librados::IoCtx *io_ctx); |
214 | int set_namespace(const std::string& namespace_name, librados::IoCtx *io_ctx); | |
215 | ||
216 | void disable_cache(); | |
7c673cae FG |
217 | |
218 | int open_image(librados::IoCtx &io_ctx, const std::string &image_name, | |
219 | bool read_only, librbd::Image *image); | |
220 | ||
221 | int open_image_by_id(librados::IoCtx &io_ctx, const std::string &image_id, | |
222 | bool read_only, librbd::Image *image); | |
223 | ||
224 | int init_and_open_image(const std::string &pool_name, | |
11fdf7f2 | 225 | const std::string &namespace_name, |
7c673cae FG |
226 | const std::string &image_name, |
227 | const std::string &image_id, | |
228 | const std::string &snap_name, bool read_only, | |
229 | librados::Rados *rados, librados::IoCtx *io_ctx, | |
230 | librbd::Image *image); | |
231 | ||
232 | int snap_set(librbd::Image &image, const std::string &snap_name); | |
233 | ||
234 | void calc_sparse_extent(const bufferptr &bp, | |
235 | size_t sparse_size, | |
236 | size_t buffer_offset, | |
237 | uint64_t length, | |
238 | size_t *write_length, | |
239 | bool *zeroed); | |
240 | ||
11fdf7f2 TL |
241 | bool is_not_user_snap_namespace(librbd::Image* image, |
242 | const librbd::snap_info_t &snap_info); | |
7c673cae FG |
243 | |
244 | std::string image_id(librbd::Image& image); | |
245 | ||
9f95a23c TL |
246 | std::string mirror_image_mode( |
247 | librbd::mirror_image_mode_t mirror_image_mode); | |
248 | std::string mirror_image_state( | |
249 | librbd::mirror_image_state_t mirror_image_state); | |
250 | std::string mirror_image_status_state( | |
251 | librbd::mirror_image_status_state_t state); | |
252 | std::string mirror_image_site_status_state( | |
253 | const librbd::mirror_image_site_status_t& status); | |
254 | std::string mirror_image_global_status_state( | |
255 | const librbd::mirror_image_global_status_t& status); | |
256 | ||
257 | int get_local_mirror_image_status( | |
258 | const librbd::mirror_image_global_status_t& status, | |
259 | librbd::mirror_image_site_status_t* local_status); | |
7c673cae FG |
260 | |
261 | std::string timestr(time_t t); | |
262 | ||
263 | // duplicate here to not include librbd_internal lib | |
264 | uint64_t get_rbd_default_features(CephContext* cct); | |
265 | ||
9f95a23c TL |
266 | void get_mirror_peer_sites( |
267 | librados::IoCtx& io_ctx, | |
268 | std::vector<librbd::mirror_peer_site_t>* mirror_peers); | |
269 | void get_mirror_peer_mirror_uuids_to_names( | |
270 | const std::vector<librbd::mirror_peer_site_t>& mirror_peers, | |
271 | std::map<std::string, std::string>* fsid_to_name); | |
272 | void populate_unknown_mirror_image_site_statuses( | |
273 | const std::vector<librbd::mirror_peer_site_t>& mirror_peers, | |
274 | librbd::mirror_image_global_status_t* global_status); | |
275 | ||
276 | int mgr_command(librados::Rados& rados, const std::string& cmd, | |
277 | const std::map<std::string, std::string> &args, | |
278 | std::ostream *out_os, std::ostream *err_os); | |
279 | ||
7c673cae FG |
280 | } // namespace utils |
281 | } // namespace rbd | |
282 | ||
283 | #endif // CEPH_RBD_UTILS_H |