1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef RBD_MIRROR_IMAGE_REPLAYER_SNAPSHOT_REPLAYER_H
5 #define RBD_MIRROR_IMAGE_REPLAYER_SNAPSHOT_REPLAYER_H
7 #include "tools/rbd_mirror/image_replayer/Replayer.h"
8 #include "common/ceph_mutex.h"
9 #include "common/AsyncOpTracker.h"
10 #include "cls/rbd/cls_rbd_types.h"
11 #include "librbd/mirror/snapshot/Types.h"
12 #include "tools/rbd_mirror/image_replayer/TimeRollingMean.h"
13 #include <boost/accumulators/accumulators.hpp>
14 #include <boost/accumulators/statistics/stats.hpp>
15 #include <boost/accumulators/statistics/rolling_mean.hpp>
17 #include <type_traits>
22 namespace snapshot
{ template <typename I
> class Replay
; }
29 template <typename
> struct InstanceWatcher
;
31 template <typename
> struct Threads
;
33 namespace image_replayer
{
35 struct ReplayerListener
;
39 template <typename
> class EventPreprocessor
;
40 template <typename
> class ReplayStatusFormatter
;
41 template <typename
> class StateBuilder
;
43 template <typename ImageCtxT
>
44 class Replayer
: public image_replayer::Replayer
{
46 static Replayer
* create(
47 Threads
<ImageCtxT
>* threads
,
48 InstanceWatcher
<ImageCtxT
>* instance_watcher
,
49 const std::string
& local_mirror_uuid
,
50 PoolMetaCache
* pool_meta_cache
,
51 StateBuilder
<ImageCtxT
>* state_builder
,
52 ReplayerListener
* replayer_listener
) {
53 return new Replayer(threads
, instance_watcher
, local_mirror_uuid
,
54 pool_meta_cache
, state_builder
, replayer_listener
);
58 Threads
<ImageCtxT
>* threads
,
59 InstanceWatcher
<ImageCtxT
>* instance_watcher
,
60 const std::string
& local_mirror_uuid
,
61 PoolMetaCache
* pool_meta_cache
,
62 StateBuilder
<ImageCtxT
>* state_builder
,
63 ReplayerListener
* replayer_listener
);
66 void destroy() override
{
70 void init(Context
* on_finish
) override
;
71 void shut_down(Context
* on_finish
) override
;
73 void flush(Context
* on_finish
) override
;
75 bool get_replay_status(std::string
* description
, Context
* on_finish
) override
;
77 bool is_replaying() const override
{
78 std::unique_lock locker
{m_lock
};
79 return (m_state
== STATE_REPLAYING
|| m_state
== STATE_IDLE
);
82 bool is_resync_requested() const override
{
83 std::unique_lock locker
{m_lock
};
84 return m_resync_requested
;
87 int get_error_code() const override
{
88 std::unique_lock
locker(m_lock
);
92 std::string
get_error_description() const override
{
93 std::unique_lock
locker(m_lock
);
94 return m_error_description
;
97 std::string
get_image_spec() const {
98 std::unique_lock
locker(m_lock
);
109 * REGISTER_LOCAL_UPDATE_WATCHER
112 * REGISTER_REMOTE_UPDATE_WATCHER
115 * LOAD_LOCAL_IMAGE_META <----------------------------\
117 * v (skip if not needed) |
118 * REFRESH_LOCAL_IMAGE |
120 * v (skip if not needed) |
121 * REFRESH_REMOTE_IMAGE |
123 * | (unused non-primary snapshot) |
124 * |\--------------> PRUNE_NON_PRIMARY_SNAPSHOT---/|
126 * | (interrupted sync) |
127 * |\--------------> GET_LOCAL_IMAGE_STATE ------\ |
129 * | (new snapshot) | |
130 * |\--------------> COPY_SNAPSHOTS | |
133 * | GET_REMOTE_IMAGE_STATE | |
136 * | CREATE_NON_PRIMARY_SNAPSHOT | |
138 * | v (skip if not needed)| |
139 * | UPDATE_MIRROR_IMAGE_STATE | |
141 * | |/--------------------/ |
150 * | APPLY_IMAGE_STATE |
153 * | UPDATE_NON_PRIMARY_SNAPSHOT |
156 * | NOTIFY_IMAGE_UPDATE |
158 * | (interrupted unlink) v |
159 * |\--------------> UNLINK_PEER |
162 * | NOTIFY_LISTENER |
164 * | \----------------------/|
166 * | (remote demoted) |
167 * \---------------> NOTIFY_LISTENER |
169 * |/--------------------/ |
171 * | (update notification) |
172 * <idle> --------------------------------------------/
178 * UNREGISTER_REMOTE_UPDATE_WATCHER
181 * UNREGISTER_LOCAL_UPDATE_WATCHER
184 * WAIT_FOR_IN_FLIGHT_OPS
199 struct C_UpdateWatchCtx
;
200 struct DeepCopyHandler
;
202 Threads
<ImageCtxT
>* m_threads
;
203 InstanceWatcher
<ImageCtxT
>* m_instance_watcher
;
204 std::string m_local_mirror_uuid
;
205 PoolMetaCache
* m_pool_meta_cache
;
206 StateBuilder
<ImageCtxT
>* m_state_builder
;
207 ReplayerListener
* m_replayer_listener
;
209 mutable ceph::mutex m_lock
;
211 State m_state
= STATE_INIT
;
213 std::string m_image_spec
;
214 Context
* m_on_init_shutdown
= nullptr;
216 bool m_resync_requested
= false;
217 int m_error_code
= 0;
218 std::string m_error_description
;
220 C_UpdateWatchCtx
* m_update_watch_ctx
= nullptr;
221 uint64_t m_local_update_watcher_handle
= 0;
222 uint64_t m_remote_update_watcher_handle
= 0;
223 bool m_image_updated
= false;
225 AsyncOpTracker m_in_flight_op_tracker
;
227 uint64_t m_local_snap_id_start
= 0;
228 uint64_t m_local_snap_id_end
= CEPH_NOSNAP
;
229 cls::rbd::MirrorSnapshotNamespace m_local_mirror_snap_ns
;
230 uint64_t m_local_object_count
= 0;
232 std::string m_remote_mirror_peer_uuid
;
233 uint64_t m_remote_snap_id_start
= 0;
234 uint64_t m_remote_snap_id_end
= CEPH_NOSNAP
;
235 cls::rbd::MirrorSnapshotNamespace m_remote_mirror_snap_ns
;
237 librbd::mirror::snapshot::ImageState m_image_state
;
238 DeepCopyHandler
* m_deep_copy_handler
= nullptr;
240 TimeRollingMean m_bytes_per_second
;
242 uint64_t m_snapshot_bytes
= 0;
243 boost::accumulators::accumulator_set
<
244 uint64_t, boost::accumulators::stats
<
245 boost::accumulators::tag::rolling_mean
>> m_bytes_per_snapshot
{
246 boost::accumulators::tag::rolling_window::window_size
= 2};
247 utime_t m_snapshot_replay_start
;
249 uint32_t m_pending_snapshots
= 0;
251 bool m_remote_image_updated
= false;
252 bool m_updating_sync_point
= false;
253 bool m_sync_in_progress
= false;
255 PerfCounters
*m_perf_counters
= nullptr;
257 void load_local_image_meta();
258 void handle_load_local_image_meta(int r
);
260 void refresh_local_image();
261 void handle_refresh_local_image(int r
);
263 void refresh_remote_image();
264 void handle_refresh_remote_image(int r
);
266 void scan_local_mirror_snapshots(std::unique_lock
<ceph::mutex
>* locker
);
267 void scan_remote_mirror_snapshots(std::unique_lock
<ceph::mutex
>* locker
);
269 void prune_non_primary_snapshot(uint64_t snap_id
);
270 void handle_prune_non_primary_snapshot(int r
);
272 void copy_snapshots();
273 void handle_copy_snapshots(int r
);
275 void get_remote_image_state();
276 void handle_get_remote_image_state(int r
);
278 void get_local_image_state();
279 void handle_get_local_image_state(int r
);
281 void create_non_primary_snapshot();
282 void handle_create_non_primary_snapshot(int r
);
284 void update_mirror_image_state();
285 void handle_update_mirror_image_state(int r
);
288 void handle_request_sync(int r
);
291 void handle_copy_image(int r
);
292 void handle_copy_image_progress(uint64_t object_number
,
293 uint64_t object_count
);
294 void handle_copy_image_read(uint64_t bytes_read
);
296 void apply_image_state();
297 void handle_apply_image_state(int r
);
299 void update_non_primary_snapshot(bool complete
);
300 void handle_update_non_primary_snapshot(bool complete
, int r
);
302 void notify_image_update();
303 void handle_notify_image_update(int r
);
305 void unlink_peer(uint64_t remote_snap_id
);
306 void handle_unlink_peer(int r
);
310 void register_local_update_watcher();
311 void handle_register_local_update_watcher(int r
);
313 void register_remote_update_watcher();
314 void handle_register_remote_update_watcher(int r
);
316 void unregister_remote_update_watcher();
317 void handle_unregister_remote_update_watcher(int r
);
319 void unregister_local_update_watcher();
320 void handle_unregister_local_update_watcher(int r
);
322 void wait_for_in_flight_ops();
323 void handle_wait_for_in_flight_ops(int r
);
325 void handle_image_update_notify();
327 void handle_replay_complete(int r
, const std::string
& description
);
328 void handle_replay_complete(std::unique_lock
<ceph::mutex
>* locker
,
329 int r
, const std::string
& description
);
330 void notify_status_updated();
332 bool is_replay_interrupted();
333 bool is_replay_interrupted(std::unique_lock
<ceph::mutex
>* lock
);
335 void register_perf_counters();
336 void unregister_perf_counters();
339 } // namespace snapshot
340 } // namespace image_replayer
341 } // namespace mirror
344 extern template class rbd::mirror::image_replayer::snapshot::Replayer
<librbd::ImageCtx
>;
346 #endif // RBD_MIRROR_IMAGE_REPLAYER_SNAPSHOT_REPLAYER_H