summaryrefslogtreecommitdiffstats
path: root/src/rbd_replay/actions.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rbd_replay/actions.hpp')
-rw-r--r--src/rbd_replay/actions.hpp344
1 files changed, 344 insertions, 0 deletions
diff --git a/src/rbd_replay/actions.hpp b/src/rbd_replay/actions.hpp
new file mode 100644
index 000000000..89e483158
--- /dev/null
+++ b/src/rbd_replay/actions.hpp
@@ -0,0 +1,344 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2014 Adam Crume <adamcrume@gmail.com>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#ifndef _INCLUDED_RBD_REPLAY_ACTIONS_HPP
+#define _INCLUDED_RBD_REPLAY_ACTIONS_HPP
+
+#include <boost/shared_ptr.hpp>
+#include "include/rbd/librbd.hpp"
+#include "common/Formatter.h"
+#include "rbd_replay/ActionTypes.h"
+#include "rbd_loc.hpp"
+#include <iostream>
+
+// Stupid Doxygen requires this or else the typedef docs don't appear anywhere.
+/// @file rbd_replay/actions.hpp
+
+namespace rbd_replay {
+
+typedef uint64_t imagectx_id_t;
+typedef uint64_t thread_id_t;
+
+/// Even IDs are normal actions, odd IDs are completions.
+typedef uint32_t action_id_t;
+
+class PendingIO;
+
+/**
+ %Context through which an Action interacts with its environment.
+ */
+class ActionCtx {
+public:
+ virtual ~ActionCtx() {
+ }
+
+ /**
+ Returns the image with the given ID.
+ The image must have been previously tracked with put_image(imagectx_id_t,librbd::Image*).
+ */
+ virtual librbd::Image* get_image(imagectx_id_t imagectx_id) = 0;
+
+ /**
+ Tracks an image.
+ put_image(imagectx_id_t,librbd::Image*) must not have been called previously with the same ID,
+ and the image must not be NULL.
+ */
+ virtual void put_image(imagectx_id_t imagectx_id, librbd::Image* image) = 0;
+
+ /**
+ Stops tracking an Image and release it.
+ This deletes the C++ object, not the image itself.
+ The image must have been previously tracked with put_image(imagectx_id_t,librbd::Image*).
+ */
+ virtual void erase_image(imagectx_id_t imagectx_id) = 0;
+
+ virtual librbd::RBD* rbd() = 0;
+
+ virtual librados::IoCtx* ioctx() = 0;
+
+ virtual void add_pending(boost::shared_ptr<PendingIO> io) = 0;
+
+ virtual bool readonly() const = 0;
+
+ virtual void remove_pending(boost::shared_ptr<PendingIO> io) = 0;
+
+ virtual void set_action_complete(action_id_t id) = 0;
+
+ virtual void stop() = 0;
+
+ /**
+ Maps an image name from the name in the original trace to the name that should be used when replaying.
+ @param image_name name of the image in the original trace
+ @param snap_name name of the snap in the original trace
+ @return image name to replay against
+ */
+ virtual rbd_loc map_image_name(std::string image_name, std::string snap_name) const = 0;
+};
+
+
+/**
+ Performs an %IO or a maintenance action such as starting or stopping a thread.
+ Actions are read from a replay file and scheduled by Replayer.
+ Corresponds to the IO class, except that Actions are executed by rbd-replay,
+ and IOs are used by rbd-replay-prep for processing the raw trace.
+ */
+class Action {
+public:
+ typedef boost::shared_ptr<Action> ptr;
+
+ virtual ~Action() {
+ }
+
+ virtual void perform(ActionCtx &ctx) = 0;
+
+ /// Returns the ID of the completion corresponding to this action.
+ action_id_t pending_io_id() {
+ return id() + 1;
+ }
+
+ // There's probably a better way to do this, but oh well.
+ virtual bool is_start_thread() {
+ return false;
+ }
+
+ virtual action_id_t id() const = 0;
+ virtual thread_id_t thread_id() const = 0;
+ virtual const action::Dependencies& predecessors() const = 0;
+
+ virtual std::ostream& dump(std::ostream& o) const = 0;
+
+ static ptr construct(const action::ActionEntry &action_entry);
+};
+
+template <typename ActionType>
+class TypedAction : public Action {
+public:
+ explicit TypedAction(const ActionType &action) : m_action(action) {
+ }
+
+ action_id_t id() const override {
+ return m_action.id;
+ }
+
+ thread_id_t thread_id() const override {
+ return m_action.thread_id;
+ }
+
+ const action::Dependencies& predecessors() const override {
+ return m_action.dependencies;
+ }
+
+ std::ostream& dump(std::ostream& o) const override {
+ o << get_action_name() << ": ";
+ ceph::JSONFormatter formatter(false);
+ formatter.open_object_section("");
+ m_action.dump(&formatter);
+ formatter.close_section();
+ formatter.flush(o);
+ return o;
+ }
+
+protected:
+ const ActionType m_action;
+
+ virtual const char *get_action_name() const = 0;
+};
+
+/// Writes human-readable debug information about the action to the stream.
+/// @related Action
+std::ostream& operator<<(std::ostream& o, const Action& a);
+
+class StartThreadAction : public TypedAction<action::StartThreadAction> {
+public:
+ explicit StartThreadAction(const action::StartThreadAction &action)
+ : TypedAction<action::StartThreadAction>(action) {
+ }
+
+ bool is_start_thread() override {
+ return true;
+ }
+ void perform(ActionCtx &ctx) override;
+
+protected:
+ const char *get_action_name() const override {
+ return "StartThreadAction";
+ }
+};
+
+class StopThreadAction : public TypedAction<action::StopThreadAction> {
+public:
+ explicit StopThreadAction(const action::StopThreadAction &action)
+ : TypedAction<action::StopThreadAction>(action) {
+ }
+
+ void perform(ActionCtx &ctx) override;
+
+protected:
+ const char *get_action_name() const override {
+ return "StartThreadAction";
+ }
+};
+
+
+class AioReadAction : public TypedAction<action::AioReadAction> {
+public:
+ explicit AioReadAction(const action::AioReadAction &action)
+ : TypedAction<action::AioReadAction>(action) {
+ }
+
+ void perform(ActionCtx &ctx) override;
+
+protected:
+ const char *get_action_name() const override {
+ return "AioReadAction";
+ }
+};
+
+
+class ReadAction : public TypedAction<action::ReadAction> {
+public:
+ explicit ReadAction(const action::ReadAction &action)
+ : TypedAction<action::ReadAction>(action) {
+ }
+
+ void perform(ActionCtx &ctx) override;
+
+protected:
+ const char *get_action_name() const override {
+ return "ReadAction";
+ }
+};
+
+
+class AioWriteAction : public TypedAction<action::AioWriteAction> {
+public:
+ explicit AioWriteAction(const action::AioWriteAction &action)
+ : TypedAction<action::AioWriteAction>(action) {
+ }
+
+ void perform(ActionCtx &ctx) override;
+
+protected:
+ const char *get_action_name() const override {
+ return "AioWriteAction";
+ }
+};
+
+
+class WriteAction : public TypedAction<action::WriteAction> {
+public:
+ explicit WriteAction(const action::WriteAction &action)
+ : TypedAction<action::WriteAction>(action) {
+ }
+
+ void perform(ActionCtx &ctx) override;
+
+protected:
+ const char *get_action_name() const override {
+ return "WriteAction";
+ }
+};
+
+
+class AioDiscardAction : public TypedAction<action::AioDiscardAction> {
+public:
+ explicit AioDiscardAction(const action::AioDiscardAction &action)
+ : TypedAction<action::AioDiscardAction>(action) {
+ }
+
+ void perform(ActionCtx &ctx) override;
+
+protected:
+ const char *get_action_name() const override {
+ return "AioDiscardAction";
+ }
+};
+
+
+class DiscardAction : public TypedAction<action::DiscardAction> {
+public:
+ explicit DiscardAction(const action::DiscardAction &action)
+ : TypedAction<action::DiscardAction>(action) {
+ }
+
+ void perform(ActionCtx &ctx) override;
+
+protected:
+ const char *get_action_name() const override {
+ return "DiscardAction";
+ }
+};
+
+
+class OpenImageAction : public TypedAction<action::OpenImageAction> {
+public:
+ explicit OpenImageAction(const action::OpenImageAction &action)
+ : TypedAction<action::OpenImageAction>(action) {
+ }
+
+ void perform(ActionCtx &ctx) override;
+
+protected:
+ const char *get_action_name() const override {
+ return "OpenImageAction";
+ }
+};
+
+
+class CloseImageAction : public TypedAction<action::CloseImageAction> {
+public:
+ explicit CloseImageAction(const action::CloseImageAction &action)
+ : TypedAction<action::CloseImageAction>(action) {
+ }
+
+ void perform(ActionCtx &ctx) override;
+
+protected:
+ const char *get_action_name() const override {
+ return "CloseImageAction";
+ }
+};
+
+class AioOpenImageAction : public TypedAction<action::AioOpenImageAction> {
+public:
+ explicit AioOpenImageAction(const action::AioOpenImageAction &action)
+ : TypedAction<action::AioOpenImageAction>(action) {
+ }
+
+ void perform(ActionCtx &ctx) override;
+
+protected:
+ const char *get_action_name() const override {
+ return "AioOpenImageAction";
+ }
+};
+
+
+class AioCloseImageAction : public TypedAction<action::AioCloseImageAction> {
+public:
+ explicit AioCloseImageAction(const action::AioCloseImageAction &action)
+ : TypedAction<action::AioCloseImageAction>(action) {
+ }
+
+ void perform(ActionCtx &ctx) override;
+
+protected:
+ const char *get_action_name() const override {
+ return "AioCloseImageAction";
+ }
+};
+
+}
+
+#endif