]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/rbd_mirror/ImageReplayer.h
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / tools / rbd_mirror / ImageReplayer.h
CommitLineData
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#ifndef CEPH_RBD_MIRROR_IMAGE_REPLAYER_H
5#define CEPH_RBD_MIRROR_IMAGE_REPLAYER_H
6
7#include "common/AsyncOpTracker.h"
9f95a23c 8#include "common/ceph_mutex.h"
7c673cae 9#include "include/rados/librados.hpp"
7c673cae 10#include "cls/rbd/cls_rbd_types.h"
7c673cae 11#include "ProgressContext.h"
11fdf7f2 12#include "tools/rbd_mirror/Types.h"
c07f9fc5 13#include "tools/rbd_mirror/image_replayer/Types.h"
7c673cae 14#include <boost/optional.hpp>
7c673cae 15#include <string>
7c673cae
FG
16
17class AdminSocketHook;
7c673cae 18
9f95a23c
TL
19namespace journal { struct CacheManagerHandler; }
20namespace librbd { class ImageCtx; }
7c673cae
FG
21
22namespace rbd {
23namespace mirror {
24
31f18b77 25template <typename> struct InstanceWatcher;
9f95a23c
TL
26template <typename> struct MirrorStatusUpdater;
27struct PoolMetaCache;
7c673cae
FG
28template <typename> struct Threads;
29
9f95a23c
TL
30namespace image_replayer {
31
32class Replayer;
33template <typename> class BootstrapRequest;
34template <typename> class StateBuilder;
35
36} // namespace image_replayer
7c673cae
FG
37
38/**
39 * Replays changes from a remote cluster for a single image.
40 */
41template <typename ImageCtxT = librbd::ImageCtx>
42class ImageReplayer {
43public:
7c673cae 44 static ImageReplayer *create(
9f95a23c
TL
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);
7c673cae
FG
54 }
55 void destroy() {
56 delete this;
57 }
58
9f95a23c
TL
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,
31f18b77 63 InstanceWatcher<ImageCtxT> *instance_watcher,
9f95a23c
TL
64 MirrorStatusUpdater<ImageCtxT>* local_status_updater,
65 journal::CacheManagerHandler *cache_manager_handler,
66 PoolMetaCache* pool_meta_cache);
7c673cae
FG
67 virtual ~ImageReplayer();
68 ImageReplayer(const ImageReplayer&) = delete;
69 ImageReplayer& operator=(const ImageReplayer&) = delete;
70
9f95a23c
TL
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_(); }
7c673cae 74
9f95a23c 75 std::string get_name() { std::lock_guard l{m_lock}; return m_image_spec; };
7c673cae
FG
76 void set_state_description(int r, const std::string &desc);
77
d2e6a577
FG
78 // TODO temporary until policy handles release of image replayers
79 inline bool is_finished() const {
9f95a23c 80 std::lock_guard locker{m_lock};
d2e6a577
FG
81 return m_finished;
82 }
83 inline void set_finished(bool finished) {
9f95a23c 84 std::lock_guard locker{m_lock};
d2e6a577
FG
85 m_finished = finished;
86 }
87
f67539c2 88 inline bool is_blocklisted() const {
9f95a23c 89 std::lock_guard locker{m_lock};
f67539c2 90 return (m_last_r == -EBLOCKLISTED);
7c673cae
FG
91 }
92
c07f9fc5
FG
93 image_replayer::HealthState get_health_state() const;
94
9f95a23c 95 void add_peer(const Peer<ImageCtxT>& peer);
7c673cae
FG
96
97 inline int64_t get_local_pool_id() const {
9f95a23c 98 return m_local_io_ctx.get_id();
7c673cae
FG
99 }
100 inline const std::string& get_global_image_id() const {
101 return m_global_image_id;
102 }
103
20effc67
TL
104 void start(Context *on_finish, bool manual = false, bool restart = false);
105 void stop(Context *on_finish, bool manual = false, bool restart = false);
7c673cae 106 void restart(Context *on_finish = nullptr);
81eedcae 107 void flush();
7c673cae 108
9f95a23c 109 void print_status(Formatter *f);
7c673cae
FG
110
111protected:
112 /**
113 * @verbatim
114 * (error)
115 * <uninitialized> <------------------------------------ FAIL
116 * | ^
117 * v *
118 * <starting> *
119 * | *
120 * v (error) *
7c673cae
FG
121 * BOOTSTRAP_IMAGE * * * * * * * * * * * * * * * * * * * *
122 * | *
123 * v (error) *
7c673cae
FG
124 * START_REPLAY * * * * * * * * * * * * * * * * * * * * * *
125 * |
9f95a23c
TL
126 * v
127 * REPLAYING
7c673cae
FG
128 * |
129 * v
130 * JOURNAL_REPLAY_SHUT_DOWN
131 * |
132 * v
133 * LOCAL_IMAGE_CLOSE
134 * |
135 * v
136 * <stopped>
137 *
138 * @endverbatim
139 */
140
e306af50
TL
141 void on_start_fail(int r, const std::string &desc);
142 bool on_start_interrupted();
143 bool on_start_interrupted(ceph::mutex& lock);
7c673cae 144
e306af50 145 void on_stop_journal_replay(int r = 0, const std::string &desc = "");
7c673cae 146
7c673cae
FG
147 bool on_replay_interrupted();
148
149private:
9f95a23c 150 typedef std::set<Peer<ImageCtxT>> Peers;
20effc67 151 typedef std::list<Context *> Contexts;
c07f9fc5
FG
152
153 enum State {
154 STATE_UNKNOWN,
155 STATE_STARTING,
156 STATE_REPLAYING,
c07f9fc5
FG
157 STATE_STOPPING,
158 STATE_STOPPED,
159 };
160
9f95a23c 161 struct ReplayerListener;
7c673cae 162
7c673cae 163 typedef boost::optional<State> OptionalState;
c07f9fc5
FG
164 typedef boost::optional<cls::rbd::MirrorImageStatusState>
165 OptionalMirrorImageStatusState;
7c673cae 166
7c673cae
FG
167 class BootstrapProgressContext : public ProgressContext {
168 public:
169 BootstrapProgressContext(ImageReplayer<ImageCtxT> *replayer) :
170 replayer(replayer) {
171 }
172
173 void update_progress(const std::string &description,
9f95a23c
TL
174 bool flush = true) override;
175
7c673cae
FG
176 private:
177 ImageReplayer<ImageCtxT> *replayer;
178 };
179
9f95a23c
TL
180 librados::IoCtx &m_local_io_ctx;
181 std::string m_local_mirror_uuid;
182 std::string m_global_image_id;
d2e6a577 183 Threads<ImageCtxT> *m_threads;
31f18b77 184 InstanceWatcher<ImageCtxT> *m_instance_watcher;
9f95a23c
TL
185 MirrorStatusUpdater<ImageCtxT>* m_local_status_updater;
186 journal::CacheManagerHandler *m_cache_manager_handler;
187 PoolMetaCache* m_pool_meta_cache;
7c673cae 188
d2e6a577 189 Peers m_peers;
9f95a23c 190 Peer<ImageCtxT> m_remote_image_peer;
7c673cae 191
28e407b8 192 std::string m_local_image_name;
9f95a23c 193 std::string m_image_spec;
d2e6a577 194
9f95a23c 195 mutable ceph::mutex m_lock;
7c673cae 196 State m_state = STATE_STOPPED;
7c673cae 197 std::string m_state_desc;
c07f9fc5 198
11fdf7f2
TL
199 OptionalMirrorImageStatusState m_mirror_image_status_state =
200 boost::make_optional(false, cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN);
c07f9fc5
FG
201 int m_last_r = 0;
202
7c673cae 203 BootstrapProgressContext m_progress_cxt;
d2e6a577
FG
204
205 bool m_finished = false;
a4b75251 206 bool m_delete_in_progress = false;
d2e6a577
FG
207 bool m_delete_requested = false;
208 bool m_resync_requested = false;
e306af50 209 bool m_restart_requested = false;
d2e6a577 210
a4b75251
TL
211 bool m_status_removed = false;
212
9f95a23c
TL
213 image_replayer::StateBuilder<ImageCtxT>* m_state_builder = nullptr;
214 image_replayer::Replayer* m_replayer = nullptr;
215 ReplayerListener* m_replayer_listener = nullptr;
7c673cae
FG
216
217 Context *m_on_start_finish = nullptr;
20effc67 218 Contexts m_on_stop_contexts;
7c673cae
FG
219 bool m_stop_requested = false;
220 bool m_manual_stop = false;
221
222 AdminSocketHook *m_asok_hook = nullptr;
223
224 image_replayer::BootstrapRequest<ImageCtxT> *m_bootstrap_request = nullptr;
225
9f95a23c 226 AsyncOpTracker m_in_flight_op_tracker;
7c673cae 227
1911f103
TL
228 Context* m_update_status_task = nullptr;
229
7c673cae
FG
230 static std::string to_string(const State state);
231
7c673cae
FG
232 bool is_stopped_() const {
233 return m_state == STATE_STOPPED;
234 }
235 bool is_running_() const {
236 return !is_stopped_() && m_state != STATE_STOPPING && !m_stop_requested;
237 }
238 bool is_replaying_() const {
9f95a23c 239 return (m_state == STATE_REPLAYING);
7c673cae
FG
240 }
241
1911f103
TL
242 void schedule_update_mirror_image_replay_status();
243 void handle_update_mirror_image_replay_status(int r);
244 void cancel_update_mirror_image_replay_status();
245
9f95a23c
TL
246 void update_mirror_image_status(bool force, const OptionalState &state);
247 void set_mirror_image_status_update(bool force, const OptionalState &state);
7c673cae
FG
248
249 void shut_down(int r);
250 void handle_shut_down(int r);
d2e6a577 251
7c673cae
FG
252 void bootstrap();
253 void handle_bootstrap(int r);
254
7c673cae
FG
255 void start_replay();
256 void handle_start_replay(int r);
257
9f95a23c 258 void handle_replayer_notification();
7c673cae 259
d2e6a577
FG
260 void register_admin_socket_hook();
261 void unregister_admin_socket_hook();
28e407b8 262 void reregister_admin_socket_hook();
a4b75251
TL
263 void remove_image_status(bool force, Context *on_finish);
264 void remove_image_status_remote(bool force, Context *on_finish);
1911f103 265
7c673cae
FG
266};
267
268} // namespace mirror
269} // namespace rbd
270
271extern template class rbd::mirror::ImageReplayer<librbd::ImageCtx>;
272
273#endif // CEPH_RBD_MIRROR_IMAGE_REPLAYER_H