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 #ifndef _INCLUDED_RBD_REPLAY_ACTIONS_HPP
16 #define _INCLUDED_RBD_REPLAY_ACTIONS_HPP
18 #include <boost/shared_ptr.hpp>
19 #include "include/rbd/librbd.hpp"
20 #include "common/Formatter.h"
21 #include "rbd_replay/ActionTypes.h"
22 #include "rbd_loc.hpp"
25 // Stupid Doxygen requires this or else the typedef docs don't appear anywhere.
26 /// @file rbd_replay/actions.hpp
28 namespace rbd_replay {
30 typedef uint64_t imagectx_id_t;
31 typedef uint64_t thread_id_t;
33 /// Even IDs are normal actions, odd IDs are completions.
34 typedef uint32_t action_id_t;
39 %Context through which an Action interacts with its environment.
43 virtual ~ActionCtx() {
47 Returns the image with the given ID.
48 The image must have been previously tracked with put_image(imagectx_id_t,librbd::Image*).
50 virtual librbd::Image* get_image(imagectx_id_t imagectx_id) = 0;
54 put_image(imagectx_id_t,librbd::Image*) must not have been called previously with the same ID,
55 and the image must not be NULL.
57 virtual void put_image(imagectx_id_t imagectx_id, librbd::Image* image) = 0;
60 Stops tracking an Image and release it.
61 This deletes the C++ object, not the image itself.
62 The image must have been previously tracked with put_image(imagectx_id_t,librbd::Image*).
64 virtual void erase_image(imagectx_id_t imagectx_id) = 0;
66 virtual librbd::RBD* rbd() = 0;
68 virtual librados::IoCtx* ioctx() = 0;
70 virtual void add_pending(boost::shared_ptr<PendingIO> io) = 0;
72 virtual bool readonly() const = 0;
74 virtual void remove_pending(boost::shared_ptr<PendingIO> io) = 0;
76 virtual void set_action_complete(action_id_t id) = 0;
78 virtual void stop() = 0;
81 Maps an image name from the name in the original trace to the name that should be used when replaying.
82 @param image_name name of the image in the original trace
83 @param snap_name name of the snap in the orginal trace
84 @return image name to replay against
86 virtual rbd_loc map_image_name(std::string image_name, std::string snap_name) const = 0;
91 Performs an %IO or a maintenance action such as starting or stopping a thread.
92 Actions are read from a replay file and scheduled by Replayer.
93 Corresponds to the IO class, except that Actions are executed by rbd-replay,
94 and IOs are used by rbd-replay-prep for processing the raw trace.
98 typedef boost::shared_ptr<Action> ptr;
103 virtual void perform(ActionCtx &ctx) = 0;
105 /// Returns the ID of the completion corresponding to this action.
106 action_id_t pending_io_id() {
110 // There's probably a better way to do this, but oh well.
111 virtual bool is_start_thread() {
115 virtual action_id_t id() const = 0;
116 virtual thread_id_t thread_id() const = 0;
117 virtual const action::Dependencies& predecessors() const = 0;
119 virtual std::ostream& dump(std::ostream& o) const = 0;
121 static ptr construct(const action::ActionEntry &action_entry);
124 template <typename ActionType>
125 class TypedAction : public Action {
127 explicit TypedAction(const ActionType &action) : m_action(action) {
130 action_id_t id() const override {
134 thread_id_t thread_id() const override {
135 return m_action.thread_id;
138 const action::Dependencies& predecessors() const override {
139 return m_action.dependencies;
142 std::ostream& dump(std::ostream& o) const override {
143 o << get_action_name() << ": ";
144 ceph::JSONFormatter formatter(false);
145 formatter.open_object_section("");
146 m_action.dump(&formatter);
147 formatter.close_section();
153 const ActionType m_action;
155 virtual const char *get_action_name() const = 0;
158 /// Writes human-readable debug information about the action to the stream.
160 std::ostream& operator<<(std::ostream& o, const Action& a);
162 class StartThreadAction : public TypedAction<action::StartThreadAction> {
164 explicit StartThreadAction(const action::StartThreadAction &action)
165 : TypedAction<action::StartThreadAction>(action) {
168 bool is_start_thread() override {
171 void perform(ActionCtx &ctx) override;
174 const char *get_action_name() const override {
175 return "StartThreadAction";
179 class StopThreadAction : public TypedAction<action::StopThreadAction> {
181 explicit StopThreadAction(const action::StopThreadAction &action)
182 : TypedAction<action::StopThreadAction>(action) {
185 void perform(ActionCtx &ctx) override;
188 const char *get_action_name() const override {
189 return "StartThreadAction";
194 class AioReadAction : public TypedAction<action::AioReadAction> {
196 explicit AioReadAction(const action::AioReadAction &action)
197 : TypedAction<action::AioReadAction>(action) {
200 void perform(ActionCtx &ctx) override;
203 const char *get_action_name() const override {
204 return "AioReadAction";
209 class ReadAction : public TypedAction<action::ReadAction> {
211 explicit ReadAction(const action::ReadAction &action)
212 : TypedAction<action::ReadAction>(action) {
215 void perform(ActionCtx &ctx) override;
218 const char *get_action_name() const override {
224 class AioWriteAction : public TypedAction<action::AioWriteAction> {
226 explicit AioWriteAction(const action::AioWriteAction &action)
227 : TypedAction<action::AioWriteAction>(action) {
230 void perform(ActionCtx &ctx) override;
233 const char *get_action_name() const override {
234 return "AioWriteAction";
239 class WriteAction : public TypedAction<action::WriteAction> {
241 explicit WriteAction(const action::WriteAction &action)
242 : TypedAction<action::WriteAction>(action) {
245 void perform(ActionCtx &ctx) override;
248 const char *get_action_name() const override {
249 return "WriteAction";
254 class AioDiscardAction : public TypedAction<action::AioDiscardAction> {
256 explicit AioDiscardAction(const action::AioDiscardAction &action)
257 : TypedAction<action::AioDiscardAction>(action) {
260 void perform(ActionCtx &ctx) override;
263 const char *get_action_name() const override {
264 return "AioDiscardAction";
269 class DiscardAction : public TypedAction<action::DiscardAction> {
271 explicit DiscardAction(const action::DiscardAction &action)
272 : TypedAction<action::DiscardAction>(action) {
275 void perform(ActionCtx &ctx) override;
278 const char *get_action_name() const override {
279 return "DiscardAction";
284 class OpenImageAction : public TypedAction<action::OpenImageAction> {
286 explicit OpenImageAction(const action::OpenImageAction &action)
287 : TypedAction<action::OpenImageAction>(action) {
290 void perform(ActionCtx &ctx) override;
293 const char *get_action_name() const override {
294 return "OpenImageAction";
299 class CloseImageAction : public TypedAction<action::CloseImageAction> {
301 explicit CloseImageAction(const action::CloseImageAction &action)
302 : TypedAction<action::CloseImageAction>(action) {
305 void perform(ActionCtx &ctx) override;
308 const char *get_action_name() const override {
309 return "CloseImageAction";
313 class AioOpenImageAction : public TypedAction<action::AioOpenImageAction> {
315 explicit AioOpenImageAction(const action::AioOpenImageAction &action)
316 : TypedAction<action::AioOpenImageAction>(action) {
319 void perform(ActionCtx &ctx) override;
322 const char *get_action_name() const override {
323 return "AioOpenImageAction";
328 class AioCloseImageAction : public TypedAction<action::AioCloseImageAction> {
330 explicit AioCloseImageAction(const action::AioCloseImageAction &action)
331 : TypedAction<action::AioCloseImageAction>(action) {
334 void perform(ActionCtx &ctx) override;
337 const char *get_action_name() const override {
338 return "AioCloseImageAction";