1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2014 Adam Crume <adamcrume@gmail.com>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 // This code assumes that IO IDs and timestamps are related monotonically.
16 // In other words, (a.id < b.id) == (a.timestamp < b.timestamp) for all IOs a and b.
19 #include "rbd_replay/ActionTypes.h"
22 using namespace rbd_replay;
26 bool compare_dependencies_by_start_time(const action::Dependency &lhs,
27 const action::Dependency &rhs) {
28 return lhs.time_delta < rhs.time_delta;
31 action::Dependencies convert_dependencies(uint64_t start_time,
32 const io_set_t &deps) {
33 action::Dependencies action_deps;
34 action_deps.reserve(deps.size());
35 for (io_set_t::const_iterator it = deps.begin(); it != deps.end(); ++it) {
36 boost::shared_ptr<IO> io = *it;
37 uint64_t time_delta = 0;
38 if (start_time >= io->start_time()) {
39 time_delta = start_time - io->start_time();
41 action_deps.push_back(action::Dependency(io->ionum(), time_delta));
43 std::sort(action_deps.begin(), action_deps.end(),
44 compare_dependencies_by_start_time);
48 } // anonymous namespace
50 void IO::write_debug_base(ostream& out, string type) const {
51 out << m_ionum << ": " << m_start_time / 1000000.0 << ": " << type << ", thread = " << m_thread_id << ", deps = {";
53 for (io_set_t::iterator itr = m_dependencies.begin(), end = m_dependencies.end(); itr != end; ++itr) {
59 out << (*itr)->m_ionum << ": " << m_start_time - (*itr)->m_start_time;
65 ostream& operator<<(ostream &out, const IO::ptr &io) {
70 void StartThreadIO::encode(bufferlist &bl) const {
71 action::Action action((action::StartThreadAction(
72 ionum(), thread_id(), convert_dependencies(start_time(), dependencies()))));
76 void StartThreadIO::write_debug(std::ostream& out) const {
77 write_debug_base(out, "start thread");
80 void StopThreadIO::encode(bufferlist &bl) const {
81 action::Action action((action::StopThreadAction(
82 ionum(), thread_id(), convert_dependencies(start_time(), dependencies()))));
86 void StopThreadIO::write_debug(std::ostream& out) const {
87 write_debug_base(out, "stop thread");
90 void ReadIO::encode(bufferlist &bl) const {
91 action::Action action((action::ReadAction(
92 ionum(), thread_id(), convert_dependencies(start_time(), dependencies()),
93 m_imagectx, m_offset, m_length)));
97 void ReadIO::write_debug(std::ostream& out) const {
98 write_debug_base(out, "read");
99 out << ", imagectx=" << m_imagectx << ", offset=" << m_offset << ", length=" << m_length << "]";
102 void WriteIO::encode(bufferlist &bl) const {
103 action::Action action((action::WriteAction(
104 ionum(), thread_id(), convert_dependencies(start_time(), dependencies()),
105 m_imagectx, m_offset, m_length)));
106 ::encode(action, bl);
109 void WriteIO::write_debug(std::ostream& out) const {
110 write_debug_base(out, "write");
111 out << ", imagectx=" << m_imagectx << ", offset=" << m_offset << ", length=" << m_length << "]";
114 void DiscardIO::encode(bufferlist &bl) const {
115 action::Action action((action::DiscardAction(
116 ionum(), thread_id(), convert_dependencies(start_time(), dependencies()),
117 m_imagectx, m_offset, m_length)));
118 ::encode(action, bl);
121 void DiscardIO::write_debug(std::ostream& out) const {
122 write_debug_base(out, "discard");
123 out << ", imagectx=" << m_imagectx << ", offset=" << m_offset << ", length=" << m_length << "]";
126 void AioReadIO::encode(bufferlist &bl) const {
127 action::Action action((action::AioReadAction(
128 ionum(), thread_id(), convert_dependencies(start_time(), dependencies()),
129 m_imagectx, m_offset, m_length)));
130 ::encode(action, bl);
133 void AioReadIO::write_debug(std::ostream& out) const {
134 write_debug_base(out, "aio read");
135 out << ", imagectx=" << m_imagectx << ", offset=" << m_offset << ", length=" << m_length << "]";
138 void AioWriteIO::encode(bufferlist &bl) const {
139 action::Action action((action::AioWriteAction(
140 ionum(), thread_id(), convert_dependencies(start_time(), dependencies()),
141 m_imagectx, m_offset, m_length)));
142 ::encode(action, bl);
145 void AioWriteIO::write_debug(std::ostream& out) const {
146 write_debug_base(out, "aio write");
147 out << ", imagectx=" << m_imagectx << ", offset=" << m_offset << ", length=" << m_length << "]";
150 void AioDiscardIO::encode(bufferlist &bl) const {
151 action::Action action((action::AioDiscardAction(
152 ionum(), thread_id(), convert_dependencies(start_time(), dependencies()),
153 m_imagectx, m_offset, m_length)));
154 ::encode(action, bl);
157 void AioDiscardIO::write_debug(std::ostream& out) const {
158 write_debug_base(out, "aio discard");
159 out << ", imagectx=" << m_imagectx << ", offset=" << m_offset << ", length=" << m_length << "]";
162 void OpenImageIO::encode(bufferlist &bl) const {
163 action::Action action((action::OpenImageAction(
164 ionum(), thread_id(), convert_dependencies(start_time(), dependencies()),
165 m_imagectx, m_name, m_snap_name, m_readonly)));
166 ::encode(action, bl);
169 void OpenImageIO::write_debug(std::ostream& out) const {
170 write_debug_base(out, "open image");
171 out << ", imagectx=" << m_imagectx << ", name='" << m_name << "', snap_name='" << m_snap_name << "', readonly=" << m_readonly;
174 void CloseImageIO::encode(bufferlist &bl) const {
175 action::Action action((action::CloseImageAction(
176 ionum(), thread_id(), convert_dependencies(start_time(), dependencies()),
178 ::encode(action, bl);
181 void CloseImageIO::write_debug(std::ostream& out) const {
182 write_debug_base(out, "close image");
183 out << ", imagectx=" << m_imagectx;
186 void AioOpenImageIO::encode(bufferlist &bl) const {
187 action::Action action((action::AioOpenImageAction(
188 ionum(), thread_id(), convert_dependencies(start_time(), dependencies()),
189 m_imagectx, m_name, m_snap_name, m_readonly)));
190 ::encode(action, bl);
193 void AioOpenImageIO::write_debug(std::ostream& out) const {
194 write_debug_base(out, "aio open image");
195 out << ", imagectx=" << m_imagectx << ", name='" << m_name << "', snap_name='" << m_snap_name << "', readonly=" << m_readonly;
198 void AioCloseImageIO::encode(bufferlist &bl) const {
199 action::Action action((action::AioCloseImageAction(
200 ionum(), thread_id(), convert_dependencies(start_time(), dependencies()),
202 ::encode(action, bl);
205 void AioCloseImageIO::write_debug(std::ostream& out) const {
206 write_debug_base(out, "aio close image");
207 out << ", imagectx=" << m_imagectx;