// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab #include "StateBuilder.h" #include "include/ceph_assert.h" #include "include/Context.h" #include "common/debug.h" #include "common/errno.h" #include "journal/Journaler.h" #include "librbd/ImageCtx.h" #include "librbd/Journal.h" #include "tools/rbd_mirror/image_replayer/journal/CreateLocalImageRequest.h" #include "tools/rbd_mirror/image_replayer/journal/PrepareReplayRequest.h" #include "tools/rbd_mirror/image_replayer/journal/Replayer.h" #include "tools/rbd_mirror/image_replayer/journal/SyncPointHandler.h" #define dout_context g_ceph_context #define dout_subsys ceph_subsys_rbd_mirror #undef dout_prefix #define dout_prefix *_dout << "rbd::mirror::image_replayer::journal::" \ << "StateBuilder: " << this << " " \ << __func__ << ": " namespace rbd { namespace mirror { namespace image_replayer { namespace journal { template StateBuilder::StateBuilder(const std::string& global_image_id) : image_replayer::StateBuilder(global_image_id) { } template StateBuilder::~StateBuilder() { ceph_assert(remote_journaler == nullptr); } template void StateBuilder::close(Context* on_finish) { dout(10) << dendl; // close the remote journaler after closing the local image // in case we have lost contact w/ the remote cluster and // will block on_finish = new LambdaContext([this, on_finish](int) { shut_down_remote_journaler(on_finish); }); on_finish = new LambdaContext([this, on_finish](int) { this->close_local_image(on_finish); }); this->close_remote_image(on_finish); } template bool StateBuilder::is_disconnected() const { return (remote_client_state == cls::journal::CLIENT_STATE_DISCONNECTED); } template bool StateBuilder::is_linked_impl() const { ceph_assert(!this->remote_mirror_uuid.empty()); return (local_primary_mirror_uuid == this->remote_mirror_uuid); } template cls::rbd::MirrorImageMode StateBuilder::get_mirror_image_mode() const { return cls::rbd::MIRROR_IMAGE_MODE_JOURNAL; } template image_sync::SyncPointHandler* StateBuilder::create_sync_point_handler() { dout(10) << dendl; this->m_sync_point_handler = SyncPointHandler::create(this); return this->m_sync_point_handler; } template BaseRequest* StateBuilder::create_local_image_request( Threads* threads, librados::IoCtx& local_io_ctx, const std::string& global_image_id, PoolMetaCache* pool_meta_cache, ProgressContext* progress_ctx, Context* on_finish) { return CreateLocalImageRequest::create( threads, local_io_ctx, this->remote_image_ctx, this->global_image_id, pool_meta_cache, progress_ctx, this, on_finish); } template BaseRequest* StateBuilder::create_prepare_replay_request( const std::string& local_mirror_uuid, ProgressContext* progress_ctx, bool* resync_requested, bool* syncing, Context* on_finish) { return PrepareReplayRequest::create( local_mirror_uuid, progress_ctx, this, resync_requested, syncing, on_finish); } template image_replayer::Replayer* StateBuilder::create_replayer( Threads* threads, InstanceWatcher* instance_watcher, const std::string& local_mirror_uuid, PoolMetaCache* pool_meta_cache, ReplayerListener* replayer_listener) { return Replayer::create( threads, local_mirror_uuid, this, replayer_listener); } template void StateBuilder::shut_down_remote_journaler(Context* on_finish) { if (remote_journaler == nullptr) { on_finish->complete(0); return; } dout(10) << dendl; auto ctx = new LambdaContext([this, on_finish](int r) { handle_shut_down_remote_journaler(r, on_finish); }); remote_journaler->shut_down(ctx); } template void StateBuilder::handle_shut_down_remote_journaler(int r, Context* on_finish) { dout(10) << "r=" << r << dendl; if (r < 0) { derr << "failed to shut down remote journaler: " << cpp_strerror(r) << dendl; } delete remote_journaler; remote_journaler = nullptr; on_finish->complete(r); } } // namespace journal } // namespace image_replayer } // namespace mirror } // namespace rbd template class rbd::mirror::image_replayer::journal::StateBuilder;