]>
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 | ||
9f95a23c TL |
11 | std::ostream& operator<<(std::ostream& os, |
12 | MirrorPeerDirection mirror_peer_direction) { | |
13 | switch (mirror_peer_direction) { | |
14 | case MIRROR_PEER_DIRECTION_RX: | |
15 | os << "RX"; | |
16 | break; | |
17 | case MIRROR_PEER_DIRECTION_TX: | |
18 | os << "TX"; | |
19 | break; | |
20 | case MIRROR_PEER_DIRECTION_RX_TX: | |
21 | os << "RX/TX"; | |
22 | break; | |
23 | default: | |
24 | os << "unknown"; | |
25 | break; | |
26 | } | |
27 | return os; | |
28 | } | |
29 | ||
7c673cae | 30 | void MirrorPeer::encode(bufferlist &bl) const { |
9f95a23c | 31 | ENCODE_START(2, 1, bl); |
11fdf7f2 | 32 | encode(uuid, bl); |
9f95a23c | 33 | encode(site_name, bl); |
11fdf7f2 | 34 | encode(client_name, bl); |
9f95a23c | 35 | int64_t pool_id = -1; |
11fdf7f2 | 36 | encode(pool_id, bl); |
9f95a23c TL |
37 | |
38 | // v2 | |
39 | encode(static_cast<uint8_t>(mirror_peer_direction), bl); | |
40 | encode(mirror_uuid, bl); | |
41 | encode(last_seen, bl); | |
7c673cae FG |
42 | ENCODE_FINISH(bl); |
43 | } | |
44 | ||
11fdf7f2 | 45 | void MirrorPeer::decode(bufferlist::const_iterator &it) { |
9f95a23c | 46 | DECODE_START(2, it); |
11fdf7f2 | 47 | decode(uuid, it); |
9f95a23c | 48 | decode(site_name, it); |
11fdf7f2 | 49 | decode(client_name, it); |
9f95a23c | 50 | int64_t pool_id; |
11fdf7f2 | 51 | decode(pool_id, it); |
9f95a23c TL |
52 | |
53 | if (struct_v >= 2) { | |
54 | uint8_t mpd; | |
55 | decode(mpd, it); | |
56 | mirror_peer_direction = static_cast<MirrorPeerDirection>(mpd); | |
57 | decode(mirror_uuid, it); | |
58 | decode(last_seen, it); | |
59 | } | |
60 | ||
7c673cae FG |
61 | DECODE_FINISH(it); |
62 | } | |
63 | ||
64 | void MirrorPeer::dump(Formatter *f) const { | |
65 | f->dump_string("uuid", uuid); | |
9f95a23c TL |
66 | f->dump_stream("direction") << mirror_peer_direction; |
67 | f->dump_string("site_name", site_name); | |
68 | f->dump_string("mirror_uuid", mirror_uuid); | |
7c673cae | 69 | f->dump_string("client_name", client_name); |
9f95a23c | 70 | f->dump_stream("last_seen") << last_seen; |
7c673cae FG |
71 | } |
72 | ||
73 | void MirrorPeer::generate_test_instances(std::list<MirrorPeer*> &o) { | |
74 | o.push_back(new MirrorPeer()); | |
9f95a23c TL |
75 | o.push_back(new MirrorPeer("uuid-123", MIRROR_PEER_DIRECTION_RX, "site A", |
76 | "client name", "")); | |
77 | o.push_back(new MirrorPeer("uuid-234", MIRROR_PEER_DIRECTION_TX, "site B", | |
78 | "", "mirror_uuid")); | |
79 | o.push_back(new MirrorPeer("uuid-345", MIRROR_PEER_DIRECTION_RX_TX, "site C", | |
80 | "client name", "mirror_uuid")); | |
7c673cae FG |
81 | } |
82 | ||
83 | bool MirrorPeer::operator==(const MirrorPeer &rhs) const { | |
84 | return (uuid == rhs.uuid && | |
9f95a23c TL |
85 | mirror_peer_direction == rhs.mirror_peer_direction && |
86 | site_name == rhs.site_name && | |
7c673cae | 87 | client_name == rhs.client_name && |
9f95a23c TL |
88 | mirror_uuid == rhs.mirror_uuid && |
89 | last_seen == rhs.last_seen); | |
7c673cae FG |
90 | } |
91 | ||
92 | std::ostream& operator<<(std::ostream& os, const MirrorMode& mirror_mode) { | |
93 | switch (mirror_mode) { | |
94 | case MIRROR_MODE_DISABLED: | |
95 | os << "disabled"; | |
96 | break; | |
97 | case MIRROR_MODE_IMAGE: | |
98 | os << "image"; | |
99 | break; | |
100 | case MIRROR_MODE_POOL: | |
101 | os << "pool"; | |
102 | break; | |
103 | default: | |
104 | os << "unknown (" << static_cast<uint32_t>(mirror_mode) << ")"; | |
105 | break; | |
106 | } | |
107 | return os; | |
108 | } | |
109 | ||
110 | std::ostream& operator<<(std::ostream& os, const MirrorPeer& peer) { | |
111 | os << "[" | |
112 | << "uuid=" << peer.uuid << ", " | |
9f95a23c TL |
113 | << "direction=" << peer.mirror_peer_direction << ", " |
114 | << "site_name=" << peer.site_name << ", " | |
115 | << "client_name=" << peer.client_name << ", " | |
116 | << "mirror_uuid=" << peer.mirror_uuid << ", " | |
117 | << "last_seen=" << peer.last_seen | |
118 | << "]"; | |
7c673cae FG |
119 | return os; |
120 | } | |
121 | ||
122 | void MirrorImage::encode(bufferlist &bl) const { | |
9f95a23c | 123 | ENCODE_START(2, 1, bl); |
11fdf7f2 TL |
124 | encode(global_image_id, bl); |
125 | encode(static_cast<uint8_t>(state), bl); | |
9f95a23c | 126 | encode(static_cast<uint8_t>(mode), bl); |
7c673cae FG |
127 | ENCODE_FINISH(bl); |
128 | } | |
129 | ||
11fdf7f2 | 130 | void MirrorImage::decode(bufferlist::const_iterator &it) { |
7c673cae | 131 | uint8_t int_state; |
9f95a23c | 132 | DECODE_START(2, it); |
11fdf7f2 TL |
133 | decode(global_image_id, it); |
134 | decode(int_state, it); | |
7c673cae | 135 | state = static_cast<MirrorImageState>(int_state); |
9f95a23c TL |
136 | if (struct_v >= 2) { |
137 | uint8_t int_mode; | |
138 | decode(int_mode, it); | |
139 | mode = static_cast<MirrorImageMode>(int_mode); | |
140 | } | |
7c673cae FG |
141 | DECODE_FINISH(it); |
142 | } | |
143 | ||
144 | void MirrorImage::dump(Formatter *f) const { | |
9f95a23c | 145 | f->dump_stream("mode") << mode; |
7c673cae | 146 | f->dump_string("global_image_id", global_image_id); |
9f95a23c | 147 | f->dump_stream("state") << state; |
7c673cae FG |
148 | } |
149 | ||
150 | void MirrorImage::generate_test_instances(std::list<MirrorImage*> &o) { | |
151 | o.push_back(new MirrorImage()); | |
9f95a23c TL |
152 | o.push_back(new MirrorImage(MIRROR_IMAGE_MODE_JOURNAL, "uuid-123", |
153 | MIRROR_IMAGE_STATE_ENABLED)); | |
154 | o.push_back(new MirrorImage(MIRROR_IMAGE_MODE_SNAPSHOT, "uuid-abc", | |
155 | MIRROR_IMAGE_STATE_DISABLING)); | |
7c673cae FG |
156 | } |
157 | ||
158 | bool MirrorImage::operator==(const MirrorImage &rhs) const { | |
9f95a23c TL |
159 | return mode == rhs.mode && global_image_id == rhs.global_image_id && |
160 | state == rhs.state; | |
7c673cae FG |
161 | } |
162 | ||
163 | bool MirrorImage::operator<(const MirrorImage &rhs) const { | |
9f95a23c TL |
164 | if (mode != rhs.mode) { |
165 | return mode < rhs.mode; | |
166 | } | |
167 | if (global_image_id != rhs.global_image_id) { | |
168 | return global_image_id < rhs.global_image_id; | |
169 | } | |
170 | return state < rhs.state; | |
171 | } | |
172 | ||
173 | std::ostream& operator<<(std::ostream& os, const MirrorImageMode& mirror_mode) { | |
174 | switch (mirror_mode) { | |
175 | case MIRROR_IMAGE_MODE_JOURNAL: | |
176 | os << "journal"; | |
177 | break; | |
178 | case MIRROR_IMAGE_MODE_SNAPSHOT: | |
179 | os << "snapshot"; | |
180 | break; | |
181 | default: | |
182 | os << "unknown (" << static_cast<uint32_t>(mirror_mode) << ")"; | |
183 | break; | |
184 | } | |
185 | return os; | |
7c673cae FG |
186 | } |
187 | ||
188 | std::ostream& operator<<(std::ostream& os, const MirrorImageState& mirror_state) { | |
189 | switch (mirror_state) { | |
190 | case MIRROR_IMAGE_STATE_DISABLING: | |
191 | os << "disabling"; | |
192 | break; | |
193 | case MIRROR_IMAGE_STATE_ENABLED: | |
194 | os << "enabled"; | |
195 | break; | |
9f95a23c TL |
196 | case MIRROR_IMAGE_STATE_DISABLED: |
197 | os << "disabled"; | |
198 | break; | |
7c673cae FG |
199 | default: |
200 | os << "unknown (" << static_cast<uint32_t>(mirror_state) << ")"; | |
201 | break; | |
202 | } | |
203 | return os; | |
204 | } | |
205 | ||
206 | std::ostream& operator<<(std::ostream& os, const MirrorImage& mirror_image) { | |
207 | os << "[" | |
9f95a23c | 208 | << "mode=" << mirror_image.mode << ", " |
7c673cae FG |
209 | << "global_image_id=" << mirror_image.global_image_id << ", " |
210 | << "state=" << mirror_image.state << "]"; | |
211 | return os; | |
212 | } | |
213 | ||
9f95a23c TL |
214 | std::ostream& operator<<(std::ostream& os, |
215 | const MirrorImageStatusState& state) { | |
7c673cae FG |
216 | switch (state) { |
217 | case MIRROR_IMAGE_STATUS_STATE_UNKNOWN: | |
218 | os << "unknown"; | |
219 | break; | |
220 | case MIRROR_IMAGE_STATUS_STATE_ERROR: | |
221 | os << "error"; | |
222 | break; | |
223 | case MIRROR_IMAGE_STATUS_STATE_SYNCING: | |
224 | os << "syncing"; | |
225 | break; | |
226 | case MIRROR_IMAGE_STATUS_STATE_STARTING_REPLAY: | |
227 | os << "starting_replay"; | |
228 | break; | |
229 | case MIRROR_IMAGE_STATUS_STATE_REPLAYING: | |
230 | os << "replaying"; | |
231 | break; | |
232 | case MIRROR_IMAGE_STATUS_STATE_STOPPING_REPLAY: | |
233 | os << "stopping_replay"; | |
234 | break; | |
235 | case MIRROR_IMAGE_STATUS_STATE_STOPPED: | |
236 | os << "stopped"; | |
237 | break; | |
238 | default: | |
239 | os << "unknown (" << static_cast<uint32_t>(state) << ")"; | |
240 | break; | |
241 | } | |
242 | return os; | |
243 | } | |
244 | ||
9f95a23c TL |
245 | const std::string MirrorImageSiteStatus::LOCAL_MIRROR_UUID(""); // empty mirror uuid |
246 | ||
247 | void MirrorImageSiteStatus::encode_meta(uint8_t version, bufferlist &bl) const { | |
248 | if (version >= 2) { | |
249 | ceph::encode(mirror_uuid, bl); | |
250 | } | |
251 | cls::rbd::encode(state, bl); | |
252 | ceph::encode(description, bl); | |
253 | ceph::encode(last_update, bl); | |
254 | ceph::encode(up, bl); | |
255 | } | |
256 | ||
257 | void MirrorImageSiteStatus::decode_meta(uint8_t version, | |
258 | bufferlist::const_iterator &it) { | |
259 | if (version < 2) { | |
260 | mirror_uuid = LOCAL_MIRROR_UUID; | |
261 | } else { | |
262 | ceph::decode(mirror_uuid, it); | |
263 | } | |
264 | ||
265 | cls::rbd::decode(state, it); | |
266 | ceph::decode(description, it); | |
267 | ::decode(last_update, it); | |
268 | ceph::decode(up, it); | |
269 | } | |
270 | ||
271 | void MirrorImageSiteStatus::encode(bufferlist &bl) const { | |
272 | // break compatibility when site-name is provided | |
273 | uint8_t version = (mirror_uuid == LOCAL_MIRROR_UUID ? 1 : 2); | |
274 | ENCODE_START(version, version, bl); | |
275 | encode_meta(version, bl); | |
276 | ENCODE_FINISH(bl); | |
277 | } | |
278 | ||
279 | void MirrorImageSiteStatus::decode(bufferlist::const_iterator &it) { | |
280 | DECODE_START(2, it); | |
281 | decode_meta(struct_v, it); | |
282 | DECODE_FINISH(it); | |
283 | } | |
284 | ||
285 | void MirrorImageSiteStatus::dump(Formatter *f) const { | |
286 | f->dump_string("state", state_to_string()); | |
287 | f->dump_string("description", description); | |
288 | f->dump_stream("last_update") << last_update; | |
289 | } | |
290 | ||
291 | std::string MirrorImageSiteStatus::state_to_string() const { | |
292 | std::stringstream ss; | |
293 | ss << (up ? "up+" : "down+") << state; | |
294 | return ss.str(); | |
295 | } | |
296 | ||
297 | void MirrorImageSiteStatus::generate_test_instances( | |
298 | std::list<MirrorImageSiteStatus*> &o) { | |
299 | o.push_back(new MirrorImageSiteStatus()); | |
300 | o.push_back(new MirrorImageSiteStatus("", MIRROR_IMAGE_STATUS_STATE_REPLAYING, | |
301 | "")); | |
302 | o.push_back(new MirrorImageSiteStatus("", MIRROR_IMAGE_STATUS_STATE_ERROR, | |
303 | "error")); | |
304 | o.push_back(new MirrorImageSiteStatus("2fb68ca9-1ba0-43b3-8cdf-8c5a9db71e65", | |
305 | MIRROR_IMAGE_STATUS_STATE_STOPPED, "")); | |
306 | } | |
307 | ||
308 | bool MirrorImageSiteStatus::operator==(const MirrorImageSiteStatus &rhs) const { | |
309 | return state == rhs.state && description == rhs.description && up == rhs.up; | |
310 | } | |
311 | ||
312 | std::ostream& operator<<(std::ostream& os, | |
313 | const MirrorImageSiteStatus& status) { | |
314 | os << "{" | |
7c673cae FG |
315 | << "state=" << status.state_to_string() << ", " |
316 | << "description=" << status.description << ", " | |
9f95a23c TL |
317 | << "last_update=" << status.last_update << "]}"; |
318 | return os; | |
319 | } | |
320 | ||
321 | void MirrorImageSiteStatusOnDisk::encode_meta(bufferlist &bl, | |
322 | uint64_t features) const { | |
323 | ENCODE_START(1, 1, bl); | |
324 | auto sanitized_origin = origin; | |
325 | sanitize_entity_inst(&sanitized_origin); | |
326 | encode(sanitized_origin, bl, features); | |
327 | ENCODE_FINISH(bl); | |
328 | } | |
329 | ||
330 | void MirrorImageSiteStatusOnDisk::encode(bufferlist &bl, | |
331 | uint64_t features) const { | |
332 | encode_meta(bl, features); | |
333 | cls::rbd::MirrorImageSiteStatus::encode(bl); | |
334 | } | |
335 | ||
336 | void MirrorImageSiteStatusOnDisk::decode_meta(bufferlist::const_iterator &it) { | |
337 | DECODE_START(1, it); | |
338 | decode(origin, it); | |
339 | sanitize_entity_inst(&origin); | |
340 | DECODE_FINISH(it); | |
341 | } | |
342 | ||
343 | void MirrorImageSiteStatusOnDisk::decode(bufferlist::const_iterator &it) { | |
344 | decode_meta(it); | |
345 | cls::rbd::MirrorImageSiteStatus::decode(it); | |
346 | } | |
347 | ||
348 | void MirrorImageSiteStatusOnDisk::generate_test_instances( | |
349 | std::list<MirrorImageSiteStatusOnDisk*> &o) { | |
350 | o.push_back(new MirrorImageSiteStatusOnDisk()); | |
351 | o.push_back(new MirrorImageSiteStatusOnDisk( | |
352 | {"", MIRROR_IMAGE_STATUS_STATE_ERROR, "error"})); | |
353 | o.push_back(new MirrorImageSiteStatusOnDisk( | |
354 | {"siteA", MIRROR_IMAGE_STATUS_STATE_STOPPED, ""})); | |
355 | } | |
356 | ||
357 | int MirrorImageStatus::get_local_mirror_image_site_status( | |
358 | MirrorImageSiteStatus* status) const { | |
359 | auto it = std::find_if( | |
360 | mirror_image_site_statuses.begin(), | |
361 | mirror_image_site_statuses.end(), | |
362 | [](const MirrorImageSiteStatus& status) { | |
363 | return status.mirror_uuid == MirrorImageSiteStatus::LOCAL_MIRROR_UUID; | |
364 | }); | |
365 | if (it == mirror_image_site_statuses.end()) { | |
366 | return -ENOENT; | |
367 | } | |
368 | ||
369 | *status = *it; | |
370 | return 0; | |
371 | } | |
372 | ||
373 | void MirrorImageStatus::encode(bufferlist &bl) const { | |
374 | // don't break compatibility for extra site statuses | |
375 | ENCODE_START(2, 1, bl); | |
376 | ||
377 | // local site status | |
378 | MirrorImageSiteStatus local_status; | |
379 | int r = get_local_mirror_image_site_status(&local_status); | |
380 | local_status.encode_meta(1, bl); | |
381 | ||
382 | bool local_status_valid = (r >= 0); | |
383 | encode(local_status_valid, bl); | |
384 | ||
385 | // remote site statuses | |
386 | __u32 n = mirror_image_site_statuses.size(); | |
387 | if (local_status_valid) { | |
388 | --n; | |
389 | } | |
390 | encode(n, bl); | |
391 | ||
392 | for (auto& status : mirror_image_site_statuses) { | |
393 | if (status.mirror_uuid == MirrorImageSiteStatus::LOCAL_MIRROR_UUID) { | |
394 | continue; | |
395 | } | |
396 | status.encode_meta(2, bl); | |
397 | } | |
398 | ENCODE_FINISH(bl); | |
399 | } | |
400 | ||
401 | void MirrorImageStatus::decode(bufferlist::const_iterator &it) { | |
402 | DECODE_START(2, it); | |
403 | ||
404 | // local site status | |
405 | MirrorImageSiteStatus local_status; | |
406 | local_status.decode_meta(1, it); | |
407 | ||
408 | if (struct_v < 2) { | |
409 | mirror_image_site_statuses.push_back(local_status); | |
410 | } else { | |
411 | bool local_status_valid; | |
412 | decode(local_status_valid, it); | |
413 | ||
414 | __u32 n; | |
415 | decode(n, it); | |
416 | if (local_status_valid) { | |
417 | ++n; | |
418 | } | |
419 | ||
420 | mirror_image_site_statuses.resize(n); | |
421 | for (auto status_it = mirror_image_site_statuses.begin(); | |
422 | status_it != mirror_image_site_statuses.end(); ++status_it) { | |
423 | if (local_status_valid && | |
424 | status_it == mirror_image_site_statuses.begin()) { | |
425 | *status_it = local_status; | |
426 | continue; | |
427 | } | |
428 | ||
429 | // remote site status | |
430 | status_it->decode_meta(struct_v, it); | |
431 | } | |
432 | } | |
433 | DECODE_FINISH(it); | |
434 | } | |
435 | ||
436 | void MirrorImageStatus::dump(Formatter *f) const { | |
437 | MirrorImageSiteStatus local_status; | |
438 | int r = get_local_mirror_image_site_status(&local_status); | |
439 | if (r >= 0) { | |
440 | local_status.dump(f); | |
441 | } | |
442 | ||
443 | f->open_array_section("remotes"); | |
444 | for (auto& status : mirror_image_site_statuses) { | |
445 | if (status.mirror_uuid == MirrorImageSiteStatus::LOCAL_MIRROR_UUID) { | |
446 | continue; | |
447 | } | |
448 | ||
449 | f->open_object_section("remote"); | |
450 | status.dump(f); | |
451 | f->close_section(); | |
452 | } | |
453 | f->close_section(); | |
454 | } | |
455 | ||
456 | bool MirrorImageStatus::operator==(const MirrorImageStatus &rhs) const { | |
457 | return (mirror_image_site_statuses == rhs.mirror_image_site_statuses); | |
458 | } | |
459 | ||
460 | void MirrorImageStatus::generate_test_instances( | |
461 | std::list<MirrorImageStatus*> &o) { | |
462 | o.push_back(new MirrorImageStatus()); | |
463 | o.push_back(new MirrorImageStatus({{"", MIRROR_IMAGE_STATUS_STATE_ERROR, ""}})); | |
464 | o.push_back(new MirrorImageStatus({{"", MIRROR_IMAGE_STATUS_STATE_STOPPED, ""}, | |
465 | {"siteA", MIRROR_IMAGE_STATUS_STATE_REPLAYING, ""}})); | |
466 | } | |
467 | ||
468 | std::ostream& operator<<(std::ostream& os, | |
469 | const MirrorImageStatus& status) { | |
470 | os << "{"; | |
471 | MirrorImageSiteStatus local_status; | |
472 | int r = status.get_local_mirror_image_site_status(&local_status); | |
473 | if (r >= 0) { | |
474 | os << "state=" << local_status.state_to_string() << ", " | |
475 | << "description=" << local_status.description << ", " | |
476 | << "last_update=" << local_status.last_update << ", "; | |
477 | } | |
478 | ||
479 | os << "remotes=["; | |
480 | for (auto& remote_status : status.mirror_image_site_statuses) { | |
481 | if (remote_status.mirror_uuid == MirrorImageSiteStatus::LOCAL_MIRROR_UUID) { | |
482 | continue; | |
483 | } | |
484 | ||
485 | os << "{" | |
486 | << "mirror_uuid=" << remote_status.mirror_uuid<< ", " | |
487 | << "state=" << remote_status.state_to_string() << ", " | |
488 | << "description=" << remote_status.description << ", " | |
489 | << "last_update=" << remote_status.last_update | |
490 | << "}"; | |
491 | } | |
492 | os << "]}"; | |
7c673cae FG |
493 | return os; |
494 | } | |
495 | ||
11fdf7f2 TL |
496 | void ParentImageSpec::encode(bufferlist& bl) const { |
497 | ENCODE_START(1, 1, bl); | |
498 | encode(pool_id, bl); | |
499 | encode(pool_namespace, bl); | |
500 | encode(image_id, bl); | |
501 | encode(snap_id, bl); | |
502 | ENCODE_FINISH(bl); | |
503 | } | |
504 | ||
505 | void ParentImageSpec::decode(bufferlist::const_iterator& bl) { | |
506 | DECODE_START(1, bl); | |
507 | decode(pool_id, bl); | |
508 | decode(pool_namespace, bl); | |
509 | decode(image_id, bl); | |
510 | decode(snap_id, bl); | |
511 | DECODE_FINISH(bl); | |
512 | } | |
513 | ||
514 | void ParentImageSpec::dump(Formatter *f) const { | |
515 | f->dump_int("pool_id", pool_id); | |
516 | f->dump_string("pool_namespace", pool_namespace); | |
517 | f->dump_string("image_id", image_id); | |
518 | f->dump_unsigned("snap_id", snap_id); | |
519 | } | |
520 | ||
521 | void ParentImageSpec::generate_test_instances(std::list<ParentImageSpec*>& o) { | |
522 | o.push_back(new ParentImageSpec{}); | |
523 | o.push_back(new ParentImageSpec{1, "", "foo", 3}); | |
524 | o.push_back(new ParentImageSpec{1, "ns", "foo", 3}); | |
525 | } | |
526 | ||
9f95a23c TL |
527 | std::ostream& operator<<(std::ostream& os, const ParentImageSpec& rhs) { |
528 | os << "[" | |
529 | << "pool_id=" << rhs.pool_id << ", " | |
530 | << "pool_namespace=" << rhs.pool_namespace << ", " | |
531 | << "image_id=" << rhs.image_id << ", " | |
532 | << "snap_id=" << rhs.snap_id | |
533 | << "]"; | |
534 | return os; | |
535 | } | |
536 | ||
11fdf7f2 TL |
537 | void ChildImageSpec::encode(bufferlist &bl) const { |
538 | ENCODE_START(2, 1, bl); | |
539 | encode(pool_id, bl); | |
540 | encode(image_id, bl); | |
541 | encode(pool_namespace, bl); | |
542 | ENCODE_FINISH(bl); | |
543 | } | |
544 | ||
545 | void ChildImageSpec::decode(bufferlist::const_iterator &it) { | |
546 | DECODE_START(2, it); | |
547 | decode(pool_id, it); | |
548 | decode(image_id, it); | |
549 | if (struct_v >= 2) { | |
550 | decode(pool_namespace, it); | |
551 | } | |
552 | DECODE_FINISH(it); | |
553 | } | |
554 | ||
555 | void ChildImageSpec::dump(Formatter *f) const { | |
556 | f->dump_int("pool_id", pool_id); | |
557 | f->dump_string("pool_namespace", pool_namespace); | |
558 | f->dump_string("image_id", image_id); | |
559 | } | |
560 | ||
561 | void ChildImageSpec::generate_test_instances(std::list<ChildImageSpec*> &o) { | |
562 | o.push_back(new ChildImageSpec()); | |
563 | o.push_back(new ChildImageSpec(123, "", "abc")); | |
564 | o.push_back(new ChildImageSpec(123, "ns", "abc")); | |
565 | } | |
566 | ||
9f95a23c TL |
567 | std::ostream& operator<<(std::ostream& os, const ChildImageSpec& rhs) { |
568 | os << "[" | |
569 | << "pool_id=" << rhs.pool_id << ", " | |
570 | << "pool_namespace=" << rhs.pool_namespace << ", " | |
571 | << "image_id=" << rhs.image_id | |
572 | << "]"; | |
573 | return os; | |
574 | } | |
575 | ||
7c673cae FG |
576 | void GroupImageSpec::encode(bufferlist &bl) const { |
577 | ENCODE_START(1, 1, bl); | |
11fdf7f2 TL |
578 | encode(image_id, bl); |
579 | encode(pool_id, bl); | |
7c673cae FG |
580 | ENCODE_FINISH(bl); |
581 | } | |
582 | ||
11fdf7f2 | 583 | void GroupImageSpec::decode(bufferlist::const_iterator &it) { |
7c673cae | 584 | DECODE_START(1, it); |
11fdf7f2 TL |
585 | decode(image_id, it); |
586 | decode(pool_id, it); | |
7c673cae FG |
587 | DECODE_FINISH(it); |
588 | } | |
589 | ||
590 | void GroupImageSpec::dump(Formatter *f) const { | |
591 | f->dump_string("image_id", image_id); | |
592 | f->dump_int("pool_id", pool_id); | |
593 | } | |
594 | ||
595 | int GroupImageSpec::from_key(const std::string &image_key, | |
596 | GroupImageSpec *spec) { | |
597 | if (nullptr == spec) return -EINVAL; | |
598 | int prefix_len = cls::rbd::RBD_GROUP_IMAGE_KEY_PREFIX.size(); | |
599 | std::string data_string = image_key.substr(prefix_len, | |
600 | image_key.size() - prefix_len); | |
601 | size_t p = data_string.find("_"); | |
602 | if (std::string::npos == p) { | |
603 | return -EIO; | |
604 | } | |
605 | data_string[p] = ' '; | |
606 | ||
607 | istringstream iss(data_string); | |
608 | uint64_t pool_id; | |
609 | string image_id; | |
610 | iss >> std::hex >> pool_id >> image_id; | |
611 | ||
612 | spec->image_id = image_id; | |
613 | spec->pool_id = pool_id; | |
614 | return 0; | |
615 | } | |
616 | ||
617 | std::string GroupImageSpec::image_key() { | |
618 | if (-1 == pool_id) | |
619 | return ""; | |
620 | else { | |
621 | ostringstream oss; | |
622 | oss << RBD_GROUP_IMAGE_KEY_PREFIX << std::setw(16) | |
623 | << std::setfill('0') << std::hex << pool_id << "_" << image_id; | |
624 | return oss.str(); | |
625 | } | |
626 | } | |
627 | ||
11fdf7f2 TL |
628 | void GroupImageSpec::generate_test_instances(std::list<GroupImageSpec*> &o) { |
629 | o.push_back(new GroupImageSpec("10152ae8944a", 0)); | |
630 | o.push_back(new GroupImageSpec("1018643c9869", 3)); | |
631 | } | |
632 | ||
7c673cae FG |
633 | void GroupImageStatus::encode(bufferlist &bl) const { |
634 | ENCODE_START(1, 1, bl); | |
11fdf7f2 TL |
635 | encode(spec, bl); |
636 | encode(state, bl); | |
7c673cae FG |
637 | ENCODE_FINISH(bl); |
638 | } | |
639 | ||
11fdf7f2 | 640 | void GroupImageStatus::decode(bufferlist::const_iterator &it) { |
7c673cae | 641 | DECODE_START(1, it); |
11fdf7f2 TL |
642 | decode(spec, it); |
643 | decode(state, it); | |
7c673cae FG |
644 | DECODE_FINISH(it); |
645 | } | |
646 | ||
647 | std::string GroupImageStatus::state_to_string() const { | |
648 | std::stringstream ss; | |
649 | if (state == GROUP_IMAGE_LINK_STATE_INCOMPLETE) { | |
650 | ss << "incomplete"; | |
651 | } | |
652 | if (state == GROUP_IMAGE_LINK_STATE_ATTACHED) { | |
653 | ss << "attached"; | |
654 | } | |
655 | return ss.str(); | |
656 | } | |
657 | ||
658 | void GroupImageStatus::dump(Formatter *f) const { | |
659 | spec.dump(f); | |
660 | f->dump_string("state", state_to_string()); | |
661 | } | |
662 | ||
11fdf7f2 TL |
663 | void GroupImageStatus::generate_test_instances(std::list<GroupImageStatus*> &o) { |
664 | o.push_back(new GroupImageStatus(GroupImageSpec("10152ae8944a", 0), GROUP_IMAGE_LINK_STATE_ATTACHED)); | |
665 | o.push_back(new GroupImageStatus(GroupImageSpec("1018643c9869", 3), GROUP_IMAGE_LINK_STATE_ATTACHED)); | |
666 | o.push_back(new GroupImageStatus(GroupImageSpec("10152ae8944a", 0), GROUP_IMAGE_LINK_STATE_INCOMPLETE)); | |
667 | o.push_back(new GroupImageStatus(GroupImageSpec("1018643c9869", 3), GROUP_IMAGE_LINK_STATE_INCOMPLETE)); | |
668 | } | |
669 | ||
670 | ||
7c673cae FG |
671 | void GroupSpec::encode(bufferlist &bl) const { |
672 | ENCODE_START(1, 1, bl); | |
11fdf7f2 TL |
673 | encode(pool_id, bl); |
674 | encode(group_id, bl); | |
7c673cae FG |
675 | ENCODE_FINISH(bl); |
676 | } | |
677 | ||
11fdf7f2 | 678 | void GroupSpec::decode(bufferlist::const_iterator &it) { |
7c673cae | 679 | DECODE_START(1, it); |
11fdf7f2 TL |
680 | decode(pool_id, it); |
681 | decode(group_id, it); | |
7c673cae FG |
682 | DECODE_FINISH(it); |
683 | } | |
684 | ||
685 | void GroupSpec::dump(Formatter *f) const { | |
686 | f->dump_string("group_id", group_id); | |
687 | f->dump_int("pool_id", pool_id); | |
688 | } | |
689 | ||
690 | bool GroupSpec::is_valid() const { | |
691 | return (!group_id.empty()) && (pool_id != -1); | |
692 | } | |
693 | ||
11fdf7f2 TL |
694 | void GroupSpec::generate_test_instances(std::list<GroupSpec *> &o) { |
695 | o.push_back(new GroupSpec("10152ae8944a", 0)); | |
696 | o.push_back(new GroupSpec("1018643c9869", 3)); | |
697 | } | |
698 | ||
699 | void GroupSnapshotNamespace::encode(bufferlist& bl) const { | |
700 | using ceph::encode; | |
701 | encode(group_pool, bl); | |
702 | encode(group_id, bl); | |
703 | encode(group_snapshot_id, bl); | |
704 | } | |
705 | ||
706 | void GroupSnapshotNamespace::decode(bufferlist::const_iterator& it) { | |
707 | using ceph::decode; | |
708 | decode(group_pool, it); | |
709 | decode(group_id, it); | |
710 | decode(group_snapshot_id, it); | |
711 | } | |
712 | ||
713 | void GroupSnapshotNamespace::dump(Formatter *f) const { | |
714 | f->dump_int("group_pool", group_pool); | |
715 | f->dump_string("group_id", group_id); | |
716 | f->dump_string("group_snapshot_id", group_snapshot_id); | |
717 | } | |
718 | ||
719 | void TrashSnapshotNamespace::encode(bufferlist& bl) const { | |
720 | using ceph::encode; | |
721 | encode(original_name, bl); | |
722 | encode(static_cast<uint32_t>(original_snapshot_namespace_type), bl); | |
723 | } | |
724 | ||
725 | void TrashSnapshotNamespace::decode(bufferlist::const_iterator& it) { | |
726 | using ceph::decode; | |
727 | decode(original_name, it); | |
728 | uint32_t snap_type; | |
729 | decode(snap_type, it); | |
730 | original_snapshot_namespace_type = static_cast<SnapshotNamespaceType>( | |
731 | snap_type); | |
732 | } | |
733 | ||
734 | void TrashSnapshotNamespace::dump(Formatter *f) const { | |
735 | f->dump_string("original_name", original_name); | |
736 | f->dump_stream("original_snapshot_namespace") | |
737 | << original_snapshot_namespace_type; | |
738 | } | |
739 | ||
9f95a23c TL |
740 | void MirrorSnapshotNamespace::encode(bufferlist& bl) const { |
741 | using ceph::encode; | |
742 | encode(state, bl); | |
743 | encode(complete, bl); | |
744 | encode(mirror_peer_uuids, bl); | |
745 | encode(primary_mirror_uuid, bl); | |
746 | encode(primary_snap_id, bl); | |
747 | encode(last_copied_object_number, bl); | |
748 | encode(snap_seqs, bl); | |
749 | } | |
750 | ||
751 | void MirrorSnapshotNamespace::decode(bufferlist::const_iterator& it) { | |
752 | using ceph::decode; | |
753 | decode(state, it); | |
754 | decode(complete, it); | |
755 | decode(mirror_peer_uuids, it); | |
756 | decode(primary_mirror_uuid, it); | |
757 | decode(primary_snap_id, it); | |
758 | decode(last_copied_object_number, it); | |
759 | decode(snap_seqs, it); | |
760 | } | |
761 | ||
762 | void MirrorSnapshotNamespace::dump(Formatter *f) const { | |
763 | f->dump_stream("state") << state; | |
764 | f->dump_bool("complete", complete); | |
765 | f->open_array_section("mirror_peer_uuids"); | |
766 | for (auto &peer : mirror_peer_uuids) { | |
767 | f->dump_string("mirror_peer_uuid", peer); | |
768 | } | |
769 | f->close_section(); | |
770 | f->dump_string("primary_mirror_uuid", primary_mirror_uuid); | |
771 | f->dump_unsigned("primary_snap_id", primary_snap_id); | |
772 | f->dump_unsigned("last_copied_object_number", last_copied_object_number); | |
773 | f->dump_stream("snap_seqs") << snap_seqs; | |
774 | } | |
775 | ||
7c673cae FG |
776 | class EncodeSnapshotNamespaceVisitor : public boost::static_visitor<void> { |
777 | public: | |
778 | explicit EncodeSnapshotNamespaceVisitor(bufferlist &bl) : m_bl(bl) { | |
779 | } | |
780 | ||
781 | template <typename T> | |
782 | inline void operator()(const T& t) const { | |
11fdf7f2 TL |
783 | using ceph::encode; |
784 | encode(static_cast<uint32_t>(T::SNAPSHOT_NAMESPACE_TYPE), m_bl); | |
7c673cae FG |
785 | t.encode(m_bl); |
786 | } | |
787 | ||
788 | private: | |
789 | bufferlist &m_bl; | |
790 | }; | |
791 | ||
792 | class DecodeSnapshotNamespaceVisitor : public boost::static_visitor<void> { | |
793 | public: | |
11fdf7f2 | 794 | DecodeSnapshotNamespaceVisitor(bufferlist::const_iterator &iter) |
7c673cae FG |
795 | : m_iter(iter) { |
796 | } | |
797 | ||
798 | template <typename T> | |
799 | inline void operator()(T& t) const { | |
800 | t.decode(m_iter); | |
801 | } | |
802 | private: | |
11fdf7f2 | 803 | bufferlist::const_iterator &m_iter; |
7c673cae FG |
804 | }; |
805 | ||
806 | class DumpSnapshotNamespaceVisitor : public boost::static_visitor<void> { | |
807 | public: | |
808 | explicit DumpSnapshotNamespaceVisitor(Formatter *formatter, const std::string &key) | |
809 | : m_formatter(formatter), m_key(key) {} | |
810 | ||
811 | template <typename T> | |
812 | inline void operator()(const T& t) const { | |
813 | auto type = T::SNAPSHOT_NAMESPACE_TYPE; | |
814 | m_formatter->dump_string(m_key.c_str(), stringify(type)); | |
815 | t.dump(m_formatter); | |
816 | } | |
817 | private: | |
818 | ceph::Formatter *m_formatter; | |
819 | std::string m_key; | |
820 | }; | |
821 | ||
822 | class GetTypeVisitor : public boost::static_visitor<SnapshotNamespaceType> { | |
823 | public: | |
824 | template <typename T> | |
825 | inline SnapshotNamespaceType operator()(const T&) const { | |
826 | return static_cast<SnapshotNamespaceType>(T::SNAPSHOT_NAMESPACE_TYPE); | |
827 | } | |
828 | }; | |
829 | ||
11fdf7f2 TL |
830 | SnapshotNamespaceType get_snap_namespace_type( |
831 | const SnapshotNamespace& snapshot_namespace) { | |
832 | return static_cast<SnapshotNamespaceType>(boost::apply_visitor( | |
833 | GetTypeVisitor(), snapshot_namespace)); | |
834 | } | |
835 | ||
836 | void SnapshotInfo::encode(bufferlist& bl) const { | |
837 | ENCODE_START(1, 1, bl); | |
838 | encode(id, bl); | |
839 | encode(snapshot_namespace, bl); | |
840 | encode(name, bl); | |
841 | encode(image_size, bl); | |
842 | encode(timestamp, bl); | |
843 | encode(child_count, bl); | |
844 | ENCODE_FINISH(bl); | |
845 | } | |
846 | ||
847 | void SnapshotInfo::decode(bufferlist::const_iterator& it) { | |
848 | DECODE_START(1, it); | |
849 | decode(id, it); | |
850 | decode(snapshot_namespace, it); | |
851 | decode(name, it); | |
852 | decode(image_size, it); | |
853 | decode(timestamp, it); | |
854 | decode(child_count, it); | |
855 | DECODE_FINISH(it); | |
856 | } | |
857 | ||
858 | void SnapshotInfo::dump(Formatter *f) const { | |
859 | f->dump_unsigned("id", id); | |
860 | f->open_object_section("namespace"); | |
861 | boost::apply_visitor(DumpSnapshotNamespaceVisitor(f, "type"), | |
862 | snapshot_namespace); | |
863 | f->close_section(); | |
864 | f->dump_string("name", name); | |
865 | f->dump_unsigned("image_size", image_size); | |
866 | f->dump_stream("timestamp") << timestamp; | |
867 | } | |
7c673cae | 868 | |
11fdf7f2 TL |
869 | void SnapshotInfo::generate_test_instances(std::list<SnapshotInfo*> &o) { |
870 | o.push_back(new SnapshotInfo(1ULL, UserSnapshotNamespace{}, "snap1", 123, | |
871 | {123456, 0}, 12)); | |
872 | o.push_back(new SnapshotInfo(2ULL, | |
873 | GroupSnapshotNamespace{567, "group1", "snap1"}, | |
874 | "snap1", 123, {123456, 0}, 987)); | |
875 | o.push_back(new SnapshotInfo(3ULL, | |
876 | TrashSnapshotNamespace{ | |
877 | SNAPSHOT_NAMESPACE_TYPE_USER, "snap1"}, | |
878 | "12345", 123, {123456, 0}, 429)); | |
9f95a23c TL |
879 | o.push_back(new SnapshotInfo(1ULL, |
880 | MirrorSnapshotNamespace{MIRROR_SNAPSHOT_STATE_PRIMARY, | |
881 | {"1", "2"}, "", CEPH_NOSNAP}, | |
882 | "snap1", 123, {123456, 0}, 12)); | |
883 | o.push_back(new SnapshotInfo(1ULL, | |
884 | MirrorSnapshotNamespace{MIRROR_SNAPSHOT_STATE_NON_PRIMARY, | |
885 | {"1", "2"}, "uuid", 123}, | |
886 | "snap1", 123, {123456, 0}, 12)); | |
7c673cae FG |
887 | } |
888 | ||
11fdf7f2 | 889 | void SnapshotNamespace::encode(bufferlist& bl) const { |
7c673cae | 890 | ENCODE_START(1, 1, bl); |
11fdf7f2 | 891 | boost::apply_visitor(EncodeSnapshotNamespaceVisitor(bl), *this); |
7c673cae FG |
892 | ENCODE_FINISH(bl); |
893 | } | |
894 | ||
11fdf7f2 | 895 | void SnapshotNamespace::decode(bufferlist::const_iterator &p) |
7c673cae FG |
896 | { |
897 | DECODE_START(1, p); | |
898 | uint32_t snap_type; | |
11fdf7f2 | 899 | decode(snap_type, p); |
7c673cae FG |
900 | switch (snap_type) { |
901 | case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_USER: | |
11fdf7f2 TL |
902 | *this = UserSnapshotNamespace(); |
903 | break; | |
904 | case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_GROUP: | |
905 | *this = GroupSnapshotNamespace(); | |
906 | break; | |
907 | case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_TRASH: | |
908 | *this = TrashSnapshotNamespace(); | |
7c673cae | 909 | break; |
9f95a23c TL |
910 | case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_MIRROR: |
911 | *this = MirrorSnapshotNamespace(); | |
912 | break; | |
7c673cae | 913 | default: |
11fdf7f2 | 914 | *this = UnknownSnapshotNamespace(); |
7c673cae FG |
915 | break; |
916 | } | |
11fdf7f2 | 917 | boost::apply_visitor(DecodeSnapshotNamespaceVisitor(p), *this); |
7c673cae FG |
918 | DECODE_FINISH(p); |
919 | } | |
920 | ||
11fdf7f2 TL |
921 | void SnapshotNamespace::dump(Formatter *f) const { |
922 | boost::apply_visitor( | |
923 | DumpSnapshotNamespaceVisitor(f, "snapshot_namespace_type"), *this); | |
7c673cae FG |
924 | } |
925 | ||
11fdf7f2 TL |
926 | void SnapshotNamespace::generate_test_instances(std::list<SnapshotNamespace*> &o) { |
927 | o.push_back(new SnapshotNamespace(UserSnapshotNamespace())); | |
928 | o.push_back(new SnapshotNamespace(GroupSnapshotNamespace(0, "10152ae8944a", | |
929 | "2118643c9732"))); | |
930 | o.push_back(new SnapshotNamespace(GroupSnapshotNamespace(5, "1018643c9869", | |
931 | "33352be8933c"))); | |
932 | o.push_back(new SnapshotNamespace(TrashSnapshotNamespace())); | |
9f95a23c TL |
933 | o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_PRIMARY, |
934 | {"peer uuid"}, | |
935 | "", CEPH_NOSNAP))); | |
936 | o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_PRIMARY_DEMOTED, | |
937 | {"peer uuid"}, | |
938 | "", CEPH_NOSNAP))); | |
939 | o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_NON_PRIMARY, | |
940 | {"peer uuid"}, | |
941 | "uuid", 123))); | |
942 | o.push_back(new SnapshotNamespace(MirrorSnapshotNamespace(MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED, | |
943 | {"peer uuid"}, | |
944 | "uuid", 123))); | |
11fdf7f2 TL |
945 | } |
946 | ||
947 | std::ostream& operator<<(std::ostream& os, const SnapshotNamespaceType& type) { | |
948 | switch (type) { | |
949 | case SNAPSHOT_NAMESPACE_TYPE_USER: | |
950 | os << "user"; | |
951 | break; | |
952 | case SNAPSHOT_NAMESPACE_TYPE_GROUP: | |
953 | os << "group"; | |
954 | break; | |
955 | case SNAPSHOT_NAMESPACE_TYPE_TRASH: | |
956 | os << "trash"; | |
957 | break; | |
9f95a23c TL |
958 | case SNAPSHOT_NAMESPACE_TYPE_MIRROR: |
959 | os << "mirror"; | |
960 | break; | |
11fdf7f2 TL |
961 | default: |
962 | os << "unknown"; | |
963 | break; | |
964 | } | |
965 | return os; | |
7c673cae FG |
966 | } |
967 | ||
968 | std::ostream& operator<<(std::ostream& os, const UserSnapshotNamespace& ns) { | |
11fdf7f2 TL |
969 | os << "[" << SNAPSHOT_NAMESPACE_TYPE_USER << "]"; |
970 | return os; | |
971 | } | |
972 | ||
973 | std::ostream& operator<<(std::ostream& os, const GroupSnapshotNamespace& ns) { | |
974 | os << "[" << SNAPSHOT_NAMESPACE_TYPE_GROUP << " " | |
975 | << "group_pool=" << ns.group_pool << ", " | |
976 | << "group_id=" << ns.group_id << ", " | |
977 | << "group_snapshot_id=" << ns.group_snapshot_id << "]"; | |
978 | return os; | |
979 | } | |
980 | ||
981 | std::ostream& operator<<(std::ostream& os, const TrashSnapshotNamespace& ns) { | |
982 | os << "[" << SNAPSHOT_NAMESPACE_TYPE_TRASH << " " | |
983 | << "original_name=" << ns.original_name << ", " | |
984 | << "original_snapshot_namespace=" << ns.original_snapshot_namespace_type | |
985 | << "]"; | |
7c673cae FG |
986 | return os; |
987 | } | |
988 | ||
9f95a23c TL |
989 | std::ostream& operator<<(std::ostream& os, const MirrorSnapshotNamespace& ns) { |
990 | os << "[" << SNAPSHOT_NAMESPACE_TYPE_MIRROR << " " | |
991 | << "state=" << ns.state << ", " | |
992 | << "complete=" << ns.complete << ", " | |
993 | << "mirror_peer_uuids=" << ns.mirror_peer_uuids << ", " | |
994 | << "primary_mirror_uuid=" << ns.primary_mirror_uuid << ", " | |
995 | << "primary_snap_id=" << ns.primary_snap_id << ", " | |
996 | << "last_copied_object_number=" << ns.last_copied_object_number << ", " | |
997 | << "snap_seqs=" << ns.snap_seqs | |
998 | << "]"; | |
999 | return os; | |
1000 | } | |
1001 | ||
7c673cae FG |
1002 | std::ostream& operator<<(std::ostream& os, const UnknownSnapshotNamespace& ns) { |
1003 | os << "[unknown]"; | |
1004 | return os; | |
1005 | } | |
1006 | ||
9f95a23c TL |
1007 | std::ostream& operator<<(std::ostream& os, MirrorSnapshotState type) { |
1008 | switch (type) { | |
1009 | case MIRROR_SNAPSHOT_STATE_PRIMARY: | |
1010 | os << "primary"; | |
1011 | break; | |
1012 | case MIRROR_SNAPSHOT_STATE_PRIMARY_DEMOTED: | |
1013 | os << "primary (demoted)"; | |
1014 | break; | |
1015 | case MIRROR_SNAPSHOT_STATE_NON_PRIMARY: | |
1016 | os << "non-primary"; | |
1017 | break; | |
1018 | case MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED: | |
1019 | os << "non-primary (demoted)"; | |
1020 | break; | |
1021 | default: | |
1022 | os << "unknown"; | |
1023 | break; | |
1024 | } | |
1025 | return os; | |
1026 | } | |
1027 | ||
11fdf7f2 TL |
1028 | void ImageSnapshotSpec::encode(bufferlist& bl) const { |
1029 | using ceph::encode; | |
7c673cae | 1030 | ENCODE_START(1, 1, bl); |
11fdf7f2 TL |
1031 | encode(pool, bl); |
1032 | encode(image_id, bl); | |
1033 | encode(snap_id, bl); | |
7c673cae FG |
1034 | ENCODE_FINISH(bl); |
1035 | } | |
1036 | ||
11fdf7f2 TL |
1037 | void ImageSnapshotSpec::decode(bufferlist::const_iterator& it) { |
1038 | using ceph::decode; | |
7c673cae | 1039 | DECODE_START(1, it); |
11fdf7f2 TL |
1040 | decode(pool, it); |
1041 | decode(image_id, it); | |
1042 | decode(snap_id, it); | |
7c673cae FG |
1043 | DECODE_FINISH(it); |
1044 | } | |
1045 | ||
11fdf7f2 TL |
1046 | void ImageSnapshotSpec::dump(Formatter *f) const { |
1047 | f->dump_int("pool", pool); | |
1048 | f->dump_string("image_id", image_id); | |
1049 | f->dump_int("snap_id", snap_id); | |
1050 | } | |
1051 | ||
1052 | void ImageSnapshotSpec::generate_test_instances(std::list<ImageSnapshotSpec *> &o) { | |
1053 | o.push_back(new ImageSnapshotSpec(0, "myimage", 2)); | |
1054 | o.push_back(new ImageSnapshotSpec(1, "testimage", 7)); | |
1055 | } | |
1056 | ||
1057 | void GroupSnapshot::encode(bufferlist& bl) const { | |
1058 | using ceph::encode; | |
1059 | ENCODE_START(1, 1, bl); | |
1060 | encode(id, bl); | |
1061 | encode(name, bl); | |
1062 | encode(state, bl); | |
1063 | encode(snaps, bl); | |
1064 | ENCODE_FINISH(bl); | |
1065 | } | |
1066 | ||
1067 | void GroupSnapshot::decode(bufferlist::const_iterator& it) { | |
1068 | using ceph::decode; | |
1069 | DECODE_START(1, it); | |
1070 | decode(id, it); | |
1071 | decode(name, it); | |
1072 | decode(state, it); | |
1073 | decode(snaps, it); | |
1074 | DECODE_FINISH(it); | |
1075 | } | |
1076 | ||
1077 | void GroupSnapshot::dump(Formatter *f) const { | |
1078 | f->dump_string("id", id); | |
1079 | f->dump_string("name", name); | |
1080 | f->dump_int("state", state); | |
1081 | } | |
1082 | ||
1083 | void GroupSnapshot::generate_test_instances(std::list<GroupSnapshot *> &o) { | |
1084 | o.push_back(new GroupSnapshot("10152ae8944a", "groupsnapshot1", GROUP_SNAPSHOT_STATE_INCOMPLETE)); | |
1085 | o.push_back(new GroupSnapshot("1018643c9869", "groupsnapshot2", GROUP_SNAPSHOT_STATE_COMPLETE)); | |
1086 | } | |
1087 | void TrashImageSpec::encode(bufferlist& bl) const { | |
1088 | ENCODE_START(2, 1, bl); | |
1089 | encode(source, bl); | |
1090 | encode(name, bl); | |
1091 | encode(deletion_time, bl); | |
1092 | encode(deferment_end_time, bl); | |
1093 | encode(state, bl); | |
1094 | ENCODE_FINISH(bl); | |
1095 | } | |
1096 | ||
1097 | void TrashImageSpec::decode(bufferlist::const_iterator &it) { | |
1098 | DECODE_START(2, it); | |
1099 | decode(source, it); | |
1100 | decode(name, it); | |
1101 | decode(deletion_time, it); | |
1102 | decode(deferment_end_time, it); | |
1103 | if (struct_v >= 2) { | |
1104 | decode(state, it); | |
7c673cae | 1105 | } |
11fdf7f2 TL |
1106 | DECODE_FINISH(it); |
1107 | } | |
1108 | ||
1109 | void TrashImageSpec::dump(Formatter *f) const { | |
1110 | f->dump_stream("source") << source; | |
7c673cae FG |
1111 | f->dump_string("name", name); |
1112 | f->dump_unsigned("deletion_time", deletion_time); | |
1113 | f->dump_unsigned("deferment_end_time", deferment_end_time); | |
1114 | } | |
1115 | ||
11fdf7f2 TL |
1116 | void MirrorImageMap::encode(bufferlist &bl) const { |
1117 | ENCODE_START(1, 1, bl); | |
1118 | encode(instance_id, bl); | |
1119 | encode(mapped_time, bl); | |
1120 | encode(data, bl); | |
1121 | ENCODE_FINISH(bl); | |
1122 | } | |
1123 | ||
1124 | void MirrorImageMap::decode(bufferlist::const_iterator &it) { | |
1125 | DECODE_START(1, it); | |
1126 | decode(instance_id, it); | |
1127 | decode(mapped_time, it); | |
1128 | decode(data, it); | |
1129 | DECODE_FINISH(it); | |
1130 | } | |
1131 | ||
1132 | void MirrorImageMap::dump(Formatter *f) const { | |
1133 | f->dump_string("instance_id", instance_id); | |
1134 | f->dump_stream("mapped_time") << mapped_time; | |
1135 | ||
1136 | std::stringstream data_ss; | |
1137 | data.hexdump(data_ss); | |
1138 | f->dump_string("data", data_ss.str()); | |
1139 | } | |
1140 | ||
1141 | void MirrorImageMap::generate_test_instances( | |
1142 | std::list<MirrorImageMap*> &o) { | |
1143 | bufferlist data; | |
1144 | data.append(std::string(128, '1')); | |
1145 | ||
1146 | o.push_back(new MirrorImageMap("uuid-123", utime_t(), data)); | |
1147 | o.push_back(new MirrorImageMap("uuid-abc", utime_t(), data)); | |
1148 | } | |
1149 | ||
1150 | bool MirrorImageMap::operator==(const MirrorImageMap &rhs) const { | |
1151 | return instance_id == rhs.instance_id && mapped_time == rhs.mapped_time && | |
1152 | data.contents_equal(rhs.data); | |
1153 | } | |
1154 | ||
1155 | bool MirrorImageMap::operator<(const MirrorImageMap &rhs) const { | |
1156 | return instance_id < rhs.instance_id || | |
1157 | (instance_id == rhs.instance_id && mapped_time < rhs.mapped_time); | |
1158 | } | |
1159 | ||
1160 | std::ostream& operator<<(std::ostream& os, | |
1161 | const MirrorImageMap &image_map) { | |
1162 | return os << "[" << "instance_id=" << image_map.instance_id << ", mapped_time=" | |
1163 | << image_map.mapped_time << "]"; | |
1164 | } | |
1165 | ||
1166 | std::ostream& operator<<(std::ostream& os, | |
1167 | const MigrationHeaderType& type) { | |
1168 | switch (type) { | |
1169 | case MIGRATION_HEADER_TYPE_SRC: | |
1170 | os << "source"; | |
1171 | break; | |
1172 | case MIGRATION_HEADER_TYPE_DST: | |
1173 | os << "destination"; | |
1174 | break; | |
1175 | default: | |
1176 | os << "unknown (" << static_cast<uint32_t>(type) << ")"; | |
1177 | break; | |
1178 | } | |
1179 | return os; | |
1180 | } | |
1181 | ||
1182 | std::ostream& operator<<(std::ostream& os, | |
1183 | const MigrationState& migration_state) { | |
1184 | switch (migration_state) { | |
1185 | case MIGRATION_STATE_ERROR: | |
1186 | os << "error"; | |
1187 | break; | |
1188 | case MIGRATION_STATE_PREPARING: | |
1189 | os << "preparing"; | |
1190 | break; | |
1191 | case MIGRATION_STATE_PREPARED: | |
1192 | os << "prepared"; | |
1193 | break; | |
1194 | case MIGRATION_STATE_EXECUTING: | |
1195 | os << "executing"; | |
1196 | break; | |
1197 | case MIGRATION_STATE_EXECUTED: | |
1198 | os << "executed"; | |
1199 | break; | |
1200 | default: | |
1201 | os << "unknown (" << static_cast<uint32_t>(migration_state) << ")"; | |
1202 | break; | |
1203 | } | |
1204 | return os; | |
1205 | } | |
1206 | ||
1207 | void MigrationSpec::encode(bufferlist& bl) const { | |
9f95a23c | 1208 | ENCODE_START(2, 1, bl); |
11fdf7f2 TL |
1209 | encode(header_type, bl); |
1210 | encode(pool_id, bl); | |
1211 | encode(pool_namespace, bl); | |
1212 | encode(image_name, bl); | |
1213 | encode(image_id, bl); | |
1214 | encode(snap_seqs, bl); | |
1215 | encode(overlap, bl); | |
1216 | encode(flatten, bl); | |
1217 | encode(mirroring, bl); | |
1218 | encode(state, bl); | |
1219 | encode(state_description, bl); | |
9f95a23c | 1220 | encode(static_cast<uint8_t>(mirror_image_mode), bl); |
11fdf7f2 TL |
1221 | ENCODE_FINISH(bl); |
1222 | } | |
1223 | ||
1224 | void MigrationSpec::decode(bufferlist::const_iterator& bl) { | |
9f95a23c | 1225 | DECODE_START(2, bl); |
11fdf7f2 TL |
1226 | decode(header_type, bl); |
1227 | decode(pool_id, bl); | |
1228 | decode(pool_namespace, bl); | |
1229 | decode(image_name, bl); | |
1230 | decode(image_id, bl); | |
1231 | decode(snap_seqs, bl); | |
1232 | decode(overlap, bl); | |
1233 | decode(flatten, bl); | |
1234 | decode(mirroring, bl); | |
1235 | decode(state, bl); | |
1236 | decode(state_description, bl); | |
9f95a23c TL |
1237 | if (struct_v >= 2) { |
1238 | uint8_t int_mode; | |
1239 | decode(int_mode, bl); | |
1240 | mirror_image_mode = static_cast<MirrorImageMode>(int_mode); | |
1241 | } | |
1242 | DECODE_FINISH(bl); | |
11fdf7f2 TL |
1243 | } |
1244 | ||
1245 | std::ostream& operator<<(std::ostream& os, | |
1246 | const std::map<uint64_t, uint64_t>& snap_seqs) { | |
1247 | os << "{"; | |
1248 | size_t count = 0; | |
1249 | for (auto &it : snap_seqs) { | |
1250 | os << (count++ > 0 ? ", " : "") << "(" << it.first << ", " << it.second | |
1251 | << ")"; | |
1252 | } | |
1253 | os << "}"; | |
1254 | return os; | |
1255 | } | |
1256 | ||
1257 | void MigrationSpec::dump(Formatter *f) const { | |
1258 | f->dump_stream("header_type") << header_type; | |
1259 | f->dump_int("pool_id", pool_id); | |
1260 | f->dump_string("pool_namespace", pool_namespace); | |
1261 | f->dump_string("image_name", image_name); | |
1262 | f->dump_string("image_id", image_id); | |
1263 | f->dump_stream("snap_seqs") << snap_seqs; | |
1264 | f->dump_unsigned("overlap", overlap); | |
1265 | f->dump_bool("mirroring", mirroring); | |
9f95a23c | 1266 | f->dump_stream("mirror_image_mode") << mirror_image_mode; |
11fdf7f2 TL |
1267 | } |
1268 | ||
1269 | void MigrationSpec::generate_test_instances(std::list<MigrationSpec*> &o) { | |
1270 | o.push_back(new MigrationSpec()); | |
1271 | o.push_back(new MigrationSpec(MIGRATION_HEADER_TYPE_SRC, 1, "ns", | |
1272 | "image_name", "image_id", {{1, 2}}, 123, true, | |
9f95a23c TL |
1273 | MIRROR_IMAGE_MODE_SNAPSHOT, true, |
1274 | MIGRATION_STATE_PREPARED, "description")); | |
11fdf7f2 TL |
1275 | } |
1276 | ||
1277 | std::ostream& operator<<(std::ostream& os, | |
1278 | const MigrationSpec& migration_spec) { | |
1279 | os << "[" | |
1280 | << "header_type=" << migration_spec.header_type << ", " | |
1281 | << "pool_id=" << migration_spec.pool_id << ", " | |
1282 | << "pool_namespace=" << migration_spec.pool_namespace << ", " | |
1283 | << "image_name=" << migration_spec.image_name << ", " | |
1284 | << "image_id=" << migration_spec.image_id << ", " | |
1285 | << "snap_seqs=" << migration_spec.snap_seqs << ", " | |
1286 | << "overlap=" << migration_spec.overlap << ", " | |
1287 | << "flatten=" << migration_spec.flatten << ", " | |
1288 | << "mirroring=" << migration_spec.mirroring << ", " | |
9f95a23c | 1289 | << "mirror_image_mode=" << migration_spec.mirror_image_mode << ", " |
11fdf7f2 TL |
1290 | << "state=" << migration_spec.state << ", " |
1291 | << "state_description=" << migration_spec.state_description << "]"; | |
1292 | return os; | |
1293 | } | |
1294 | ||
1295 | std::ostream& operator<<(std::ostream& os, const AssertSnapcSeqState& state) { | |
1296 | switch (state) { | |
1297 | case ASSERT_SNAPC_SEQ_GT_SNAPSET_SEQ: | |
1298 | os << "gt"; | |
1299 | break; | |
1300 | case ASSERT_SNAPC_SEQ_LE_SNAPSET_SEQ: | |
1301 | os << "le"; | |
1302 | break; | |
1303 | default: | |
1304 | os << "unknown (" << static_cast<uint32_t>(state) << ")"; | |
1305 | break; | |
1306 | } | |
1307 | return os; | |
1308 | } | |
1309 | ||
9f95a23c TL |
1310 | void sanitize_entity_inst(entity_inst_t* entity_inst) { |
1311 | // make all addrs of type ANY because the type isn't what uniquely | |
1312 | // identifies them and clients and on-disk formats can be encoded | |
1313 | // with different backwards compatibility settings. | |
1314 | entity_inst->addr.set_type(entity_addr_t::TYPE_ANY); | |
1315 | } | |
1316 | ||
7c673cae FG |
1317 | } // namespace rbd |
1318 | } // namespace cls |