]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/rbd_mirror/ImageReplayer.h
update source to Ceph Pacific 16.2.2
[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
e306af50
TL
104 void start(Context *on_finish = nullptr, bool manual = false,
105 bool restart = false);
7c673cae 106 void stop(Context *on_finish = nullptr, bool manual = false,
e306af50 107 bool restart = false);
7c673cae 108 void restart(Context *on_finish = nullptr);
81eedcae 109 void flush();
7c673cae 110
9f95a23c 111 void print_status(Formatter *f);
7c673cae
FG
112
113protected:
114 /**
115 * @verbatim
116 * (error)
117 * <uninitialized> <------------------------------------ FAIL
118 * | ^
119 * v *
120 * <starting> *
121 * | *
122 * v (error) *
7c673cae
FG
123 * BOOTSTRAP_IMAGE * * * * * * * * * * * * * * * * * * * *
124 * | *
125 * v (error) *
7c673cae
FG
126 * START_REPLAY * * * * * * * * * * * * * * * * * * * * * *
127 * |
9f95a23c
TL
128 * v
129 * REPLAYING
7c673cae
FG
130 * |
131 * v
132 * JOURNAL_REPLAY_SHUT_DOWN
133 * |
134 * v
135 * LOCAL_IMAGE_CLOSE
136 * |
137 * v
138 * <stopped>
139 *
140 * @endverbatim
141 */
142
e306af50
TL
143 void on_start_fail(int r, const std::string &desc);
144 bool on_start_interrupted();
145 bool on_start_interrupted(ceph::mutex& lock);
7c673cae 146
e306af50 147 void on_stop_journal_replay(int r = 0, const std::string &desc = "");
7c673cae 148
7c673cae
FG
149 bool on_replay_interrupted();
150
151private:
9f95a23c 152 typedef std::set<Peer<ImageCtxT>> Peers;
c07f9fc5
FG
153
154 enum State {
155 STATE_UNKNOWN,
156 STATE_STARTING,
157 STATE_REPLAYING,
c07f9fc5
FG
158 STATE_STOPPING,
159 STATE_STOPPED,
160 };
161
9f95a23c 162 struct ReplayerListener;
7c673cae 163
7c673cae 164 typedef boost::optional<State> OptionalState;
c07f9fc5
FG
165 typedef boost::optional<cls::rbd::MirrorImageStatusState>
166 OptionalMirrorImageStatusState;
7c673cae 167
7c673cae
FG
168 class BootstrapProgressContext : public ProgressContext {
169 public:
170 BootstrapProgressContext(ImageReplayer<ImageCtxT> *replayer) :
171 replayer(replayer) {
172 }
173
174 void update_progress(const std::string &description,
9f95a23c
TL
175 bool flush = true) override;
176
7c673cae
FG
177 private:
178 ImageReplayer<ImageCtxT> *replayer;
179 };
180
9f95a23c
TL
181 librados::IoCtx &m_local_io_ctx;
182 std::string m_local_mirror_uuid;
183 std::string m_global_image_id;
d2e6a577 184 Threads<ImageCtxT> *m_threads;
31f18b77 185 InstanceWatcher<ImageCtxT> *m_instance_watcher;
9f95a23c
TL
186 MirrorStatusUpdater<ImageCtxT>* m_local_status_updater;
187 journal::CacheManagerHandler *m_cache_manager_handler;
188 PoolMetaCache* m_pool_meta_cache;
7c673cae 189
d2e6a577 190 Peers m_peers;
9f95a23c 191 Peer<ImageCtxT> m_remote_image_peer;
7c673cae 192
28e407b8 193 std::string m_local_image_name;
9f95a23c 194 std::string m_image_spec;
d2e6a577 195
9f95a23c 196 mutable ceph::mutex m_lock;
7c673cae 197 State m_state = STATE_STOPPED;
7c673cae 198 std::string m_state_desc;
c07f9fc5 199
11fdf7f2
TL
200 OptionalMirrorImageStatusState m_mirror_image_status_state =
201 boost::make_optional(false, cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN);
c07f9fc5
FG
202 int m_last_r = 0;
203
7c673cae 204 BootstrapProgressContext m_progress_cxt;
d2e6a577
FG
205
206 bool m_finished = false;
207 bool m_delete_requested = false;
208 bool m_resync_requested = false;
e306af50 209 bool m_restart_requested = false;
d2e6a577 210
9f95a23c
TL
211 image_replayer::StateBuilder<ImageCtxT>* m_state_builder = nullptr;
212 image_replayer::Replayer* m_replayer = nullptr;
213 ReplayerListener* m_replayer_listener = nullptr;
7c673cae
FG
214
215 Context *m_on_start_finish = nullptr;
216 Context *m_on_stop_finish = nullptr;
7c673cae
FG
217 bool m_stop_requested = false;
218 bool m_manual_stop = false;
219
220 AdminSocketHook *m_asok_hook = nullptr;
221
222 image_replayer::BootstrapRequest<ImageCtxT> *m_bootstrap_request = nullptr;
223
9f95a23c 224 AsyncOpTracker m_in_flight_op_tracker;
7c673cae 225
1911f103
TL
226 Context* m_update_status_task = nullptr;
227
7c673cae
FG
228 static std::string to_string(const State state);
229
7c673cae
FG
230 bool is_stopped_() const {
231 return m_state == STATE_STOPPED;
232 }
233 bool is_running_() const {
234 return !is_stopped_() && m_state != STATE_STOPPING && !m_stop_requested;
235 }
236 bool is_replaying_() const {
9f95a23c 237 return (m_state == STATE_REPLAYING);
7c673cae
FG
238 }
239
1911f103
TL
240 void schedule_update_mirror_image_replay_status();
241 void handle_update_mirror_image_replay_status(int r);
242 void cancel_update_mirror_image_replay_status();
243
9f95a23c
TL
244 void update_mirror_image_status(bool force, const OptionalState &state);
245 void set_mirror_image_status_update(bool force, const OptionalState &state);
7c673cae
FG
246
247 void shut_down(int r);
248 void handle_shut_down(int r);
d2e6a577 249
7c673cae
FG
250 void bootstrap();
251 void handle_bootstrap(int r);
252
7c673cae
FG
253 void start_replay();
254 void handle_start_replay(int r);
255
9f95a23c 256 void handle_replayer_notification();
7c673cae 257
d2e6a577
FG
258 void register_admin_socket_hook();
259 void unregister_admin_socket_hook();
28e407b8 260 void reregister_admin_socket_hook();
1911f103 261
7c673cae
FG
262};
263
264} // namespace mirror
265} // namespace rbd
266
267extern template class rbd::mirror::ImageReplayer<librbd::ImageCtx>;
268
269#endif // CEPH_RBD_MIRROR_IMAGE_REPLAYER_H