]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / tools / rbd_mirror / image_replayer / PrepareRemoteImageRequest.cc
CommitLineData
d2e6a577
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h"
5#include "include/rados/librados.hpp"
6#include "cls/rbd/cls_rbd_client.h"
11fdf7f2 7#include "common/debug.h"
d2e6a577 8#include "common/errno.h"
b32b8144
FG
9#include "common/WorkQueue.h"
10#include "journal/Journaler.h"
d2e6a577
FG
11#include "librbd/ImageCtx.h"
12#include "librbd/Utils.h"
b32b8144
FG
13#include "librbd/journal/Types.h"
14#include "tools/rbd_mirror/Threads.h"
d2e6a577 15#include "tools/rbd_mirror/image_replayer/GetMirrorImageIdRequest.h"
11fdf7f2 16#include "tools/rbd_mirror/image_replayer/Utils.h"
d2e6a577
FG
17
18#define dout_context g_ceph_context
19#define dout_subsys ceph_subsys_rbd_mirror
20#undef dout_prefix
21#define dout_prefix *_dout << "rbd::mirror::image_replayer::" \
22 << "PrepareRemoteImageRequest: " << this << " " \
23 << __func__ << ": "
24
25namespace rbd {
26namespace mirror {
27namespace image_replayer {
28
b32b8144 29using librbd::util::create_async_context_callback;
d2e6a577
FG
30using librbd::util::create_context_callback;
31using librbd::util::create_rados_callback;
32
33template <typename I>
34void PrepareRemoteImageRequest<I>::send() {
35 get_remote_mirror_uuid();
36}
37
38template <typename I>
39void PrepareRemoteImageRequest<I>::get_remote_mirror_uuid() {
40 dout(20) << dendl;
41
42 librados::ObjectReadOperation op;
43 librbd::cls_client::mirror_uuid_get_start(&op);
44
45 librados::AioCompletion *aio_comp = create_rados_callback<
46 PrepareRemoteImageRequest<I>,
47 &PrepareRemoteImageRequest<I>::handle_get_remote_mirror_uuid>(this);
b32b8144 48 int r = m_remote_io_ctx.aio_operate(RBD_MIRRORING, aio_comp, &op, &m_out_bl);
11fdf7f2 49 ceph_assert(r == 0);
d2e6a577
FG
50 aio_comp->release();
51}
52
53template <typename I>
54void PrepareRemoteImageRequest<I>::handle_get_remote_mirror_uuid(int r) {
55 if (r >= 0) {
11fdf7f2 56 auto it = m_out_bl.cbegin();
d2e6a577
FG
57 r = librbd::cls_client::mirror_uuid_get_finish(&it, m_remote_mirror_uuid);
58 if (r >= 0 && m_remote_mirror_uuid->empty()) {
59 r = -ENOENT;
60 }
61 }
62
63 dout(20) << "r=" << r << dendl;
64 if (r < 0) {
65 if (r == -ENOENT) {
66 dout(5) << "remote mirror uuid missing" << dendl;
67 } else {
68 derr << "failed to retrieve remote mirror uuid: " << cpp_strerror(r)
69 << dendl;
70 }
71 finish(r);
72 return;
73 }
74
75 get_remote_image_id();
76}
77
78template <typename I>
79void PrepareRemoteImageRequest<I>::get_remote_image_id() {
80 dout(20) << dendl;
81
82 Context *ctx = create_context_callback<
83 PrepareRemoteImageRequest<I>,
84 &PrepareRemoteImageRequest<I>::handle_get_remote_image_id>(this);
b32b8144
FG
85 auto req = GetMirrorImageIdRequest<I>::create(m_remote_io_ctx,
86 m_global_image_id,
d2e6a577
FG
87 m_remote_image_id, ctx);
88 req->send();
89}
90
91template <typename I>
92void PrepareRemoteImageRequest<I>::handle_get_remote_image_id(int r) {
93 dout(20) << "r=" << r << ", "
94 << "remote_image_id=" << *m_remote_image_id << dendl;
95
96 if (r < 0) {
97 finish(r);
98 return;
99 }
100
b32b8144
FG
101 get_client();
102}
103
104template <typename I>
105void PrepareRemoteImageRequest<I>::get_client() {
106 dout(20) << dendl;
107
11fdf7f2 108 ceph_assert(*m_remote_journaler == nullptr);
b32b8144
FG
109 *m_remote_journaler = new Journaler(m_threads->work_queue, m_threads->timer,
110 &m_threads->timer_lock, m_remote_io_ctx,
111 *m_remote_image_id, m_local_mirror_uuid,
11fdf7f2 112 m_journal_settings);
b32b8144
FG
113
114 Context *ctx = create_async_context_callback(
115 m_threads->work_queue, create_context_callback<
116 PrepareRemoteImageRequest<I>,
117 &PrepareRemoteImageRequest<I>::handle_get_client>(this));
118 (*m_remote_journaler)->get_client(m_local_mirror_uuid, &m_client, ctx);
119}
120
121template <typename I>
122void PrepareRemoteImageRequest<I>::handle_get_client(int r) {
123 dout(20) << "r=" << r << dendl;
124
125 if (r == -ENOENT) {
126 dout(10) << "client not registered" << dendl;
127 register_client();
128 } else if (r < 0) {
129 derr << "failed to retrieve client: " << cpp_strerror(r) << dendl;
130 finish(r);
11fdf7f2 131 } else if (!util::decode_client_meta(m_client, m_client_meta)) {
b32b8144
FG
132 // require operator intervention since the data is corrupt
133 finish(-EBADMSG);
134 } else {
135 // skip registration if it already exists
136 *m_client_state = m_client.state;
137 finish(0);
138 }
139}
140
141template <typename I>
142void PrepareRemoteImageRequest<I>::register_client() {
143 dout(20) << dendl;
144
145 librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta{
146 m_local_image_id};
147 mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
148
149 librbd::journal::ClientData client_data{mirror_peer_client_meta};
150 bufferlist client_data_bl;
11fdf7f2 151 encode(client_data, client_data_bl);
b32b8144
FG
152
153 Context *ctx = create_async_context_callback(
154 m_threads->work_queue, create_context_callback<
155 PrepareRemoteImageRequest<I>,
156 &PrepareRemoteImageRequest<I>::handle_register_client>(this));
157 (*m_remote_journaler)->register_client(client_data_bl, ctx);
158}
159
160template <typename I>
161void PrepareRemoteImageRequest<I>::handle_register_client(int r) {
162 dout(20) << "r=" << r << dendl;
163
164 if (r < 0) {
165 derr << "failed to register with remote journal: " << cpp_strerror(r)
166 << dendl;
167 finish(r);
168 return;
169 }
170
171 *m_client_state = cls::journal::CLIENT_STATE_CONNECTED;
172 *m_client_meta = librbd::journal::MirrorPeerClientMeta(m_local_image_id);
173 m_client_meta->state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
174
d2e6a577
FG
175 finish(0);
176}
177
178template <typename I>
179void PrepareRemoteImageRequest<I>::finish(int r) {
180 dout(20) << "r=" << r << dendl;
181
b32b8144
FG
182 if (r < 0) {
183 delete *m_remote_journaler;
184 *m_remote_journaler = nullptr;
185 }
186
d2e6a577
FG
187 m_on_finish->complete(r);
188 delete this;
189}
190
191} // namespace image_replayer
192} // namespace mirror
193} // namespace rbd
194
195template class rbd::mirror::image_replayer::PrepareRemoteImageRequest<librbd::ImageCtx>;