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