1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "SyncPointCreateRequest.h"
5 #include "include/uuid.h"
6 #include "common/errno.h"
7 #include "journal/Journaler.h"
8 #include "librbd/ImageCtx.h"
9 #include "librbd/ImageState.h"
10 #include "librbd/Operations.h"
11 #include "librbd/Utils.h"
13 #define dout_context g_ceph_context
14 #define dout_subsys ceph_subsys_rbd_mirror
16 #define dout_prefix *_dout << "rbd::mirror::image_sync::SyncPointCreateRequest: " \
17 << this << " " << __func__
21 namespace image_sync {
25 static const std::string SNAP_NAME_PREFIX(".rbd-mirror");
27 } // anonymous namespace
29 using librbd::util::create_context_callback;
32 SyncPointCreateRequest<I>::SyncPointCreateRequest(I *remote_image_ctx,
33 const std::string &mirror_uuid,
35 MirrorPeerClientMeta *client_meta,
37 : m_remote_image_ctx(remote_image_ctx), m_mirror_uuid(mirror_uuid),
38 m_journaler(journaler), m_client_meta(client_meta), m_on_finish(on_finish),
39 m_client_meta_copy(*client_meta) {
40 assert(m_client_meta->sync_points.size() < 2);
42 // initialize the updated client meta with the new sync point
43 m_client_meta_copy.sync_points.emplace_back();
44 if (m_client_meta_copy.sync_points.size() > 1) {
45 m_client_meta_copy.sync_points.back().from_snap_name =
46 m_client_meta_copy.sync_points.front().snap_name;
51 void SyncPointCreateRequest<I>::send() {
56 void SyncPointCreateRequest<I>::send_update_client() {
58 uuid_gen.generate_random();
60 MirrorPeerSyncPoint &sync_point = m_client_meta_copy.sync_points.back();
61 sync_point.snap_name = SNAP_NAME_PREFIX + "." + m_mirror_uuid + "." +
64 dout(20) << ": sync_point=" << sync_point << dendl;
66 bufferlist client_data_bl;
67 librbd::journal::ClientData client_data(m_client_meta_copy);
68 ::encode(client_data, client_data_bl);
70 Context *ctx = create_context_callback<
71 SyncPointCreateRequest<I>, &SyncPointCreateRequest<I>::handle_update_client>(
73 m_journaler->update_client(client_data_bl, ctx);
77 void SyncPointCreateRequest<I>::handle_update_client(int r) {
78 dout(20) << ": r=" << r << dendl;
81 derr << ": failed to update client data: " << cpp_strerror(r)
87 // update provided meta structure to reflect reality
88 *m_client_meta = m_client_meta_copy;
94 void SyncPointCreateRequest<I>::send_refresh_image() {
97 Context *ctx = create_context_callback<
98 SyncPointCreateRequest<I>, &SyncPointCreateRequest<I>::handle_refresh_image>(
100 m_remote_image_ctx->state->refresh(ctx);
103 template <typename I>
104 void SyncPointCreateRequest<I>::handle_refresh_image(int r) {
105 dout(20) << ": r=" << r << dendl;
108 derr << ": remote image refresh failed: " << cpp_strerror(r) << dendl;
116 template <typename I>
117 void SyncPointCreateRequest<I>::send_create_snap() {
120 MirrorPeerSyncPoint &sync_point = m_client_meta_copy.sync_points.back();
122 Context *ctx = create_context_callback<
123 SyncPointCreateRequest<I>, &SyncPointCreateRequest<I>::handle_create_snap>(
125 m_remote_image_ctx->operations->snap_create(
126 cls::rbd::UserSnapshotNamespace(), sync_point.snap_name.c_str(), ctx);
129 template <typename I>
130 void SyncPointCreateRequest<I>::handle_create_snap(int r) {
131 dout(20) << ": r=" << r << dendl;
134 send_update_client();
137 derr << ": failed to create snapshot: " << cpp_strerror(r) << dendl;
142 send_final_refresh_image();
145 template <typename I>
146 void SyncPointCreateRequest<I>::send_final_refresh_image() {
149 Context *ctx = create_context_callback<
150 SyncPointCreateRequest<I>,
151 &SyncPointCreateRequest<I>::handle_final_refresh_image>(this);
152 m_remote_image_ctx->state->refresh(ctx);
155 template <typename I>
156 void SyncPointCreateRequest<I>::handle_final_refresh_image(int r) {
157 dout(20) << ": r=" << r << dendl;
160 derr << ": failed to refresh image for snapshot: " << cpp_strerror(r)
169 template <typename I>
170 void SyncPointCreateRequest<I>::finish(int r) {
171 dout(20) << ": r=" << r << dendl;
173 m_on_finish->complete(r);
177 } // namespace image_sync
178 } // namespace mirror
181 template class rbd::mirror::image_sync::SyncPointCreateRequest<librbd::ImageCtx>;