Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / rbd_replay / ActionTypes.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 "rbd_replay/ActionTypes.h"
5 #include "include/assert.h"
6 #include "include/byteorder.h"
7 #include "include/stringify.h"
8 #include "common/Formatter.h"
9 #include <iostream>
10 #include <boost/variant.hpp>
11
12 namespace rbd_replay {
13 namespace action {
14
15 namespace {
16
17 bool byte_swap_required(__u8 version) {
18 #if defined(CEPH_LITTLE_ENDIAN)
19   return (version == 0);
20 #else
21   return false;
22 #endif
23 }
24
25 void decode_big_endian_string(std::string &str, bufferlist::iterator &it) {
26 #if defined(CEPH_LITTLE_ENDIAN)
27   uint32_t length;
28   ::decode(length, it);
29   length = swab(length);
30   str.clear();
31   it.copy(length, str);
32 #else
33   assert(false);
34 #endif
35 }
36
37 class EncodeVisitor : public boost::static_visitor<void> {
38 public:
39   explicit EncodeVisitor(bufferlist &bl) : m_bl(bl) {
40   }
41
42   template <typename Action>
43   inline void operator()(const Action &action) const {
44     ::encode(static_cast<uint8_t>(Action::ACTION_TYPE), m_bl);
45     action.encode(m_bl);
46   }
47 private:
48   bufferlist &m_bl;
49 };
50
51 class DecodeVisitor : public boost::static_visitor<void> {
52 public:
53   DecodeVisitor(__u8 version, bufferlist::iterator &iter)
54     : m_version(version), m_iter(iter) {
55   }
56
57   template <typename Action>
58   inline void operator()(Action &action) const {
59     action.decode(m_version, m_iter);
60   }
61 private:
62   __u8 m_version;
63   bufferlist::iterator &m_iter;
64 };
65
66 class DumpVisitor : public boost::static_visitor<void> {
67 public:
68   explicit DumpVisitor(Formatter *formatter) : m_formatter(formatter) {}
69
70   template <typename Action>
71   inline void operator()(const Action &action) const {
72     ActionType action_type = Action::ACTION_TYPE;
73     m_formatter->dump_string("action_type", stringify(action_type));
74     action.dump(m_formatter);
75   }
76 private:
77   ceph::Formatter *m_formatter;
78 };
79
80 } // anonymous namespace
81
82 void Dependency::encode(bufferlist &bl) const {
83   ::encode(id, bl);
84   ::encode(time_delta, bl);
85 }
86
87 void Dependency::decode(bufferlist::iterator &it) {
88   decode(1, it);
89 }
90
91 void Dependency::decode(__u8 version, bufferlist::iterator &it) {
92   ::decode(id, it);
93   ::decode(time_delta, it);
94   if (byte_swap_required(version)) {
95     id = swab(id);
96     time_delta = swab(time_delta);
97   }
98 }
99
100 void Dependency::dump(Formatter *f) const {
101   f->dump_unsigned("id", id);
102   f->dump_unsigned("time_delta", time_delta);
103 }
104
105 void Dependency::generate_test_instances(std::list<Dependency *> &o) {
106   o.push_back(new Dependency());
107   o.push_back(new Dependency(1, 123456789));
108 }
109
110 void ActionBase::encode(bufferlist &bl) const {
111   ::encode(id, bl);
112   ::encode(thread_id, bl);
113   ::encode(dependencies, bl);
114 }
115
116 void ActionBase::decode(__u8 version, bufferlist::iterator &it) {
117   ::decode(id, it);
118   ::decode(thread_id, it);
119   if (version == 0) {
120     uint32_t num_successors;
121     ::decode(num_successors, it);
122
123     uint32_t num_completion_successors;
124     ::decode(num_completion_successors, it);
125   }
126
127   if (byte_swap_required(version)) {
128     id = swab(id);
129     thread_id = swab(thread_id);
130
131     uint32_t dep_count;
132     ::decode(dep_count, it);
133     dep_count = swab(dep_count);
134     dependencies.resize(dep_count);
135     for (uint32_t i = 0; i < dep_count; ++i) {
136       dependencies[i].decode(0, it);
137     }
138   } else {
139     ::decode(dependencies, it);
140   }
141 }
142
143 void ActionBase::dump(Formatter *f) const {
144   f->dump_unsigned("id", id);
145   f->dump_unsigned("thread_id", thread_id);
146   f->open_array_section("dependencies");
147   for (size_t i = 0; i < dependencies.size(); ++i) {
148     f->open_object_section("dependency");
149     dependencies[i].dump(f);
150     f->close_section();
151   }
152   f->close_section();
153 }
154
155 void ImageActionBase::encode(bufferlist &bl) const {
156   ActionBase::encode(bl);
157   ::encode(imagectx_id, bl);
158 }
159
160 void ImageActionBase::decode(__u8 version, bufferlist::iterator &it) {
161   ActionBase::decode(version, it);
162   ::decode(imagectx_id, it);
163   if (byte_swap_required(version)) {
164     imagectx_id = swab(imagectx_id);
165   }
166 }
167
168 void ImageActionBase::dump(Formatter *f) const {
169   ActionBase::dump(f);
170   f->dump_unsigned("imagectx_id", imagectx_id);
171 }
172
173 void IoActionBase::encode(bufferlist &bl) const {
174   ImageActionBase::encode(bl);
175   ::encode(offset, bl);
176   ::encode(length, bl);
177 }
178
179 void IoActionBase::decode(__u8 version, bufferlist::iterator &it) {
180   ImageActionBase::decode(version, it);
181   ::decode(offset, it);
182   ::decode(length, it);
183   if (byte_swap_required(version)) {
184     offset = swab(offset);
185     length = swab(length);
186   }
187 }
188
189 void IoActionBase::dump(Formatter *f) const {
190   ImageActionBase::dump(f);
191   f->dump_unsigned("offset", offset);
192   f->dump_unsigned("length", length);
193 }
194
195 void OpenImageAction::encode(bufferlist &bl) const {
196   ImageActionBase::encode(bl);
197   ::encode(name, bl);
198   ::encode(snap_name, bl);
199   ::encode(read_only, bl);
200 }
201
202 void OpenImageAction::decode(__u8 version, bufferlist::iterator &it) {
203   ImageActionBase::decode(version, it);
204   if (byte_swap_required(version)) {
205     decode_big_endian_string(name, it);
206     decode_big_endian_string(snap_name, it);
207   } else {
208     ::decode(name, it);
209     ::decode(snap_name, it);
210   }
211   ::decode(read_only, it);
212 }
213
214 void OpenImageAction::dump(Formatter *f) const {
215   ImageActionBase::dump(f);
216   f->dump_string("name", name);
217   f->dump_string("snap_name", snap_name);
218   f->dump_bool("read_only", read_only);
219 }
220
221 void AioOpenImageAction::encode(bufferlist &bl) const {
222   ImageActionBase::encode(bl);
223   ::encode(name, bl);
224   ::encode(snap_name, bl);
225   ::encode(read_only, bl);
226 }
227
228 void AioOpenImageAction::decode(__u8 version, bufferlist::iterator &it) {
229   ImageActionBase::decode(version, it);
230   if (byte_swap_required(version)) {
231     decode_big_endian_string(name, it);
232     decode_big_endian_string(snap_name, it);
233   } else {
234     ::decode(name, it);
235     ::decode(snap_name, it);
236   }
237   ::decode(read_only, it);
238 }
239
240 void AioOpenImageAction::dump(Formatter *f) const {
241   ImageActionBase::dump(f);
242   f->dump_string("name", name);
243   f->dump_string("snap_name", snap_name);
244   f->dump_bool("read_only", read_only);
245 }
246
247 void UnknownAction::encode(bufferlist &bl) const {
248   assert(false);
249 }
250
251 void UnknownAction::decode(__u8 version, bufferlist::iterator &it) {
252 }
253
254 void UnknownAction::dump(Formatter *f) const {
255 }
256
257 void ActionEntry::encode(bufferlist &bl) const {
258   ENCODE_START(1, 1, bl);
259   boost::apply_visitor(EncodeVisitor(bl), action);
260   ENCODE_FINISH(bl);
261 }
262
263 void ActionEntry::decode(bufferlist::iterator &it) {
264   DECODE_START(1, it);
265   decode(struct_v, it);
266   DECODE_FINISH(it);
267 }
268
269 void ActionEntry::decode_unversioned(bufferlist::iterator &it) {
270   decode(0, it);
271 }
272
273 void ActionEntry::decode(__u8 version, bufferlist::iterator &it) {
274   uint8_t action_type;
275   ::decode(action_type, it);
276
277   // select the correct action variant based upon the action_type
278   switch (action_type) {
279   case ACTION_TYPE_START_THREAD:
280     action = StartThreadAction();
281     break;
282   case ACTION_TYPE_STOP_THREAD:
283     action = StopThreadAction();
284     break;
285   case ACTION_TYPE_READ:
286     action = ReadAction();
287     break;
288   case ACTION_TYPE_WRITE:
289     action = WriteAction();
290     break;
291   case ACTION_TYPE_DISCARD:
292     action = DiscardAction();
293     break;
294   case ACTION_TYPE_AIO_READ:
295     action = AioReadAction();
296     break;
297   case ACTION_TYPE_AIO_WRITE:
298     action = AioWriteAction();
299     break;
300   case ACTION_TYPE_AIO_DISCARD:
301     action = AioDiscardAction();
302     break;
303   case ACTION_TYPE_OPEN_IMAGE:
304     action = OpenImageAction();
305     break;
306   case ACTION_TYPE_CLOSE_IMAGE:
307     action = CloseImageAction();
308     break;
309   case ACTION_TYPE_AIO_OPEN_IMAGE:
310     action = AioOpenImageAction();
311     break;
312   case ACTION_TYPE_AIO_CLOSE_IMAGE:
313     action = AioCloseImageAction();
314     break;
315   }
316
317   boost::apply_visitor(DecodeVisitor(version, it), action);
318 }
319
320 void ActionEntry::dump(Formatter *f) const {
321   boost::apply_visitor(DumpVisitor(f), action);
322 }
323
324 void ActionEntry::generate_test_instances(std::list<ActionEntry *> &o) {
325   Dependencies dependencies;
326   dependencies.push_back(Dependency(3, 123456789));
327   dependencies.push_back(Dependency(4, 234567890));
328
329   o.push_back(new ActionEntry(StartThreadAction()));
330   o.push_back(new ActionEntry(StartThreadAction(1, 123456789, dependencies)));
331   o.push_back(new ActionEntry(StopThreadAction()));
332   o.push_back(new ActionEntry(StopThreadAction(1, 123456789, dependencies)));
333
334   o.push_back(new ActionEntry(ReadAction()));
335   o.push_back(new ActionEntry(ReadAction(1, 123456789, dependencies, 3, 4, 5)));
336   o.push_back(new ActionEntry(WriteAction()));
337   o.push_back(new ActionEntry(WriteAction(1, 123456789, dependencies, 3, 4,
338                                           5)));
339   o.push_back(new ActionEntry(DiscardAction()));
340   o.push_back(new ActionEntry(DiscardAction(1, 123456789, dependencies, 3, 4,
341                                             5)));
342   o.push_back(new ActionEntry(AioReadAction()));
343   o.push_back(new ActionEntry(AioReadAction(1, 123456789, dependencies, 3, 4,
344                                             5)));
345   o.push_back(new ActionEntry(AioWriteAction()));
346   o.push_back(new ActionEntry(AioWriteAction(1, 123456789, dependencies, 3, 4,
347                                              5)));
348   o.push_back(new ActionEntry(AioDiscardAction()));
349   o.push_back(new ActionEntry(AioDiscardAction(1, 123456789, dependencies, 3, 4,
350                                                5)));
351
352   o.push_back(new ActionEntry(OpenImageAction()));
353   o.push_back(new ActionEntry(OpenImageAction(1, 123456789, dependencies, 3,
354                                               "image_name", "snap_name",
355                                               true)));
356   o.push_back(new ActionEntry(CloseImageAction()));
357   o.push_back(new ActionEntry(CloseImageAction(1, 123456789, dependencies, 3)));
358
359   o.push_back(new ActionEntry(AioOpenImageAction()));
360   o.push_back(new ActionEntry(AioOpenImageAction(1, 123456789, dependencies, 3,
361                                               "image_name", "snap_name",
362                                               true)));
363   o.push_back(new ActionEntry(AioCloseImageAction()));
364   o.push_back(new ActionEntry(AioCloseImageAction(1, 123456789, dependencies, 3)));
365 }
366
367 } // namespace action
368 } // namespace rbd_replay
369
370 std::ostream &operator<<(std::ostream &out,
371                          const rbd_replay::action::ActionType &type) {
372   using namespace rbd_replay::action;
373
374   switch (type) {
375   case ACTION_TYPE_START_THREAD:
376     out << "StartThread";
377     break;
378   case ACTION_TYPE_STOP_THREAD:
379     out << "StopThread";
380     break;
381   case ACTION_TYPE_READ:
382     out << "Read";
383     break;
384   case ACTION_TYPE_WRITE:
385     out << "Write";
386     break;
387   case ACTION_TYPE_DISCARD:
388     out << "Discard";
389     break;
390   case ACTION_TYPE_AIO_READ:
391     out << "AioRead";
392     break;
393   case ACTION_TYPE_AIO_WRITE:
394     out << "AioWrite";
395     break;
396   case ACTION_TYPE_AIO_DISCARD:
397     out << "AioDiscard";
398     break;
399   case ACTION_TYPE_OPEN_IMAGE:
400     out << "OpenImage";
401     break;
402   case ACTION_TYPE_CLOSE_IMAGE:
403     out << "CloseImage";
404     break;
405   case ACTION_TYPE_AIO_OPEN_IMAGE:
406     out << "AioOpenImage";
407     break;
408   case ACTION_TYPE_AIO_CLOSE_IMAGE:
409     out << "AioCloseImage";
410     break;
411   default:
412     out << "Unknown (" << static_cast<uint32_t>(type) << ")";
413     break;
414   }
415   return out;
416 }
417