1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
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"
17 #define dout_context g_ceph_context
18 #define dout_subsys ceph_subsys_rbd_mirror
20 #define dout_prefix *_dout << "rbd::mirror::image_replayer::journal::" \
21 << "StateBuilder: " << this << " " \
26 namespace image_replayer
{
30 StateBuilder
<I
>::StateBuilder(const std::string
& global_image_id
)
31 : image_replayer::StateBuilder
<I
>(global_image_id
) {
35 StateBuilder
<I
>::~StateBuilder() {
36 ceph_assert(remote_journaler
== nullptr);
40 void StateBuilder
<I
>::close(Context
* on_finish
) {
43 // close the remote journaler after closing the local image
44 // in case we have lost contact w/ the remote cluster and
46 on_finish
= new LambdaContext([this, on_finish
](int) {
47 shut_down_remote_journaler(on_finish
);
49 on_finish
= new LambdaContext([this, on_finish
](int) {
50 this->close_local_image(on_finish
);
52 this->close_remote_image(on_finish
);
56 bool StateBuilder
<I
>::is_disconnected() const {
57 return (remote_client_state
== cls::journal::CLIENT_STATE_DISCONNECTED
);
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
);
67 cls::rbd::MirrorImageMode StateBuilder
<I
>::get_mirror_image_mode() const {
68 return cls::rbd::MIRROR_IMAGE_MODE_JOURNAL
;
72 image_sync::SyncPointHandler
* StateBuilder
<I
>::create_sync_point_handler() {
75 this->m_sync_point_handler
= SyncPointHandler
<I
>::create(this);
76 return this->m_sync_point_handler
;
80 BaseRequest
* StateBuilder
<I
>::create_local_image_request(
82 librados::IoCtx
& local_io_ctx
,
83 const std::string
& global_image_id
,
84 PoolMetaCache
* pool_meta_cache
,
85 ProgressContext
* progress_ctx
,
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
);
93 BaseRequest
* StateBuilder
<I
>::create_prepare_replay_request(
94 const std::string
& local_mirror_uuid
,
95 ProgressContext
* progress_ctx
,
96 bool* resync_requested
,
99 return PrepareReplayRequest
<I
>::create(
100 local_mirror_uuid
, progress_ctx
, this, resync_requested
, syncing
,
104 template <typename I
>
105 image_replayer::Replayer
* StateBuilder
<I
>::create_replayer(
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
);
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);
123 auto ctx
= new LambdaContext([this, on_finish
](int r
) {
124 handle_shut_down_remote_journaler(r
, on_finish
);
126 remote_journaler
->shut_down(ctx
);
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
;
135 derr
<< "failed to shut down remote journaler: " << cpp_strerror(r
)
139 delete remote_journaler
;
140 remote_journaler
= nullptr;
141 on_finish
->complete(r
);
144 } // namespace journal
145 } // namespace image_replayer
146 } // namespace mirror
149 template class rbd::mirror::image_replayer::journal::StateBuilder
<librbd::ImageCtx
>;