]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd_mirror/image_replayer/journal/StateBuilder.cc
import ceph quincy 17.2.4
[ceph.git] / ceph / src / tools / rbd_mirror / image_replayer / journal / StateBuilder.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "StateBuilder.h"
5 #include "include/ceph_assert.h"
6 #include "include/Context.h"
7 #include "common/debug.h"
8 #include "common/errno.h"
9 #include "journal/Journaler.h"
10 #include "librbd/ImageCtx.h"
11 #include "librbd/Journal.h"
12 #include "tools/rbd_mirror/image_replayer/journal/CreateLocalImageRequest.h"
13 #include "tools/rbd_mirror/image_replayer/journal/PrepareReplayRequest.h"
14 #include "tools/rbd_mirror/image_replayer/journal/Replayer.h"
15 #include "tools/rbd_mirror/image_replayer/journal/SyncPointHandler.h"
16
17 #define dout_context g_ceph_context
18 #define dout_subsys ceph_subsys_rbd_mirror
19 #undef dout_prefix
20 #define dout_prefix *_dout << "rbd::mirror::image_replayer::journal::" \
21 << "StateBuilder: " << this << " " \
22 << __func__ << ": "
23
24 namespace rbd {
25 namespace mirror {
26 namespace image_replayer {
27 namespace journal {
28
29 template <typename I>
30 StateBuilder<I>::StateBuilder(const std::string& global_image_id)
31 : image_replayer::StateBuilder<I>(global_image_id) {
32 }
33
34 template <typename I>
35 StateBuilder<I>::~StateBuilder() {
36 ceph_assert(remote_journaler == nullptr);
37 }
38
39 template <typename I>
40 void StateBuilder<I>::close(Context* on_finish) {
41 dout(10) << dendl;
42
43 // close the remote journaler after closing the local image
44 // in case we have lost contact w/ the remote cluster and
45 // will block
46 on_finish = new LambdaContext([this, on_finish](int) {
47 shut_down_remote_journaler(on_finish);
48 });
49 on_finish = new LambdaContext([this, on_finish](int) {
50 this->close_local_image(on_finish);
51 });
52 this->close_remote_image(on_finish);
53 }
54
55 template <typename I>
56 bool StateBuilder<I>::is_disconnected() const {
57 return (remote_client_state == cls::journal::CLIENT_STATE_DISCONNECTED);
58 }
59
60 template <typename I>
61 bool StateBuilder<I>::is_linked_impl() const {
62 ceph_assert(!this->remote_mirror_uuid.empty());
63 return (local_primary_mirror_uuid == this->remote_mirror_uuid);
64 }
65
66 template <typename I>
67 cls::rbd::MirrorImageMode StateBuilder<I>::get_mirror_image_mode() const {
68 return cls::rbd::MIRROR_IMAGE_MODE_JOURNAL;
69 }
70
71 template <typename I>
72 image_sync::SyncPointHandler* StateBuilder<I>::create_sync_point_handler() {
73 dout(10) << dendl;
74
75 this->m_sync_point_handler = SyncPointHandler<I>::create(this);
76 return this->m_sync_point_handler;
77 }
78
79 template <typename I>
80 BaseRequest* StateBuilder<I>::create_local_image_request(
81 Threads<I>* threads,
82 librados::IoCtx& local_io_ctx,
83 const std::string& global_image_id,
84 PoolMetaCache* pool_meta_cache,
85 ProgressContext* progress_ctx,
86 Context* on_finish) {
87 return CreateLocalImageRequest<I>::create(
88 threads, local_io_ctx, this->remote_image_ctx, this->global_image_id,
89 pool_meta_cache, progress_ctx, this, on_finish);
90 }
91
92 template <typename I>
93 BaseRequest* StateBuilder<I>::create_prepare_replay_request(
94 const std::string& local_mirror_uuid,
95 ProgressContext* progress_ctx,
96 bool* resync_requested,
97 bool* syncing,
98 Context* on_finish) {
99 return PrepareReplayRequest<I>::create(
100 local_mirror_uuid, progress_ctx, this, resync_requested, syncing,
101 on_finish);
102 }
103
104 template <typename I>
105 image_replayer::Replayer* StateBuilder<I>::create_replayer(
106 Threads<I>* threads,
107 InstanceWatcher<I>* instance_watcher,
108 const std::string& local_mirror_uuid,
109 PoolMetaCache* pool_meta_cache,
110 ReplayerListener* replayer_listener) {
111 return Replayer<I>::create(
112 threads, local_mirror_uuid, this, replayer_listener);
113 }
114
115 template <typename I>
116 void StateBuilder<I>::shut_down_remote_journaler(Context* on_finish) {
117 if (remote_journaler == nullptr) {
118 on_finish->complete(0);
119 return;
120 }
121
122 dout(10) << dendl;
123 auto ctx = new LambdaContext([this, on_finish](int r) {
124 handle_shut_down_remote_journaler(r, on_finish);
125 });
126 remote_journaler->shut_down(ctx);
127 }
128
129 template <typename I>
130 void StateBuilder<I>::handle_shut_down_remote_journaler(int r,
131 Context* on_finish) {
132 dout(10) << "r=" << r << dendl;
133
134 if (r < 0) {
135 derr << "failed to shut down remote journaler: " << cpp_strerror(r)
136 << dendl;
137 }
138
139 delete remote_journaler;
140 remote_journaler = nullptr;
141 on_finish->complete(r);
142 }
143
144 } // namespace journal
145 } // namespace image_replayer
146 } // namespace mirror
147 } // namespace rbd
148
149 template class rbd::mirror::image_replayer::journal::StateBuilder<librbd::ImageCtx>;