X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Frbd_replay%2FActionTypes.cc;fp=src%2Fceph%2Fsrc%2Frbd_replay%2FActionTypes.cc;h=eed19fcec1ae370e71a19c36587cf9ad4d93bdc7;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/rbd_replay/ActionTypes.cc b/src/ceph/src/rbd_replay/ActionTypes.cc new file mode 100644 index 0000000..eed19fc --- /dev/null +++ b/src/ceph/src/rbd_replay/ActionTypes.cc @@ -0,0 +1,417 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "rbd_replay/ActionTypes.h" +#include "include/assert.h" +#include "include/byteorder.h" +#include "include/stringify.h" +#include "common/Formatter.h" +#include +#include + +namespace rbd_replay { +namespace action { + +namespace { + +bool byte_swap_required(__u8 version) { +#if defined(CEPH_LITTLE_ENDIAN) + return (version == 0); +#else + return false; +#endif +} + +void decode_big_endian_string(std::string &str, bufferlist::iterator &it) { +#if defined(CEPH_LITTLE_ENDIAN) + uint32_t length; + ::decode(length, it); + length = swab(length); + str.clear(); + it.copy(length, str); +#else + assert(false); +#endif +} + +class EncodeVisitor : public boost::static_visitor { +public: + explicit EncodeVisitor(bufferlist &bl) : m_bl(bl) { + } + + template + inline void operator()(const Action &action) const { + ::encode(static_cast(Action::ACTION_TYPE), m_bl); + action.encode(m_bl); + } +private: + bufferlist &m_bl; +}; + +class DecodeVisitor : public boost::static_visitor { +public: + DecodeVisitor(__u8 version, bufferlist::iterator &iter) + : m_version(version), m_iter(iter) { + } + + template + inline void operator()(Action &action) const { + action.decode(m_version, m_iter); + } +private: + __u8 m_version; + bufferlist::iterator &m_iter; +}; + +class DumpVisitor : public boost::static_visitor { +public: + explicit DumpVisitor(Formatter *formatter) : m_formatter(formatter) {} + + template + inline void operator()(const Action &action) const { + ActionType action_type = Action::ACTION_TYPE; + m_formatter->dump_string("action_type", stringify(action_type)); + action.dump(m_formatter); + } +private: + ceph::Formatter *m_formatter; +}; + +} // anonymous namespace + +void Dependency::encode(bufferlist &bl) const { + ::encode(id, bl); + ::encode(time_delta, bl); +} + +void Dependency::decode(bufferlist::iterator &it) { + decode(1, it); +} + +void Dependency::decode(__u8 version, bufferlist::iterator &it) { + ::decode(id, it); + ::decode(time_delta, it); + if (byte_swap_required(version)) { + id = swab(id); + time_delta = swab(time_delta); + } +} + +void Dependency::dump(Formatter *f) const { + f->dump_unsigned("id", id); + f->dump_unsigned("time_delta", time_delta); +} + +void Dependency::generate_test_instances(std::list &o) { + o.push_back(new Dependency()); + o.push_back(new Dependency(1, 123456789)); +} + +void ActionBase::encode(bufferlist &bl) const { + ::encode(id, bl); + ::encode(thread_id, bl); + ::encode(dependencies, bl); +} + +void ActionBase::decode(__u8 version, bufferlist::iterator &it) { + ::decode(id, it); + ::decode(thread_id, it); + if (version == 0) { + uint32_t num_successors; + ::decode(num_successors, it); + + uint32_t num_completion_successors; + ::decode(num_completion_successors, it); + } + + if (byte_swap_required(version)) { + id = swab(id); + thread_id = swab(thread_id); + + uint32_t dep_count; + ::decode(dep_count, it); + dep_count = swab(dep_count); + dependencies.resize(dep_count); + for (uint32_t i = 0; i < dep_count; ++i) { + dependencies[i].decode(0, it); + } + } else { + ::decode(dependencies, it); + } +} + +void ActionBase::dump(Formatter *f) const { + f->dump_unsigned("id", id); + f->dump_unsigned("thread_id", thread_id); + f->open_array_section("dependencies"); + for (size_t i = 0; i < dependencies.size(); ++i) { + f->open_object_section("dependency"); + dependencies[i].dump(f); + f->close_section(); + } + f->close_section(); +} + +void ImageActionBase::encode(bufferlist &bl) const { + ActionBase::encode(bl); + ::encode(imagectx_id, bl); +} + +void ImageActionBase::decode(__u8 version, bufferlist::iterator &it) { + ActionBase::decode(version, it); + ::decode(imagectx_id, it); + if (byte_swap_required(version)) { + imagectx_id = swab(imagectx_id); + } +} + +void ImageActionBase::dump(Formatter *f) const { + ActionBase::dump(f); + f->dump_unsigned("imagectx_id", imagectx_id); +} + +void IoActionBase::encode(bufferlist &bl) const { + ImageActionBase::encode(bl); + ::encode(offset, bl); + ::encode(length, bl); +} + +void IoActionBase::decode(__u8 version, bufferlist::iterator &it) { + ImageActionBase::decode(version, it); + ::decode(offset, it); + ::decode(length, it); + if (byte_swap_required(version)) { + offset = swab(offset); + length = swab(length); + } +} + +void IoActionBase::dump(Formatter *f) const { + ImageActionBase::dump(f); + f->dump_unsigned("offset", offset); + f->dump_unsigned("length", length); +} + +void OpenImageAction::encode(bufferlist &bl) const { + ImageActionBase::encode(bl); + ::encode(name, bl); + ::encode(snap_name, bl); + ::encode(read_only, bl); +} + +void OpenImageAction::decode(__u8 version, bufferlist::iterator &it) { + ImageActionBase::decode(version, it); + if (byte_swap_required(version)) { + decode_big_endian_string(name, it); + decode_big_endian_string(snap_name, it); + } else { + ::decode(name, it); + ::decode(snap_name, it); + } + ::decode(read_only, it); +} + +void OpenImageAction::dump(Formatter *f) const { + ImageActionBase::dump(f); + f->dump_string("name", name); + f->dump_string("snap_name", snap_name); + f->dump_bool("read_only", read_only); +} + +void AioOpenImageAction::encode(bufferlist &bl) const { + ImageActionBase::encode(bl); + ::encode(name, bl); + ::encode(snap_name, bl); + ::encode(read_only, bl); +} + +void AioOpenImageAction::decode(__u8 version, bufferlist::iterator &it) { + ImageActionBase::decode(version, it); + if (byte_swap_required(version)) { + decode_big_endian_string(name, it); + decode_big_endian_string(snap_name, it); + } else { + ::decode(name, it); + ::decode(snap_name, it); + } + ::decode(read_only, it); +} + +void AioOpenImageAction::dump(Formatter *f) const { + ImageActionBase::dump(f); + f->dump_string("name", name); + f->dump_string("snap_name", snap_name); + f->dump_bool("read_only", read_only); +} + +void UnknownAction::encode(bufferlist &bl) const { + assert(false); +} + +void UnknownAction::decode(__u8 version, bufferlist::iterator &it) { +} + +void UnknownAction::dump(Formatter *f) const { +} + +void ActionEntry::encode(bufferlist &bl) const { + ENCODE_START(1, 1, bl); + boost::apply_visitor(EncodeVisitor(bl), action); + ENCODE_FINISH(bl); +} + +void ActionEntry::decode(bufferlist::iterator &it) { + DECODE_START(1, it); + decode(struct_v, it); + DECODE_FINISH(it); +} + +void ActionEntry::decode_unversioned(bufferlist::iterator &it) { + decode(0, it); +} + +void ActionEntry::decode(__u8 version, bufferlist::iterator &it) { + uint8_t action_type; + ::decode(action_type, it); + + // select the correct action variant based upon the action_type + switch (action_type) { + case ACTION_TYPE_START_THREAD: + action = StartThreadAction(); + break; + case ACTION_TYPE_STOP_THREAD: + action = StopThreadAction(); + break; + case ACTION_TYPE_READ: + action = ReadAction(); + break; + case ACTION_TYPE_WRITE: + action = WriteAction(); + break; + case ACTION_TYPE_DISCARD: + action = DiscardAction(); + break; + case ACTION_TYPE_AIO_READ: + action = AioReadAction(); + break; + case ACTION_TYPE_AIO_WRITE: + action = AioWriteAction(); + break; + case ACTION_TYPE_AIO_DISCARD: + action = AioDiscardAction(); + break; + case ACTION_TYPE_OPEN_IMAGE: + action = OpenImageAction(); + break; + case ACTION_TYPE_CLOSE_IMAGE: + action = CloseImageAction(); + break; + case ACTION_TYPE_AIO_OPEN_IMAGE: + action = AioOpenImageAction(); + break; + case ACTION_TYPE_AIO_CLOSE_IMAGE: + action = AioCloseImageAction(); + break; + } + + boost::apply_visitor(DecodeVisitor(version, it), action); +} + +void ActionEntry::dump(Formatter *f) const { + boost::apply_visitor(DumpVisitor(f), action); +} + +void ActionEntry::generate_test_instances(std::list &o) { + Dependencies dependencies; + dependencies.push_back(Dependency(3, 123456789)); + dependencies.push_back(Dependency(4, 234567890)); + + o.push_back(new ActionEntry(StartThreadAction())); + o.push_back(new ActionEntry(StartThreadAction(1, 123456789, dependencies))); + o.push_back(new ActionEntry(StopThreadAction())); + o.push_back(new ActionEntry(StopThreadAction(1, 123456789, dependencies))); + + o.push_back(new ActionEntry(ReadAction())); + o.push_back(new ActionEntry(ReadAction(1, 123456789, dependencies, 3, 4, 5))); + o.push_back(new ActionEntry(WriteAction())); + o.push_back(new ActionEntry(WriteAction(1, 123456789, dependencies, 3, 4, + 5))); + o.push_back(new ActionEntry(DiscardAction())); + o.push_back(new ActionEntry(DiscardAction(1, 123456789, dependencies, 3, 4, + 5))); + o.push_back(new ActionEntry(AioReadAction())); + o.push_back(new ActionEntry(AioReadAction(1, 123456789, dependencies, 3, 4, + 5))); + o.push_back(new ActionEntry(AioWriteAction())); + o.push_back(new ActionEntry(AioWriteAction(1, 123456789, dependencies, 3, 4, + 5))); + o.push_back(new ActionEntry(AioDiscardAction())); + o.push_back(new ActionEntry(AioDiscardAction(1, 123456789, dependencies, 3, 4, + 5))); + + o.push_back(new ActionEntry(OpenImageAction())); + o.push_back(new ActionEntry(OpenImageAction(1, 123456789, dependencies, 3, + "image_name", "snap_name", + true))); + o.push_back(new ActionEntry(CloseImageAction())); + o.push_back(new ActionEntry(CloseImageAction(1, 123456789, dependencies, 3))); + + o.push_back(new ActionEntry(AioOpenImageAction())); + o.push_back(new ActionEntry(AioOpenImageAction(1, 123456789, dependencies, 3, + "image_name", "snap_name", + true))); + o.push_back(new ActionEntry(AioCloseImageAction())); + o.push_back(new ActionEntry(AioCloseImageAction(1, 123456789, dependencies, 3))); +} + +} // namespace action +} // namespace rbd_replay + +std::ostream &operator<<(std::ostream &out, + const rbd_replay::action::ActionType &type) { + using namespace rbd_replay::action; + + switch (type) { + case ACTION_TYPE_START_THREAD: + out << "StartThread"; + break; + case ACTION_TYPE_STOP_THREAD: + out << "StopThread"; + break; + case ACTION_TYPE_READ: + out << "Read"; + break; + case ACTION_TYPE_WRITE: + out << "Write"; + break; + case ACTION_TYPE_DISCARD: + out << "Discard"; + break; + case ACTION_TYPE_AIO_READ: + out << "AioRead"; + break; + case ACTION_TYPE_AIO_WRITE: + out << "AioWrite"; + break; + case ACTION_TYPE_AIO_DISCARD: + out << "AioDiscard"; + break; + case ACTION_TYPE_OPEN_IMAGE: + out << "OpenImage"; + break; + case ACTION_TYPE_CLOSE_IMAGE: + out << "CloseImage"; + break; + case ACTION_TYPE_AIO_OPEN_IMAGE: + out << "AioOpenImage"; + break; + case ACTION_TYPE_AIO_CLOSE_IMAGE: + out << "AioCloseImage"; + break; + default: + out << "Unknown (" << static_cast(type) << ")"; + break; + } + return out; +} +