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::const_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);
(1) Event overrun-buffer-val: Overrunning buffer pointed to by "__u8 const(static_cast<uint8_t>(this->state))" of 1 bytes by passing it to a function which accesses it at byte offset 7. [details]
81   	  encode(static_cast<uint8_t>(state), bl);
82   	  ENCODE_FINISH(bl);
83   	}
84   	
85   	void MirrorImage::decode(bufferlist::const_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::const_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 ParentImageSpec::encode(bufferlist& bl) const {
216  	  ENCODE_START(1, 1, bl);
217  	  encode(pool_id, bl);
218  	  encode(pool_namespace, bl);
219  	  encode(image_id, bl);
220  	  encode(snap_id, bl);
221  	  ENCODE_FINISH(bl);
222  	}
223  	
224  	void ParentImageSpec::decode(bufferlist::const_iterator& bl) {
225  	  DECODE_START(1, bl);
226  	  decode(pool_id, bl);
227  	  decode(pool_namespace, bl);
228  	  decode(image_id, bl);
229  	  decode(snap_id, bl);
230  	  DECODE_FINISH(bl);
231  	}
232  	
233  	void ParentImageSpec::dump(Formatter *f) const {
234  	  f->dump_int("pool_id", pool_id);
235  	  f->dump_string("pool_namespace", pool_namespace);
236  	  f->dump_string("image_id", image_id);
237  	  f->dump_unsigned("snap_id", snap_id);
238  	}
239  	
240  	void ParentImageSpec::generate_test_instances(std::list<ParentImageSpec*>& o) {
241  	  o.push_back(new ParentImageSpec{});
242  	  o.push_back(new ParentImageSpec{1, "", "foo", 3});
243  	  o.push_back(new ParentImageSpec{1, "ns", "foo", 3});
244  	}
245  	
246  	void ChildImageSpec::encode(bufferlist &bl) const {
247  	  ENCODE_START(2, 1, bl);
248  	  encode(pool_id, bl);
249  	  encode(image_id, bl);
250  	  encode(pool_namespace, bl);
251  	  ENCODE_FINISH(bl);
252  	}
253  	
254  	void ChildImageSpec::decode(bufferlist::const_iterator &it) {
255  	  DECODE_START(2, it);
256  	  decode(pool_id, it);
257  	  decode(image_id, it);
258  	  if (struct_v >= 2) {
259  	    decode(pool_namespace, it);
260  	  }
261  	  DECODE_FINISH(it);
262  	}
263  	
264  	void ChildImageSpec::dump(Formatter *f) const {
265  	  f->dump_int("pool_id", pool_id);
266  	  f->dump_string("pool_namespace", pool_namespace);
267  	  f->dump_string("image_id", image_id);
268  	}
269  	
270  	void ChildImageSpec::generate_test_instances(std::list<ChildImageSpec*> &o) {
271  	  o.push_back(new ChildImageSpec());
272  	  o.push_back(new ChildImageSpec(123, "", "abc"));
273  	  o.push_back(new ChildImageSpec(123, "ns", "abc"));
274  	}
275  	
276  	void GroupImageSpec::encode(bufferlist &bl) const {
277  	  ENCODE_START(1, 1, bl);
278  	  encode(image_id, bl);
279  	  encode(pool_id, bl);
280  	  ENCODE_FINISH(bl);
281  	}
282  	
283  	void GroupImageSpec::decode(bufferlist::const_iterator &it) {
284  	  DECODE_START(1, it);
285  	  decode(image_id, it);
286  	  decode(pool_id, it);
287  	  DECODE_FINISH(it);
288  	}
289  	
290  	void GroupImageSpec::dump(Formatter *f) const {
291  	  f->dump_string("image_id", image_id);
292  	  f->dump_int("pool_id", pool_id);
293  	}
294  	
295  	int GroupImageSpec::from_key(const std::string &image_key,
296  					    GroupImageSpec *spec) {
297  	  if (nullptr == spec) return -EINVAL;
298  	  int prefix_len = cls::rbd::RBD_GROUP_IMAGE_KEY_PREFIX.size();
299  	  std::string data_string = image_key.substr(prefix_len,
300  						     image_key.size() - prefix_len);
301  	  size_t p = data_string.find("_");
302  	  if (std::string::npos == p) {
303  	    return -EIO;
304  	  }
305  	  data_string[p] = ' ';
306  	
307  	  istringstream iss(data_string);
308  	  uint64_t pool_id;
309  	  string image_id;
310  	  iss >> std::hex >> pool_id >> image_id;
311  	
312  	  spec->image_id = image_id;
313  	  spec->pool_id = pool_id;
314  	  return 0;
315  	}
316  	
317  	std::string GroupImageSpec::image_key() {
318  	  if (-1 == pool_id)
319  	    return "";
320  	  else {
321  	    ostringstream oss;
322  	    oss << RBD_GROUP_IMAGE_KEY_PREFIX << std::setw(16)
323  		<< std::setfill('0') << std::hex << pool_id << "_" << image_id;
324  	    return oss.str();
325  	  }
326  	}
327  	
328  	void GroupImageSpec::generate_test_instances(std::list<GroupImageSpec*> &o) {
329  	  o.push_back(new GroupImageSpec("10152ae8944a", 0));
330  	  o.push_back(new GroupImageSpec("1018643c9869", 3));
331  	}
332  	
333  	void GroupImageStatus::encode(bufferlist &bl) const {
334  	  ENCODE_START(1, 1, bl);
335  	  encode(spec, bl);
336  	  encode(state, bl);
337  	  ENCODE_FINISH(bl);
338  	}
339  	
340  	void GroupImageStatus::decode(bufferlist::const_iterator &it) {
341  	  DECODE_START(1, it);
342  	  decode(spec, it);
343  	  decode(state, it);
344  	  DECODE_FINISH(it);
345  	}
346  	
347  	std::string GroupImageStatus::state_to_string() const {
348  	  std::stringstream ss;
349  	  if (state == GROUP_IMAGE_LINK_STATE_INCOMPLETE) {
350  	    ss << "incomplete";
351  	  }
352  	  if (state == GROUP_IMAGE_LINK_STATE_ATTACHED) {
353  	    ss << "attached";
354  	  }
355  	  return ss.str();
356  	}
357  	
358  	void GroupImageStatus::dump(Formatter *f) const {
359  	  spec.dump(f);
360  	  f->dump_string("state", state_to_string());
361  	}
362  	
363  	void GroupImageStatus::generate_test_instances(std::list<GroupImageStatus*> &o) {
364  	  o.push_back(new GroupImageStatus(GroupImageSpec("10152ae8944a", 0), GROUP_IMAGE_LINK_STATE_ATTACHED));
365  	  o.push_back(new GroupImageStatus(GroupImageSpec("1018643c9869", 3), GROUP_IMAGE_LINK_STATE_ATTACHED));
366  	  o.push_back(new GroupImageStatus(GroupImageSpec("10152ae8944a", 0), GROUP_IMAGE_LINK_STATE_INCOMPLETE));
367  	  o.push_back(new GroupImageStatus(GroupImageSpec("1018643c9869", 3), GROUP_IMAGE_LINK_STATE_INCOMPLETE));
368  	}
369  	
370  	
371  	void GroupSpec::encode(bufferlist &bl) const {
372  	  ENCODE_START(1, 1, bl);
373  	  encode(pool_id, bl);
374  	  encode(group_id, bl);
375  	  ENCODE_FINISH(bl);
376  	}
377  	
378  	void GroupSpec::decode(bufferlist::const_iterator &it) {
379  	  DECODE_START(1, it);
380  	  decode(pool_id, it);
381  	  decode(group_id, it);
382  	  DECODE_FINISH(it);
383  	}
384  	
385  	void GroupSpec::dump(Formatter *f) const {
386  	  f->dump_string("group_id", group_id);
387  	  f->dump_int("pool_id", pool_id);
388  	}
389  	
390  	bool GroupSpec::is_valid() const {
391  	  return (!group_id.empty()) && (pool_id != -1);
392  	}
393  	
394  	void GroupSpec::generate_test_instances(std::list<GroupSpec *> &o) {
395  	  o.push_back(new GroupSpec("10152ae8944a", 0));
396  	  o.push_back(new GroupSpec("1018643c9869", 3));
397  	}
398  	
399  	void GroupSnapshotNamespace::encode(bufferlist& bl) const {
400  	  using ceph::encode;
401  	  encode(group_pool, bl);
402  	  encode(group_id, bl);
403  	  encode(group_snapshot_id, bl);
404  	}
405  	
406  	void GroupSnapshotNamespace::decode(bufferlist::const_iterator& it) {
407  	  using ceph::decode;
408  	  decode(group_pool, it);
409  	  decode(group_id, it);
410  	  decode(group_snapshot_id, it);
411  	}
412  	
413  	void GroupSnapshotNamespace::dump(Formatter *f) const {
414  	  f->dump_int("group_pool", group_pool);
415  	  f->dump_string("group_id", group_id);
416  	  f->dump_string("group_snapshot_id", group_snapshot_id);
417  	}
418  	
419  	void TrashSnapshotNamespace::encode(bufferlist& bl) const {
420  	  using ceph::encode;
421  	  encode(original_name, bl);
422  	  encode(static_cast<uint32_t>(original_snapshot_namespace_type), bl);
423  	}
424  	
425  	void TrashSnapshotNamespace::decode(bufferlist::const_iterator& it) {
426  	  using ceph::decode;
427  	  decode(original_name, it);
428  	  uint32_t snap_type;
429  	  decode(snap_type, it);
430  	  original_snapshot_namespace_type = static_cast<SnapshotNamespaceType>(
431  	    snap_type);
432  	}
433  	
434  	void TrashSnapshotNamespace::dump(Formatter *f) const {
435  	  f->dump_string("original_name", original_name);
436  	  f->dump_stream("original_snapshot_namespace")
437  	    << original_snapshot_namespace_type;
438  	}
439  	
440  	class EncodeSnapshotNamespaceVisitor : public boost::static_visitor<void> {
441  	public:
442  	  explicit EncodeSnapshotNamespaceVisitor(bufferlist &bl) : m_bl(bl) {
443  	  }
444  	
445  	  template <typename T>
446  	  inline void operator()(const T& t) const {
447  	    using ceph::encode;
448  	    encode(static_cast<uint32_t>(T::SNAPSHOT_NAMESPACE_TYPE), m_bl);
449  	    t.encode(m_bl);
450  	  }
451  	
452  	private:
453  	  bufferlist &m_bl;
454  	};
455  	
456  	class DecodeSnapshotNamespaceVisitor : public boost::static_visitor<void> {
457  	public:
458  	  DecodeSnapshotNamespaceVisitor(bufferlist::const_iterator &iter)
459  	    : m_iter(iter) {
460  	  }
461  	
462  	  template <typename T>
463  	  inline void operator()(T& t) const {
464  	    t.decode(m_iter);
465  	  }
466  	private:
467  	  bufferlist::const_iterator &m_iter;
468  	};
469  	
470  	class DumpSnapshotNamespaceVisitor : public boost::static_visitor<void> {
471  	public:
472  	  explicit DumpSnapshotNamespaceVisitor(Formatter *formatter, const std::string &key)
473  	    : m_formatter(formatter), m_key(key) {}
474  	
475  	  template <typename T>
476  	  inline void operator()(const T& t) const {
477  	    auto type = T::SNAPSHOT_NAMESPACE_TYPE;
478  	    m_formatter->dump_string(m_key.c_str(), stringify(type));
479  	    t.dump(m_formatter);
480  	  }
481  	private:
482  	  ceph::Formatter *m_formatter;
483  	  std::string m_key;
484  	};
485  	
486  	class GetTypeVisitor : public boost::static_visitor<SnapshotNamespaceType> {
487  	public:
488  	  template <typename T>
489  	  inline SnapshotNamespaceType operator()(const T&) const {
490  	    return static_cast<SnapshotNamespaceType>(T::SNAPSHOT_NAMESPACE_TYPE);
491  	  }
492  	};
493  	
494  	SnapshotNamespaceType get_snap_namespace_type(
495  	    const SnapshotNamespace& snapshot_namespace) {
496  	  return static_cast<SnapshotNamespaceType>(boost::apply_visitor(
497  	    GetTypeVisitor(), snapshot_namespace));
498  	}
499  	
500  	void SnapshotInfo::encode(bufferlist& bl) const {
501  	  ENCODE_START(1, 1, bl);
502  	  encode(id, bl);
503  	  encode(snapshot_namespace, bl);
504  	  encode(name, bl);
505  	  encode(image_size, bl);
506  	  encode(timestamp, bl);
507  	  encode(child_count, bl);
508  	  ENCODE_FINISH(bl);
509  	}
510  	
511  	void SnapshotInfo::decode(bufferlist::const_iterator& it) {
512  	  DECODE_START(1, it);
513  	  decode(id, it);
514  	  decode(snapshot_namespace, it);
515  	  decode(name, it);
516  	  decode(image_size, it);
517  	  decode(timestamp, it);
518  	  decode(child_count, it);
519  	  DECODE_FINISH(it);
520  	}
521  	
522  	void SnapshotInfo::dump(Formatter *f) const {
523  	  f->dump_unsigned("id", id);
524  	  f->open_object_section("namespace");
525  	  boost::apply_visitor(DumpSnapshotNamespaceVisitor(f, "type"),
526  	                       snapshot_namespace);
527  	  f->close_section();
528  	  f->dump_string("name", name);
529  	  f->dump_unsigned("image_size", image_size);
530  	  f->dump_stream("timestamp") << timestamp;
531  	}
532  	
533  	void SnapshotInfo::generate_test_instances(std::list<SnapshotInfo*> &o) {
534  	  o.push_back(new SnapshotInfo(1ULL, UserSnapshotNamespace{}, "snap1", 123,
535  	                               {123456, 0}, 12));
536  	  o.push_back(new SnapshotInfo(2ULL,
537  	                               GroupSnapshotNamespace{567, "group1", "snap1"},
538  	                               "snap1", 123, {123456, 0}, 987));
539  	  o.push_back(new SnapshotInfo(3ULL,
540  	                               TrashSnapshotNamespace{
541  	                                 SNAPSHOT_NAMESPACE_TYPE_USER, "snap1"},
542  	                               "12345", 123, {123456, 0}, 429));
543  	}
544  	
545  	void SnapshotNamespace::encode(bufferlist& bl) const {
546  	  ENCODE_START(1, 1, bl);
547  	  boost::apply_visitor(EncodeSnapshotNamespaceVisitor(bl), *this);
548  	  ENCODE_FINISH(bl);
549  	}
550  	
551  	void SnapshotNamespace::decode(bufferlist::const_iterator &p)
552  	{
553  	  DECODE_START(1, p);
554  	  uint32_t snap_type;
555  	  decode(snap_type, p);
556  	  switch (snap_type) {
557  	    case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_USER:
558  	      *this = UserSnapshotNamespace();
559  	      break;
560  	    case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_GROUP:
561  	      *this = GroupSnapshotNamespace();
562  	      break;
563  	    case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_TRASH:
564  	      *this = TrashSnapshotNamespace();
565  	      break;
566  	    default:
567  	      *this = UnknownSnapshotNamespace();
568  	      break;
569  	  }
570  	  boost::apply_visitor(DecodeSnapshotNamespaceVisitor(p), *this);
571  	  DECODE_FINISH(p);
572  	}
573  	
574  	void SnapshotNamespace::dump(Formatter *f) const {
575  	  boost::apply_visitor(
576  	    DumpSnapshotNamespaceVisitor(f, "snapshot_namespace_type"), *this);
577  	}
578  	
579  	void SnapshotNamespace::generate_test_instances(std::list<SnapshotNamespace*> &o) {
580  	  o.push_back(new SnapshotNamespace(UserSnapshotNamespace()));
581  	  o.push_back(new SnapshotNamespace(GroupSnapshotNamespace(0, "10152ae8944a",
582  	                                                           "2118643c9732")));
583  	  o.push_back(new SnapshotNamespace(GroupSnapshotNamespace(5, "1018643c9869",
584  	                                                           "33352be8933c")));
585  	  o.push_back(new SnapshotNamespace(TrashSnapshotNamespace()));
586  	}
587  	
588  	std::ostream& operator<<(std::ostream& os, const SnapshotNamespaceType& type) {
589  	  switch (type) {
590  	  case SNAPSHOT_NAMESPACE_TYPE_USER:
591  	    os << "user";
592  	    break;
593  	  case SNAPSHOT_NAMESPACE_TYPE_GROUP:
594  	    os << "group";
595  	    break;
596  	  case SNAPSHOT_NAMESPACE_TYPE_TRASH:
597  	    os << "trash";
598  	    break;
599  	  default:
600  	    os << "unknown";
601  	    break;
602  	  }
603  	  return os;
604  	}
605  	
606  	std::ostream& operator<<(std::ostream& os, const UserSnapshotNamespace& ns) {
607  	  os << "[" << SNAPSHOT_NAMESPACE_TYPE_USER << "]";
608  	  return os;
609  	}
610  	
611  	std::ostream& operator<<(std::ostream& os, const GroupSnapshotNamespace& ns) {
612  	  os << "[" << SNAPSHOT_NAMESPACE_TYPE_GROUP << " "
613  	     << "group_pool=" << ns.group_pool << ", "
614  	     << "group_id=" << ns.group_id << ", "
615  	     << "group_snapshot_id=" << ns.group_snapshot_id << "]";
616  	  return os;
617  	}
618  	
619  	std::ostream& operator<<(std::ostream& os, const TrashSnapshotNamespace& ns) {
620  	  os << "[" << SNAPSHOT_NAMESPACE_TYPE_TRASH << " "
621  	     << "original_name=" << ns.original_name << ", "
622  	     << "original_snapshot_namespace=" << ns.original_snapshot_namespace_type
623  	     << "]";
624  	  return os;
625  	}
626  	
627  	std::ostream& operator<<(std::ostream& os, const UnknownSnapshotNamespace& ns) {
628  	  os << "[unknown]";
629  	  return os;
630  	}
631  	
632  	void ImageSnapshotSpec::encode(bufferlist& bl) const {
633  	  using ceph::encode;
634  	  ENCODE_START(1, 1, bl);
635  	  encode(pool, bl);
636  	  encode(image_id, bl);
637  	  encode(snap_id, bl);
638  	  ENCODE_FINISH(bl);
639  	}
640  	
641  	void ImageSnapshotSpec::decode(bufferlist::const_iterator& it) {
642  	  using ceph::decode;
643  	  DECODE_START(1, it);
644  	  decode(pool, it);
645  	  decode(image_id, it);
646  	  decode(snap_id, it);
647  	  DECODE_FINISH(it);
648  	}
649  	
650  	void ImageSnapshotSpec::dump(Formatter *f) const {
651  	  f->dump_int("pool", pool);
652  	  f->dump_string("image_id", image_id);
653  	  f->dump_int("snap_id", snap_id);
654  	}
655  	
656  	void ImageSnapshotSpec::generate_test_instances(std::list<ImageSnapshotSpec *> &o) {
657  	  o.push_back(new ImageSnapshotSpec(0, "myimage", 2));
658  	  o.push_back(new ImageSnapshotSpec(1, "testimage", 7));
659  	}
660  	
661  	void GroupSnapshot::encode(bufferlist& bl) const {
662  	  using ceph::encode;
663  	  ENCODE_START(1, 1, bl);
664  	  encode(id, bl);
665  	  encode(name, bl);
666  	  encode(state, bl);
667  	  encode(snaps, bl);
668  	  ENCODE_FINISH(bl);
669  	}
670  	
671  	void GroupSnapshot::decode(bufferlist::const_iterator& it) {
672  	  using ceph::decode;
673  	  DECODE_START(1, it);
674  	  decode(id, it);
675  	  decode(name, it);
676  	  decode(state, it);
677  	  decode(snaps, it);
678  	  DECODE_FINISH(it);
679  	}
680  	
681  	void GroupSnapshot::dump(Formatter *f) const {
682  	  f->dump_string("id", id);
683  	  f->dump_string("name", name);
684  	  f->dump_int("state", state);
685  	}
686  	
687  	void GroupSnapshot::generate_test_instances(std::list<GroupSnapshot *> &o) {
688  	  o.push_back(new GroupSnapshot("10152ae8944a", "groupsnapshot1", GROUP_SNAPSHOT_STATE_INCOMPLETE));
689  	  o.push_back(new GroupSnapshot("1018643c9869", "groupsnapshot2", GROUP_SNAPSHOT_STATE_COMPLETE));
690  	}
691  	void TrashImageSpec::encode(bufferlist& bl) const {
692  	  ENCODE_START(2, 1, bl);
693  	  encode(source, bl);
694  	  encode(name, bl);
695  	  encode(deletion_time, bl);
696  	  encode(deferment_end_time, bl);
697  	  encode(state, bl);
698  	  ENCODE_FINISH(bl);
699  	}
700  	
701  	void TrashImageSpec::decode(bufferlist::const_iterator &it) {
702  	  DECODE_START(2, it);
703  	  decode(source, it);
704  	  decode(name, it);
705  	  decode(deletion_time, it);
706  	  decode(deferment_end_time, it);
707  	  if (struct_v >= 2) {
708  	    decode(state, it);
709  	  }
710  	  DECODE_FINISH(it);
711  	}
712  	
713  	void TrashImageSpec::dump(Formatter *f) const {
714  	  f->dump_stream("source") << source;
715  	  f->dump_string("name", name);
716  	  f->dump_unsigned("deletion_time", deletion_time);
717  	  f->dump_unsigned("deferment_end_time", deferment_end_time);
718  	}
719  	
720  	void MirrorImageMap::encode(bufferlist &bl) const {
721  	  ENCODE_START(1, 1, bl);
722  	  encode(instance_id, bl);
723  	  encode(mapped_time, bl);
724  	  encode(data, bl);
725  	  ENCODE_FINISH(bl);
726  	}
727  	
728  	void MirrorImageMap::decode(bufferlist::const_iterator &it) {
729  	  DECODE_START(1, it);
730  	  decode(instance_id, it);
731  	  decode(mapped_time, it);
732  	  decode(data, it);
733  	  DECODE_FINISH(it);
734  	}
735  	
736  	void MirrorImageMap::dump(Formatter *f) const {
737  	  f->dump_string("instance_id", instance_id);
738  	  f->dump_stream("mapped_time") << mapped_time;
739  	
740  	  std::stringstream data_ss;
741  	  data.hexdump(data_ss);
742  	  f->dump_string("data", data_ss.str());
743  	}
744  	
745  	void MirrorImageMap::generate_test_instances(
746  	  std::list<MirrorImageMap*> &o) {
747  	  bufferlist data;
748  	  data.append(std::string(128, '1'));
749  	
750  	  o.push_back(new MirrorImageMap("uuid-123", utime_t(), data));
751  	  o.push_back(new MirrorImageMap("uuid-abc", utime_t(), data));
752  	}
753  	
754  	bool MirrorImageMap::operator==(const MirrorImageMap &rhs) const {
755  	  return instance_id == rhs.instance_id && mapped_time == rhs.mapped_time &&
756  	    data.contents_equal(rhs.data);
757  	}
758  	
759  	bool MirrorImageMap::operator<(const MirrorImageMap &rhs) const {
760  	  return instance_id < rhs.instance_id ||
761  	        (instance_id == rhs.instance_id && mapped_time < rhs.mapped_time);
762  	}
763  	
764  	std::ostream& operator<<(std::ostream& os,
765  	                         const MirrorImageMap &image_map) {
766  	  return os << "[" << "instance_id=" << image_map.instance_id << ", mapped_time="
767  	            << image_map.mapped_time << "]";
768  	}
769  	
770  	std::ostream& operator<<(std::ostream& os,
771  	                         const MigrationHeaderType& type) {
772  	  switch (type) {
773  	  case MIGRATION_HEADER_TYPE_SRC:
774  	    os << "source";
775  	    break;
776  	  case MIGRATION_HEADER_TYPE_DST:
777  	    os << "destination";
778  	    break;
779  	  default:
780  	    os << "unknown (" << static_cast<uint32_t>(type) << ")";
781  	    break;
782  	  }
783  	  return os;
784  	}
785  	
786  	std::ostream& operator<<(std::ostream& os,
787  	                         const MigrationState& migration_state) {
788  	  switch (migration_state) {
789  	  case MIGRATION_STATE_ERROR:
790  	    os << "error";
791  	    break;
792  	  case MIGRATION_STATE_PREPARING:
793  	    os << "preparing";
794  	    break;
795  	  case MIGRATION_STATE_PREPARED:
796  	    os << "prepared";
797  	    break;
798  	  case MIGRATION_STATE_EXECUTING:
799  	    os << "executing";
800  	    break;
801  	  case MIGRATION_STATE_EXECUTED:
802  	    os << "executed";
803  	    break;
804  	  default:
805  	    os << "unknown (" << static_cast<uint32_t>(migration_state) << ")";
806  	    break;
807  	  }
808  	  return os;
809  	}
810  	
811  	void MigrationSpec::encode(bufferlist& bl) const {
812  	  ENCODE_START(1, 1, bl);
813  	  encode(header_type, bl);
814  	  encode(pool_id, bl);
815  	  encode(pool_namespace, bl);
816  	  encode(image_name, bl);
817  	  encode(image_id, bl);
818  	  encode(snap_seqs, bl);
819  	  encode(overlap, bl);
820  	  encode(flatten, bl);
821  	  encode(mirroring, bl);
822  	  encode(state, bl);
823  	  encode(state_description, bl);
824  	  ENCODE_FINISH(bl);
825  	}
826  	
827  	void MigrationSpec::decode(bufferlist::const_iterator& bl) {
828  	  DECODE_START(1, bl);
829  	  decode(header_type, bl);
830  	  decode(pool_id, bl);
831  	  decode(pool_namespace, bl);
832  	  decode(image_name, bl);
833  	  decode(image_id, bl);
834  	  decode(snap_seqs, bl);
835  	  decode(overlap, bl);
836  	  decode(flatten, bl);
837  	  decode(mirroring, bl);
838  	  decode(state, bl);
839  	  decode(state_description, bl);
840  	  DECODE_FINISH(bl);
841  	}
842  	
843  	std::ostream& operator<<(std::ostream& os,
844  	                         const std::map<uint64_t, uint64_t>& snap_seqs) {
845  	  os << "{";
846  	  size_t count = 0;
847  	  for (auto &it : snap_seqs) {
848  	    os << (count++ > 0 ? ", " : "") << "(" << it.first << ", " << it.second
849  	       << ")";
850  	  }
851  	  os << "}";
852  	  return os;
853  	}
854  	
855  	void MigrationSpec::dump(Formatter *f) const {
856  	  f->dump_stream("header_type") << header_type;
857  	  f->dump_int("pool_id", pool_id);
858  	  f->dump_string("pool_namespace", pool_namespace);
859  	  f->dump_string("image_name", image_name);
860  	  f->dump_string("image_id", image_id);
861  	  f->dump_stream("snap_seqs") << snap_seqs;
862  	  f->dump_unsigned("overlap", overlap);
863  	  f->dump_bool("mirroring", mirroring);
864  	}
865  	
866  	void MigrationSpec::generate_test_instances(std::list<MigrationSpec*> &o) {
867  	  o.push_back(new MigrationSpec());
868  	  o.push_back(new MigrationSpec(MIGRATION_HEADER_TYPE_SRC, 1, "ns",
869  	                                "image_name", "image_id", {{1, 2}}, 123, true,
870  	                                true, MIGRATION_STATE_PREPARED, "description"));
871  	}
872  	
873  	std::ostream& operator<<(std::ostream& os,
874  	                         const MigrationSpec& migration_spec) {
875  	  os << "["
876  	     << "header_type=" << migration_spec.header_type << ", "
877  	     << "pool_id=" << migration_spec.pool_id << ", "
878  	     << "pool_namespace=" << migration_spec.pool_namespace << ", "
879  	     << "image_name=" << migration_spec.image_name << ", "
880  	     << "image_id=" << migration_spec.image_id << ", "
881  	     << "snap_seqs=" << migration_spec.snap_seqs << ", "
882  	     << "overlap=" << migration_spec.overlap << ", "
883  	     << "flatten=" << migration_spec.flatten << ", "
884  	     << "mirroring=" << migration_spec.mirroring << ", "
885  	     << "state=" << migration_spec.state << ", "
886  	     << "state_description=" << migration_spec.state_description << "]";
887  	  return os;
888  	}
889  	
890  	std::ostream& operator<<(std::ostream& os, const AssertSnapcSeqState& state) {
891  	  switch (state) {
892  	  case ASSERT_SNAPC_SEQ_GT_SNAPSET_SEQ:
893  	    os << "gt";
894  	    break;
895  	  case ASSERT_SNAPC_SEQ_LE_SNAPSET_SEQ:
896  	    os << "le";
897  	    break;
898  	  default:
899  	    os << "unknown (" << static_cast<uint32_t>(state) << ")";
900  	    break;
901  	  }
902  	  return os;
903  	}
904  	
905  	} // namespace rbd
906  	} // namespace cls
907