Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / cls / rbd / cls_rbd_types.cc
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
320 void GroupSnapshotNamespace::encode(bufferlist& bl) const {
321   ::encode(group_pool, bl);
322   ::encode(group_id, bl);
323   ::encode(snapshot_id, bl);
324 }
325
326 void GroupSnapshotNamespace::decode(bufferlist::iterator& it) {
327   ::decode(group_pool, it);
328   ::decode(group_id, it);
329   ::decode(snapshot_id, it);
330 }
331
332 void GroupSnapshotNamespace::dump(Formatter *f) const {
333   f->dump_int("group_pool", group_pool);
334   f->dump_string("group_id", group_id);
335   f->dump_int("snapshot_id", snapshot_id);
336 }
337
338 class EncodeSnapshotNamespaceVisitor : public boost::static_visitor<void> {
339 public:
340   explicit EncodeSnapshotNamespaceVisitor(bufferlist &bl) : m_bl(bl) {
341   }
342
343   template <typename T>
344   inline void operator()(const T& t) const {
345     ::encode(static_cast<uint32_t>(T::SNAPSHOT_NAMESPACE_TYPE), m_bl);
346     t.encode(m_bl);
347   }
348
349 private:
350   bufferlist &m_bl;
351 };
352
353 class DecodeSnapshotNamespaceVisitor : public boost::static_visitor<void> {
354 public:
355   DecodeSnapshotNamespaceVisitor(bufferlist::iterator &iter)
356     : m_iter(iter) {
357   }
358
359   template <typename T>
360   inline void operator()(T& t) const {
361     t.decode(m_iter);
362   }
363 private:
364   bufferlist::iterator &m_iter;
365 };
366
367 class DumpSnapshotNamespaceVisitor : public boost::static_visitor<void> {
368 public:
369   explicit DumpSnapshotNamespaceVisitor(Formatter *formatter, const std::string &key)
370     : m_formatter(formatter), m_key(key) {}
371
372   template <typename T>
373   inline void operator()(const T& t) const {
374     auto type = T::SNAPSHOT_NAMESPACE_TYPE;
375     m_formatter->dump_string(m_key.c_str(), stringify(type));
376     t.dump(m_formatter);
377   }
378 private:
379   ceph::Formatter *m_formatter;
380   std::string m_key;
381 };
382
383 class GetTypeVisitor : public boost::static_visitor<SnapshotNamespaceType> {
384 public:
385   template <typename T>
386   inline SnapshotNamespaceType operator()(const T&) const {
387     return static_cast<SnapshotNamespaceType>(T::SNAPSHOT_NAMESPACE_TYPE);
388   }
389 };
390
391
392 SnapshotNamespaceType SnapshotNamespaceOnDisk::get_namespace_type() const {
393   return static_cast<SnapshotNamespaceType>(boost::apply_visitor(GetTypeVisitor(),
394                                                                  snapshot_namespace));
395 }
396
397 void SnapshotNamespaceOnDisk::encode(bufferlist& bl) const {
398   ENCODE_START(1, 1, bl);
399   boost::apply_visitor(EncodeSnapshotNamespaceVisitor(bl), snapshot_namespace);
400   ENCODE_FINISH(bl);
401 }
402
403 void SnapshotNamespaceOnDisk::decode(bufferlist::iterator &p)
404 {
405   DECODE_START(1, p);
406   uint32_t snap_type;
407   ::decode(snap_type, p);
408   switch (snap_type) {
409     case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_USER:
410       snapshot_namespace = UserSnapshotNamespace();
411       break;
412     case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_GROUP:
413       snapshot_namespace = GroupSnapshotNamespace();
414       break;
415     default:
416       snapshot_namespace = UnknownSnapshotNamespace();
417       break;
418   }
419   boost::apply_visitor(DecodeSnapshotNamespaceVisitor(p), snapshot_namespace);
420   DECODE_FINISH(p);
421 }
422
423 void SnapshotNamespaceOnDisk::dump(Formatter *f) const {
424   boost::apply_visitor(DumpSnapshotNamespaceVisitor(f, "snapshot_namespace_type"), snapshot_namespace);
425 }
426
427 void SnapshotNamespaceOnDisk::generate_test_instances(std::list<SnapshotNamespaceOnDisk *> &o) {
428   o.push_back(new SnapshotNamespaceOnDisk(UserSnapshotNamespace()));
429   o.push_back(new SnapshotNamespaceOnDisk(GroupSnapshotNamespace(0, "10152ae8944a", 1)));
430   o.push_back(new SnapshotNamespaceOnDisk(GroupSnapshotNamespace(5, "1018643c9869", 3)));
431 }
432
433 std::ostream& operator<<(std::ostream& os, const UserSnapshotNamespace& ns) {
434   os << "[user]";
435   return os;
436 }
437
438 std::ostream& operator<<(std::ostream& os, const GroupSnapshotNamespace& ns) {
439   os << "[group"
440      << " group_pool=" << ns.group_pool
441      << " group_id=" << ns.group_id
442      << " snapshot_id=" << ns.snapshot_id << "]";
443   return os;
444 }
445
446 std::ostream& operator<<(std::ostream& os, const UnknownSnapshotNamespace& ns) {
447   os << "[unknown]";
448   return os;
449 }
450
451 void TrashImageSpec::encode(bufferlist& bl) const {
452   ENCODE_START(1, 1, bl);
453   ::encode(source, bl);
454   ::encode(name, bl);
455   ::encode(deletion_time, bl);
456   ::encode(deferment_end_time, bl);
457   ENCODE_FINISH(bl);
458 }
459
460 void TrashImageSpec::decode(bufferlist::iterator &it) {
461   DECODE_START(1, it);
462   ::decode(source, it);
463   ::decode(name, it);
464   ::decode(deletion_time, it);
465   ::decode(deferment_end_time, it);
466   DECODE_FINISH(it);
467 }
468
469 void TrashImageSpec::dump(Formatter *f) const {
470   switch(source) {
471     case TRASH_IMAGE_SOURCE_USER:
472       f->dump_string("source", "user");
473       break;
474     case TRASH_IMAGE_SOURCE_MIRRORING:
475       f->dump_string("source", "rbd_mirror");
476   }
477   f->dump_string("name", name);
478   f->dump_unsigned("deletion_time", deletion_time);
479   f->dump_unsigned("deferment_end_time", deferment_end_time);
480 }
481
482 } // namespace rbd
483 } // namespace cls