1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_RBD_MIRROR_IMAGE_REPLAYER_H
5 #define CEPH_RBD_MIRROR_IMAGE_REPLAYER_H
7 #include "common/AsyncOpTracker.h"
8 #include "common/ceph_mutex.h"
9 #include "include/rados/librados.hpp"
10 #include "cls/rbd/cls_rbd_types.h"
11 #include "ProgressContext.h"
12 #include "tools/rbd_mirror/Types.h"
13 #include "tools/rbd_mirror/image_replayer/Types.h"
14 #include <boost/optional.hpp>
17 class AdminSocketHook
;
19 namespace journal
{ struct CacheManagerHandler
; }
20 namespace librbd
{ class ImageCtx
; }
25 template <typename
> struct InstanceWatcher
;
26 template <typename
> struct MirrorStatusUpdater
;
28 template <typename
> struct Threads
;
30 namespace image_replayer
{
33 template <typename
> class BootstrapRequest
;
34 template <typename
> class StateBuilder
;
36 } // namespace image_replayer
39 * Replays changes from a remote cluster for a single image.
41 template <typename ImageCtxT
= librbd::ImageCtx
>
44 static ImageReplayer
*create(
45 librados::IoCtx
&local_io_ctx
, const std::string
&local_mirror_uuid
,
46 const std::string
&global_image_id
, Threads
<ImageCtxT
> *threads
,
47 InstanceWatcher
<ImageCtxT
> *instance_watcher
,
48 MirrorStatusUpdater
<ImageCtxT
>* local_status_updater
,
49 journal::CacheManagerHandler
*cache_manager_handler
,
50 PoolMetaCache
* pool_meta_cache
) {
51 return new ImageReplayer(local_io_ctx
, local_mirror_uuid
, global_image_id
,
52 threads
, instance_watcher
, local_status_updater
,
53 cache_manager_handler
, pool_meta_cache
);
59 ImageReplayer(librados::IoCtx
&local_io_ctx
,
60 const std::string
&local_mirror_uuid
,
61 const std::string
&global_image_id
,
62 Threads
<ImageCtxT
> *threads
,
63 InstanceWatcher
<ImageCtxT
> *instance_watcher
,
64 MirrorStatusUpdater
<ImageCtxT
>* local_status_updater
,
65 journal::CacheManagerHandler
*cache_manager_handler
,
66 PoolMetaCache
* pool_meta_cache
);
67 virtual ~ImageReplayer();
68 ImageReplayer(const ImageReplayer
&) = delete;
69 ImageReplayer
& operator=(const ImageReplayer
&) = delete;
71 bool is_stopped() { std::lock_guard l
{m_lock
}; return is_stopped_(); }
72 bool is_running() { std::lock_guard l
{m_lock
}; return is_running_(); }
73 bool is_replaying() { std::lock_guard l
{m_lock
}; return is_replaying_(); }
75 std::string
get_name() { std::lock_guard l
{m_lock
}; return m_image_spec
; };
76 void set_state_description(int r
, const std::string
&desc
);
78 // TODO temporary until policy handles release of image replayers
79 inline bool is_finished() const {
80 std::lock_guard locker
{m_lock
};
83 inline void set_finished(bool finished
) {
84 std::lock_guard locker
{m_lock
};
85 m_finished
= finished
;
88 inline bool is_blacklisted() const {
89 std::lock_guard locker
{m_lock
};
90 return (m_last_r
== -EBLACKLISTED
);
93 image_replayer::HealthState
get_health_state() const;
95 void add_peer(const Peer
<ImageCtxT
>& peer
);
97 inline int64_t get_local_pool_id() const {
98 return m_local_io_ctx
.get_id();
100 inline const std::string
& get_global_image_id() const {
101 return m_global_image_id
;
104 void start(Context
*on_finish
= nullptr, bool manual
= false);
105 void stop(Context
*on_finish
= nullptr, bool manual
= false,
106 int r
= 0, const std::string
& desc
= "");
107 void restart(Context
*on_finish
= nullptr);
110 void print_status(Formatter
*f
);
116 * <uninitialized> <------------------------------------ FAIL
122 * BOOTSTRAP_IMAGE * * * * * * * * * * * * * * * * * * * *
125 * START_REPLAY * * * * * * * * * * * * * * * * * * * * * *
131 * JOURNAL_REPLAY_SHUT_DOWN
142 virtual void on_start_fail(int r
, const std::string
&desc
);
143 virtual bool on_start_interrupted();
144 virtual bool on_start_interrupted(ceph::mutex
& lock
);
146 virtual void on_stop_journal_replay(int r
= 0, const std::string
&desc
= "");
148 bool on_replay_interrupted();
151 typedef std::set
<Peer
<ImageCtxT
>> Peers
;
161 struct ReplayerListener
;
163 typedef boost::optional
<State
> OptionalState
;
164 typedef boost::optional
<cls::rbd::MirrorImageStatusState
>
165 OptionalMirrorImageStatusState
;
167 class BootstrapProgressContext
: public ProgressContext
{
169 BootstrapProgressContext(ImageReplayer
<ImageCtxT
> *replayer
) :
173 void update_progress(const std::string
&description
,
174 bool flush
= true) override
;
177 ImageReplayer
<ImageCtxT
> *replayer
;
180 librados::IoCtx
&m_local_io_ctx
;
181 std::string m_local_mirror_uuid
;
182 std::string m_global_image_id
;
183 Threads
<ImageCtxT
> *m_threads
;
184 InstanceWatcher
<ImageCtxT
> *m_instance_watcher
;
185 MirrorStatusUpdater
<ImageCtxT
>* m_local_status_updater
;
186 journal::CacheManagerHandler
*m_cache_manager_handler
;
187 PoolMetaCache
* m_pool_meta_cache
;
190 Peer
<ImageCtxT
> m_remote_image_peer
;
192 std::string m_local_image_name
;
193 std::string m_image_spec
;
195 mutable ceph::mutex m_lock
;
196 State m_state
= STATE_STOPPED
;
197 std::string m_state_desc
;
199 OptionalMirrorImageStatusState m_mirror_image_status_state
=
200 boost::make_optional(false, cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN
);
203 BootstrapProgressContext m_progress_cxt
;
205 bool m_finished
= false;
206 bool m_delete_requested
= false;
207 bool m_resync_requested
= false;
209 image_replayer::StateBuilder
<ImageCtxT
>* m_state_builder
= nullptr;
210 image_replayer::Replayer
* m_replayer
= nullptr;
211 ReplayerListener
* m_replayer_listener
= nullptr;
213 Context
*m_on_start_finish
= nullptr;
214 Context
*m_on_stop_finish
= nullptr;
215 bool m_stop_requested
= false;
216 bool m_manual_stop
= false;
218 AdminSocketHook
*m_asok_hook
= nullptr;
220 image_replayer::BootstrapRequest
<ImageCtxT
> *m_bootstrap_request
= nullptr;
222 AsyncOpTracker m_in_flight_op_tracker
;
224 Context
* m_update_status_task
= nullptr;
226 static std::string
to_string(const State state
);
228 bool is_stopped_() const {
229 return m_state
== STATE_STOPPED
;
231 bool is_running_() const {
232 return !is_stopped_() && m_state
!= STATE_STOPPING
&& !m_stop_requested
;
234 bool is_replaying_() const {
235 return (m_state
== STATE_REPLAYING
);
238 void schedule_update_mirror_image_replay_status();
239 void handle_update_mirror_image_replay_status(int r
);
240 void cancel_update_mirror_image_replay_status();
242 void update_mirror_image_status(bool force
, const OptionalState
&state
);
243 void set_mirror_image_status_update(bool force
, const OptionalState
&state
);
245 void shut_down(int r
);
246 void handle_shut_down(int r
);
249 void handle_bootstrap(int r
);
252 void handle_start_replay(int r
);
254 void handle_replayer_notification();
256 void register_admin_socket_hook();
257 void unregister_admin_socket_hook();
258 void reregister_admin_socket_hook();
262 } // namespace mirror
265 extern template class rbd::mirror::ImageReplayer
<librbd::ImageCtx
>;
267 #endif // CEPH_RBD_MIRROR_IMAGE_REPLAYER_H