]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2014 Adam Crume <adamcrume@gmail.com> | |
7 | * | |
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. | |
12 | * | |
13 | */ | |
14 | ||
15 | #ifndef _INCLUDED_RBD_REPLAY_REPLAYER_HPP | |
16 | #define _INCLUDED_RBD_REPLAY_REPLAYER_HPP | |
17 | ||
11fdf7f2 TL |
18 | #include <chrono> |
19 | #include <mutex> | |
20 | #include <thread> | |
21 | #include <condition_variable> | |
7c673cae FG |
22 | #include "rbd_replay/ActionTypes.h" |
23 | #include "BoundedBuffer.hpp" | |
24 | #include "ImageNameMap.hpp" | |
25 | #include "PendingIO.hpp" | |
26 | ||
27 | namespace rbd_replay { | |
28 | ||
29 | class Replayer; | |
30 | ||
31 | /** | |
32 | Performs Actions within a single thread. | |
33 | */ | |
34 | class Worker : public ActionCtx { | |
35 | public: | |
36 | explicit Worker(Replayer &replayer); | |
37 | ||
38 | void start(); | |
39 | ||
40 | /// Should only be called by StopThreadAction | |
41 | void stop() override; | |
42 | ||
43 | void join(); | |
44 | ||
45 | void send(Action::ptr action); | |
46 | ||
47 | void add_pending(PendingIO::ptr io) override; | |
48 | ||
49 | void remove_pending(PendingIO::ptr io) override; | |
50 | ||
51 | librbd::Image* get_image(imagectx_id_t imagectx_id) override; | |
52 | ||
53 | void put_image(imagectx_id_t imagectx_id, librbd::Image* image) override; | |
54 | ||
55 | void erase_image(imagectx_id_t imagectx_id) override; | |
56 | ||
57 | librbd::RBD* rbd() override; | |
58 | ||
59 | librados::IoCtx* ioctx() override; | |
60 | ||
61 | void set_action_complete(action_id_t id) override; | |
62 | ||
63 | bool readonly() const override; | |
64 | ||
65 | rbd_loc map_image_name(std::string image_name, std::string snap_name) const override; | |
66 | ||
67 | private: | |
68 | void run(); | |
69 | ||
70 | Replayer &m_replayer; | |
71 | BoundedBuffer<Action::ptr> m_buffer; | |
11fdf7f2 | 72 | std::shared_ptr<std::thread> m_thread; |
7c673cae | 73 | std::map<action_id_t, PendingIO::ptr> m_pending_ios; |
11fdf7f2 TL |
74 | std::mutex m_pending_ios_mutex; |
75 | std::condition_variable_any m_pending_ios_empty; | |
7c673cae FG |
76 | bool m_done; |
77 | }; | |
78 | ||
79 | ||
80 | class Replayer { | |
81 | public: | |
82 | explicit Replayer(int num_action_trackers); | |
83 | ||
84 | ~Replayer(); | |
85 | ||
86 | void run(const std::string &replay_file); | |
87 | ||
88 | librbd::RBD* get_rbd() { | |
89 | return m_rbd; | |
90 | } | |
91 | ||
92 | librados::IoCtx* get_ioctx() { | |
93 | return m_ioctx; | |
94 | } | |
95 | ||
96 | librbd::Image* get_image(imagectx_id_t imagectx_id); | |
97 | ||
98 | void put_image(imagectx_id_t imagectx_id, librbd::Image *image); | |
99 | ||
100 | void erase_image(imagectx_id_t imagectx_id); | |
101 | ||
102 | void set_action_complete(action_id_t id); | |
103 | ||
104 | bool is_action_complete(action_id_t id); | |
105 | ||
106 | void wait_for_actions(const action::Dependencies &deps); | |
107 | ||
108 | std::string pool_name() const; | |
109 | ||
110 | void set_pool_name(std::string pool_name); | |
111 | ||
112 | void set_latency_multiplier(float f); | |
113 | ||
114 | bool readonly() const; | |
115 | ||
116 | void set_readonly(bool readonly); | |
117 | ||
118 | void set_image_name_map(const ImageNameMap &map) { | |
119 | m_image_name_map = map; | |
120 | } | |
121 | ||
122 | void set_dump_perf_counters(bool dump_perf_counters) { | |
123 | m_dump_perf_counters = dump_perf_counters; | |
124 | } | |
125 | ||
126 | const ImageNameMap &image_name_map() const { | |
127 | return m_image_name_map; | |
128 | } | |
129 | ||
130 | private: | |
131 | struct action_tracker_d { | |
132 | /// Maps an action ID to the time the action completed | |
11fdf7f2 TL |
133 | std::map<action_id_t, std::chrono::system_clock::time_point> actions; |
134 | std::shared_mutex mutex; | |
135 | std::condition_variable_any condition; | |
7c673cae FG |
136 | }; |
137 | ||
138 | void clear_images(); | |
139 | ||
140 | action_tracker_d &tracker_for(action_id_t id); | |
141 | ||
142 | /// Disallow copying | |
143 | Replayer(const Replayer& rhs); | |
144 | /// Disallow assignment | |
145 | const Replayer& operator=(const Replayer& rhs); | |
146 | ||
147 | librbd::RBD* m_rbd; | |
148 | librados::IoCtx* m_ioctx; | |
149 | std::string m_pool_name; | |
150 | float m_latency_multiplier; | |
151 | bool m_readonly; | |
152 | ImageNameMap m_image_name_map; | |
153 | bool m_dump_perf_counters; | |
154 | ||
155 | std::map<imagectx_id_t, librbd::Image*> m_images; | |
11fdf7f2 | 156 | std::shared_mutex m_images_mutex; |
7c673cae FG |
157 | |
158 | /// Actions are hashed across the trackers by ID. | |
159 | /// Number of trackers should probably be larger than the number of cores and prime. | |
160 | /// Should definitely be odd. | |
161 | const int m_num_action_trackers; | |
162 | action_tracker_d* m_action_trackers; | |
163 | }; | |
164 | ||
165 | } | |
166 | ||
167 | #endif |