]>
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 | #include <boost/variant.hpp> | |
5 | #include "cls/rbd/cls_rbd_types.h" | |
6 | #include "common/Formatter.h" | |
7 | ||
8 | namespace cls { | |
9 | namespace rbd { | |
10 | ||
11 | void MirrorPeer::encode(bufferlist &bl) const { | |
12 | ENCODE_START(1, 1, bl); | |
13 | ::encode(uuid, bl); | |
14 | ::encode(cluster_name, bl); | |
15 | ::encode(client_name, bl); | |
16 | ::encode(pool_id, bl); | |
17 | ENCODE_FINISH(bl); | |
18 | } | |
19 | ||
20 | void MirrorPeer::decode(bufferlist::iterator &it) { | |
21 | DECODE_START(1, it); | |
22 | ::decode(uuid, it); | |
23 | ::decode(cluster_name, it); | |
24 | ::decode(client_name, it); | |
25 | ::decode(pool_id, it); | |
26 | DECODE_FINISH(it); | |
27 | } | |
28 | ||
29 | void MirrorPeer::dump(Formatter *f) const { | |
30 | f->dump_string("uuid", uuid); | |
31 | f->dump_string("cluster_name", cluster_name); | |
32 | f->dump_string("client_name", client_name); | |
33 | f->dump_int("pool_id", pool_id); | |
34 | } | |
35 | ||
36 | void MirrorPeer::generate_test_instances(std::list<MirrorPeer*> &o) { | |
37 | o.push_back(new MirrorPeer()); | |
38 | o.push_back(new MirrorPeer("uuid-123", "cluster name", "client name", 123)); | |
39 | } | |
40 | ||
41 | bool MirrorPeer::operator==(const MirrorPeer &rhs) const { | |
42 | return (uuid == rhs.uuid && | |
43 | cluster_name == rhs.cluster_name && | |
44 | client_name == rhs.client_name && | |
45 | pool_id == rhs.pool_id); | |
46 | } | |
47 | ||
48 | std::ostream& operator<<(std::ostream& os, const MirrorMode& mirror_mode) { | |
49 | switch (mirror_mode) { | |
50 | case MIRROR_MODE_DISABLED: | |
51 | os << "disabled"; | |
52 | break; | |
53 | case MIRROR_MODE_IMAGE: | |
54 | os << "image"; | |
55 | break; | |
56 | case MIRROR_MODE_POOL: | |
57 | os << "pool"; | |
58 | break; | |
59 | default: | |
60 | os << "unknown (" << static_cast<uint32_t>(mirror_mode) << ")"; | |
61 | break; | |
62 | } | |
63 | return os; | |
64 | } | |
65 | ||
66 | std::ostream& operator<<(std::ostream& os, const MirrorPeer& peer) { | |
67 | os << "[" | |
68 | << "uuid=" << peer.uuid << ", " | |
69 | << "cluster_name=" << peer.cluster_name << ", " | |
70 | << "client_name=" << peer.client_name; | |
71 | if (peer.pool_id != -1) { | |
72 | os << ", pool_id=" << peer.pool_id; | |
73 | } | |
74 | os << "]"; | |
75 | return os; | |
76 | } | |
77 | ||
78 | void MirrorImage::encode(bufferlist &bl) const { | |
79 | ENCODE_START(1, 1, bl); | |
80 | ::encode(global_image_id, bl); | |
81 | ::encode(static_cast<uint8_t>(state), bl); | |
82 | ENCODE_FINISH(bl); | |
83 | } | |
84 | ||
85 | void MirrorImage::decode(bufferlist::iterator &it) { | |
86 | uint8_t int_state; | |
87 | DECODE_START(1, it); | |
88 | ::decode(global_image_id, it); | |
89 | ::decode(int_state, it); | |
90 | state = static_cast<MirrorImageState>(int_state); | |
91 | DECODE_FINISH(it); | |
92 | } | |
93 | ||
94 | void MirrorImage::dump(Formatter *f) const { | |
95 | f->dump_string("global_image_id", global_image_id); | |
96 | f->dump_int("state", state); | |
97 | } | |
98 | ||
99 | void MirrorImage::generate_test_instances(std::list<MirrorImage*> &o) { | |
100 | o.push_back(new MirrorImage()); | |
101 | o.push_back(new MirrorImage("uuid-123", MIRROR_IMAGE_STATE_ENABLED)); | |
102 | o.push_back(new MirrorImage("uuid-abc", MIRROR_IMAGE_STATE_DISABLING)); | |
103 | } | |
104 | ||
105 | bool MirrorImage::operator==(const MirrorImage &rhs) const { | |
106 | return global_image_id == rhs.global_image_id && state == rhs.state; | |
107 | } | |
108 | ||
109 | bool MirrorImage::operator<(const MirrorImage &rhs) const { | |
110 | return global_image_id < rhs.global_image_id || | |
111 | (global_image_id == rhs.global_image_id && state < rhs.state); | |
112 | } | |
113 | ||
114 | std::ostream& operator<<(std::ostream& os, const MirrorImageState& mirror_state) { | |
115 | switch (mirror_state) { | |
116 | case MIRROR_IMAGE_STATE_DISABLING: | |
117 | os << "disabling"; | |
118 | break; | |
119 | case MIRROR_IMAGE_STATE_ENABLED: | |
120 | os << "enabled"; | |
121 | break; | |
122 | default: | |
123 | os << "unknown (" << static_cast<uint32_t>(mirror_state) << ")"; | |
124 | break; | |
125 | } | |
126 | return os; | |
127 | } | |
128 | ||
129 | std::ostream& operator<<(std::ostream& os, const MirrorImage& mirror_image) { | |
130 | os << "[" | |
131 | << "global_image_id=" << mirror_image.global_image_id << ", " | |
132 | << "state=" << mirror_image.state << "]"; | |
133 | return os; | |
134 | } | |
135 | ||
136 | void MirrorImageStatus::encode(bufferlist &bl) const { | |
137 | ENCODE_START(1, 1, bl); | |
138 | ::encode(state, bl); | |
139 | ::encode(description, bl); | |
140 | ::encode(last_update, bl); | |
141 | ::encode(up, bl); | |
142 | ENCODE_FINISH(bl); | |
143 | } | |
144 | ||
145 | void MirrorImageStatus::decode(bufferlist::iterator &it) { | |
146 | DECODE_START(1, it); | |
147 | ::decode(state, it); | |
148 | ::decode(description, it); | |
149 | ::decode(last_update, it); | |
150 | ::decode(up, it); | |
151 | DECODE_FINISH(it); | |
152 | } | |
153 | ||
154 | void MirrorImageStatus::dump(Formatter *f) const { | |
155 | f->dump_string("state", state_to_string()); | |
156 | f->dump_string("description", description); | |
157 | f->dump_stream("last_update") << last_update; | |
158 | } | |
159 | ||
160 | std::string MirrorImageStatus::state_to_string() const { | |
161 | std::stringstream ss; | |
162 | ss << (up ? "up+" : "down+") << state; | |
163 | return ss.str(); | |
164 | } | |
165 | ||
166 | void MirrorImageStatus::generate_test_instances( | |
167 | std::list<MirrorImageStatus*> &o) { | |
168 | o.push_back(new MirrorImageStatus()); | |
169 | o.push_back(new MirrorImageStatus(MIRROR_IMAGE_STATUS_STATE_REPLAYING)); | |
170 | o.push_back(new MirrorImageStatus(MIRROR_IMAGE_STATUS_STATE_ERROR, "error")); | |
171 | } | |
172 | ||
173 | bool MirrorImageStatus::operator==(const MirrorImageStatus &rhs) const { | |
174 | return state == rhs.state && description == rhs.description && up == rhs.up; | |
175 | } | |
176 | ||
177 | std::ostream& operator<<(std::ostream& os, const MirrorImageStatusState& state) { | |
178 | switch (state) { | |
179 | case MIRROR_IMAGE_STATUS_STATE_UNKNOWN: | |
180 | os << "unknown"; | |
181 | break; | |
182 | case MIRROR_IMAGE_STATUS_STATE_ERROR: | |
183 | os << "error"; | |
184 | break; | |
185 | case MIRROR_IMAGE_STATUS_STATE_SYNCING: | |
186 | os << "syncing"; | |
187 | break; | |
188 | case MIRROR_IMAGE_STATUS_STATE_STARTING_REPLAY: | |
189 | os << "starting_replay"; | |
190 | break; | |
191 | case MIRROR_IMAGE_STATUS_STATE_REPLAYING: | |
192 | os << "replaying"; | |
193 | break; | |
194 | case MIRROR_IMAGE_STATUS_STATE_STOPPING_REPLAY: | |
195 | os << "stopping_replay"; | |
196 | break; | |
197 | case MIRROR_IMAGE_STATUS_STATE_STOPPED: | |
198 | os << "stopped"; | |
199 | break; | |
200 | default: | |
201 | os << "unknown (" << static_cast<uint32_t>(state) << ")"; | |
202 | break; | |
203 | } | |
204 | return os; | |
205 | } | |
206 | ||
207 | std::ostream& operator<<(std::ostream& os, const MirrorImageStatus& status) { | |
208 | os << "[" | |
209 | << "state=" << status.state_to_string() << ", " | |
210 | << "description=" << status.description << ", " | |
211 | << "last_update=" << status.last_update << "]"; | |
212 | return os; | |
213 | } | |
214 | ||
215 | void GroupImageSpec::encode(bufferlist &bl) const { | |
216 | ENCODE_START(1, 1, bl); | |
217 | ::encode(image_id, bl); | |
218 | ::encode(pool_id, bl); | |
219 | ENCODE_FINISH(bl); | |
220 | } | |
221 | ||
222 | void GroupImageSpec::decode(bufferlist::iterator &it) { | |
223 | DECODE_START(1, it); | |
224 | ::decode(image_id, it); | |
225 | ::decode(pool_id, it); | |
226 | DECODE_FINISH(it); | |
227 | } | |
228 | ||
229 | void GroupImageSpec::dump(Formatter *f) const { | |
230 | f->dump_string("image_id", image_id); | |
231 | f->dump_int("pool_id", pool_id); | |
232 | } | |
233 | ||
234 | int GroupImageSpec::from_key(const std::string &image_key, | |
235 | GroupImageSpec *spec) { | |
236 | if (nullptr == spec) return -EINVAL; | |
237 | int prefix_len = cls::rbd::RBD_GROUP_IMAGE_KEY_PREFIX.size(); | |
238 | std::string data_string = image_key.substr(prefix_len, | |
239 | image_key.size() - prefix_len); | |
240 | size_t p = data_string.find("_"); | |
241 | if (std::string::npos == p) { | |
242 | return -EIO; | |
243 | } | |
244 | data_string[p] = ' '; | |
245 | ||
246 | istringstream iss(data_string); | |
247 | uint64_t pool_id; | |
248 | string image_id; | |
249 | iss >> std::hex >> pool_id >> image_id; | |
250 | ||
251 | spec->image_id = image_id; | |
252 | spec->pool_id = pool_id; | |
253 | return 0; | |
254 | } | |
255 | ||
256 | std::string GroupImageSpec::image_key() { | |
257 | if (-1 == pool_id) | |
258 | return ""; | |
259 | else { | |
260 | ostringstream oss; | |
261 | oss << RBD_GROUP_IMAGE_KEY_PREFIX << std::setw(16) | |
262 | << std::setfill('0') << std::hex << pool_id << "_" << image_id; | |
263 | return oss.str(); | |
264 | } | |
265 | } | |
266 | ||
267 | void GroupImageStatus::encode(bufferlist &bl) const { | |
268 | ENCODE_START(1, 1, bl); | |
269 | ::encode(spec, bl); | |
270 | ::encode(state, bl); | |
271 | ENCODE_FINISH(bl); | |
272 | } | |
273 | ||
274 | void GroupImageStatus::decode(bufferlist::iterator &it) { | |
275 | DECODE_START(1, it); | |
276 | ::decode(spec, it); | |
277 | ::decode(state, it); | |
278 | DECODE_FINISH(it); | |
279 | } | |
280 | ||
281 | std::string GroupImageStatus::state_to_string() const { | |
282 | std::stringstream ss; | |
283 | if (state == GROUP_IMAGE_LINK_STATE_INCOMPLETE) { | |
284 | ss << "incomplete"; | |
285 | } | |
286 | if (state == GROUP_IMAGE_LINK_STATE_ATTACHED) { | |
287 | ss << "attached"; | |
288 | } | |
289 | return ss.str(); | |
290 | } | |
291 | ||
292 | void GroupImageStatus::dump(Formatter *f) const { | |
293 | spec.dump(f); | |
294 | f->dump_string("state", state_to_string()); | |
295 | } | |
296 | ||
297 | void GroupSpec::encode(bufferlist &bl) const { | |
298 | ENCODE_START(1, 1, bl); | |
299 | ::encode(pool_id, bl); | |
300 | ::encode(group_id, bl); | |
301 | ENCODE_FINISH(bl); | |
302 | } | |
303 | ||
304 | void GroupSpec::decode(bufferlist::iterator &it) { | |
305 | DECODE_START(1, it); | |
306 | ::decode(pool_id, it); | |
307 | ::decode(group_id, it); | |
308 | DECODE_FINISH(it); | |
309 | } | |
310 | ||
311 | void GroupSpec::dump(Formatter *f) const { | |
312 | f->dump_string("group_id", group_id); | |
313 | f->dump_int("pool_id", pool_id); | |
314 | } | |
315 | ||
316 | bool GroupSpec::is_valid() const { | |
317 | return (!group_id.empty()) && (pool_id != -1); | |
318 | } | |
319 | ||
7c673cae FG |
320 | class EncodeSnapshotNamespaceVisitor : public boost::static_visitor<void> { |
321 | public: | |
322 | explicit EncodeSnapshotNamespaceVisitor(bufferlist &bl) : m_bl(bl) { | |
323 | } | |
324 | ||
325 | template <typename T> | |
326 | inline void operator()(const T& t) const { | |
327 | ::encode(static_cast<uint32_t>(T::SNAPSHOT_NAMESPACE_TYPE), m_bl); | |
328 | t.encode(m_bl); | |
329 | } | |
330 | ||
331 | private: | |
332 | bufferlist &m_bl; | |
333 | }; | |
334 | ||
335 | class DecodeSnapshotNamespaceVisitor : public boost::static_visitor<void> { | |
336 | public: | |
337 | DecodeSnapshotNamespaceVisitor(bufferlist::iterator &iter) | |
338 | : m_iter(iter) { | |
339 | } | |
340 | ||
341 | template <typename T> | |
342 | inline void operator()(T& t) const { | |
343 | t.decode(m_iter); | |
344 | } | |
345 | private: | |
346 | bufferlist::iterator &m_iter; | |
347 | }; | |
348 | ||
349 | class DumpSnapshotNamespaceVisitor : public boost::static_visitor<void> { | |
350 | public: | |
351 | explicit DumpSnapshotNamespaceVisitor(Formatter *formatter, const std::string &key) | |
352 | : m_formatter(formatter), m_key(key) {} | |
353 | ||
354 | template <typename T> | |
355 | inline void operator()(const T& t) const { | |
356 | auto type = T::SNAPSHOT_NAMESPACE_TYPE; | |
357 | m_formatter->dump_string(m_key.c_str(), stringify(type)); | |
358 | t.dump(m_formatter); | |
359 | } | |
360 | private: | |
361 | ceph::Formatter *m_formatter; | |
362 | std::string m_key; | |
363 | }; | |
364 | ||
365 | class GetTypeVisitor : public boost::static_visitor<SnapshotNamespaceType> { | |
366 | public: | |
367 | template <typename T> | |
368 | inline SnapshotNamespaceType operator()(const T&) const { | |
369 | return static_cast<SnapshotNamespaceType>(T::SNAPSHOT_NAMESPACE_TYPE); | |
370 | } | |
371 | }; | |
372 | ||
373 | ||
374 | SnapshotNamespaceType SnapshotNamespaceOnDisk::get_namespace_type() const { | |
375 | return static_cast<SnapshotNamespaceType>(boost::apply_visitor(GetTypeVisitor(), | |
376 | snapshot_namespace)); | |
377 | } | |
378 | ||
379 | void SnapshotNamespaceOnDisk::encode(bufferlist& bl) const { | |
380 | ENCODE_START(1, 1, bl); | |
381 | boost::apply_visitor(EncodeSnapshotNamespaceVisitor(bl), snapshot_namespace); | |
382 | ENCODE_FINISH(bl); | |
383 | } | |
384 | ||
385 | void SnapshotNamespaceOnDisk::decode(bufferlist::iterator &p) | |
386 | { | |
387 | DECODE_START(1, p); | |
388 | uint32_t snap_type; | |
389 | ::decode(snap_type, p); | |
390 | switch (snap_type) { | |
391 | case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_USER: | |
392 | snapshot_namespace = UserSnapshotNamespace(); | |
393 | break; | |
7c673cae FG |
394 | default: |
395 | snapshot_namespace = UnknownSnapshotNamespace(); | |
396 | break; | |
397 | } | |
398 | boost::apply_visitor(DecodeSnapshotNamespaceVisitor(p), snapshot_namespace); | |
399 | DECODE_FINISH(p); | |
400 | } | |
401 | ||
402 | void SnapshotNamespaceOnDisk::dump(Formatter *f) const { | |
403 | boost::apply_visitor(DumpSnapshotNamespaceVisitor(f, "snapshot_namespace_type"), snapshot_namespace); | |
404 | } | |
405 | ||
406 | void SnapshotNamespaceOnDisk::generate_test_instances(std::list<SnapshotNamespaceOnDisk *> &o) { | |
407 | o.push_back(new SnapshotNamespaceOnDisk(UserSnapshotNamespace())); | |
7c673cae FG |
408 | } |
409 | ||
410 | std::ostream& operator<<(std::ostream& os, const UserSnapshotNamespace& ns) { | |
411 | os << "[user]"; | |
412 | return os; | |
413 | } | |
414 | ||
7c673cae FG |
415 | std::ostream& operator<<(std::ostream& os, const UnknownSnapshotNamespace& ns) { |
416 | os << "[unknown]"; | |
417 | return os; | |
418 | } | |
419 | ||
420 | void TrashImageSpec::encode(bufferlist& bl) const { | |
421 | ENCODE_START(1, 1, bl); | |
422 | ::encode(source, bl); | |
423 | ::encode(name, bl); | |
424 | ::encode(deletion_time, bl); | |
425 | ::encode(deferment_end_time, bl); | |
426 | ENCODE_FINISH(bl); | |
427 | } | |
428 | ||
429 | void TrashImageSpec::decode(bufferlist::iterator &it) { | |
430 | DECODE_START(1, it); | |
431 | ::decode(source, it); | |
432 | ::decode(name, it); | |
433 | ::decode(deletion_time, it); | |
434 | ::decode(deferment_end_time, it); | |
435 | DECODE_FINISH(it); | |
436 | } | |
437 | ||
438 | void TrashImageSpec::dump(Formatter *f) const { | |
439 | switch(source) { | |
440 | case TRASH_IMAGE_SOURCE_USER: | |
441 | f->dump_string("source", "user"); | |
442 | break; | |
443 | case TRASH_IMAGE_SOURCE_MIRRORING: | |
444 | f->dump_string("source", "rbd_mirror"); | |
445 | } | |
446 | f->dump_string("name", name); | |
447 | f->dump_unsigned("deletion_time", deletion_time); | |
448 | f->dump_unsigned("deferment_end_time", deferment_end_time); | |
449 | } | |
450 | ||
451 | } // namespace rbd | |
452 | } // namespace cls |