summaryrefslogtreecommitdiffstats
path: root/src/rbd_replay/Replayer.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rbd_replay/Replayer.hpp')
-rw-r--r--src/rbd_replay/Replayer.hpp167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/rbd_replay/Replayer.hpp b/src/rbd_replay/Replayer.hpp
new file mode 100644
index 000000000..ddbd05743
--- /dev/null
+++ b/src/rbd_replay/Replayer.hpp
@@ -0,0 +1,167 @@
+// -*- 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_REPLAYER_HPP
+#define _INCLUDED_RBD_REPLAY_REPLAYER_HPP
+
+#include <chrono>
+#include <mutex>
+#include <thread>
+#include <condition_variable>
+#include "rbd_replay/ActionTypes.h"
+#include "BoundedBuffer.hpp"
+#include "ImageNameMap.hpp"
+#include "PendingIO.hpp"
+
+namespace rbd_replay {
+
+class Replayer;
+
+/**
+ Performs Actions within a single thread.
+ */
+class Worker : public ActionCtx {
+public:
+ explicit Worker(Replayer &replayer);
+
+ void start();
+
+ /// Should only be called by StopThreadAction
+ void stop() override;
+
+ void join();
+
+ void send(Action::ptr action);
+
+ void add_pending(PendingIO::ptr io) override;
+
+ void remove_pending(PendingIO::ptr io) override;
+
+ librbd::Image* get_image(imagectx_id_t imagectx_id) override;
+
+ void put_image(imagectx_id_t imagectx_id, librbd::Image* image) override;
+
+ void erase_image(imagectx_id_t imagectx_id) override;
+
+ librbd::RBD* rbd() override;
+
+ librados::IoCtx* ioctx() override;
+
+ void set_action_complete(action_id_t id) override;
+
+ bool readonly() const override;
+
+ rbd_loc map_image_name(std::string image_name, std::string snap_name) const override;
+
+private:
+ void run();
+
+ Replayer &m_replayer;
+ BoundedBuffer<Action::ptr> m_buffer;
+ std::shared_ptr<std::thread> m_thread;
+ std::map<action_id_t, PendingIO::ptr> m_pending_ios;
+ std::mutex m_pending_ios_mutex;
+ std::condition_variable_any m_pending_ios_empty;
+ bool m_done;
+};
+
+
+class Replayer {
+public:
+ explicit Replayer(int num_action_trackers);
+
+ ~Replayer();
+
+ void run(const std::string &replay_file);
+
+ librbd::RBD* get_rbd() {
+ return m_rbd;
+ }
+
+ librados::IoCtx* get_ioctx() {
+ return m_ioctx;
+ }
+
+ librbd::Image* get_image(imagectx_id_t imagectx_id);
+
+ void put_image(imagectx_id_t imagectx_id, librbd::Image *image);
+
+ void erase_image(imagectx_id_t imagectx_id);
+
+ void set_action_complete(action_id_t id);
+
+ bool is_action_complete(action_id_t id);
+
+ void wait_for_actions(const action::Dependencies &deps);
+
+ std::string pool_name() const;
+
+ void set_pool_name(std::string pool_name);
+
+ void set_latency_multiplier(float f);
+
+ bool readonly() const;
+
+ void set_readonly(bool readonly);
+
+ void set_image_name_map(const ImageNameMap &map) {
+ m_image_name_map = map;
+ }
+
+ void set_dump_perf_counters(bool dump_perf_counters) {
+ m_dump_perf_counters = dump_perf_counters;
+ }
+
+ const ImageNameMap &image_name_map() const {
+ return m_image_name_map;
+ }
+
+private:
+ struct action_tracker_d {
+ /// Maps an action ID to the time the action completed
+ std::map<action_id_t, std::chrono::system_clock::time_point> actions;
+ std::shared_mutex mutex;
+ std::condition_variable_any condition;
+ };
+
+ void clear_images();
+
+ action_tracker_d &tracker_for(action_id_t id);
+
+ /// Disallow copying
+ Replayer(const Replayer& rhs);
+ /// Disallow assignment
+ const Replayer& operator=(const Replayer& rhs);
+
+ librbd::RBD* m_rbd;
+ librados::IoCtx* m_ioctx;
+ std::string m_pool_name;
+ float m_latency_multiplier;
+ bool m_readonly;
+ ImageNameMap m_image_name_map;
+ bool m_dump_perf_counters;
+
+ std::map<imagectx_id_t, librbd::Image*> m_images;
+ std::shared_mutex m_images_mutex;
+
+ /// Actions are hashed across the trackers by ID.
+ /// Number of trackers should probably be larger than the number of cores and prime.
+ /// Should definitely be odd.
+ const int m_num_action_trackers;
+ action_tracker_d* m_action_trackers;
+};
+
+}
+
+#endif