+ get_client();
+}
+
+template <typename I>
+void PrepareRemoteImageRequest<I>::get_client() {
+ dout(20) << dendl;
+
+ journal::Settings settings;
+ settings.commit_interval = g_ceph_context->_conf->get_val<double>(
+ "rbd_mirror_journal_commit_age");
+ settings.max_fetch_bytes = g_ceph_context->_conf->get_val<uint64_t>(
+ "rbd_mirror_journal_max_fetch_bytes");
+
+ assert(*m_remote_journaler == nullptr);
+ *m_remote_journaler = new Journaler(m_threads->work_queue, m_threads->timer,
+ &m_threads->timer_lock, m_remote_io_ctx,
+ *m_remote_image_id, m_local_mirror_uuid,
+ settings);
+
+ Context *ctx = create_async_context_callback(
+ m_threads->work_queue, create_context_callback<
+ PrepareRemoteImageRequest<I>,
+ &PrepareRemoteImageRequest<I>::handle_get_client>(this));
+ (*m_remote_journaler)->get_client(m_local_mirror_uuid, &m_client, ctx);
+}
+
+template <typename I>
+void PrepareRemoteImageRequest<I>::handle_get_client(int r) {
+ dout(20) << "r=" << r << dendl;
+
+ if (r == -ENOENT) {
+ dout(10) << "client not registered" << dendl;
+ register_client();
+ } else if (r < 0) {
+ derr << "failed to retrieve client: " << cpp_strerror(r) << dendl;
+ finish(r);
+ } else if (!decode_client_meta()) {
+ // require operator intervention since the data is corrupt
+ finish(-EBADMSG);
+ } else {
+ // skip registration if it already exists
+ *m_client_state = m_client.state;
+ finish(0);
+ }
+}
+
+template <typename I>
+void PrepareRemoteImageRequest<I>::register_client() {
+ dout(20) << dendl;
+
+ librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{
+ m_local_image_id};
+ mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
+
+ librbd::journal::ClientData client_data{mirror_peer_client_meta};
+ bufferlist client_data_bl;
+ ::encode(client_data, client_data_bl);
+
+ Context *ctx = create_async_context_callback(
+ m_threads->work_queue, create_context_callback<
+ PrepareRemoteImageRequest<I>,
+ &PrepareRemoteImageRequest<I>::handle_register_client>(this));
+ (*m_remote_journaler)->register_client(client_data_bl, ctx);
+}
+
+template <typename I>
+void PrepareRemoteImageRequest<I>::handle_register_client(int r) {
+ dout(20) << "r=" << r << dendl;
+
+ if (r < 0) {
+ derr << "failed to register with remote journal: " << cpp_strerror(r)
+ << dendl;
+ finish(r);
+ return;
+ }
+
+ *m_client_state = cls::journal::CLIENT_STATE_CONNECTED;
+ *m_client_meta = librbd::journal::MirrorPeerClientMeta(m_local_image_id);
+ m_client_meta->state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
+