]>
git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd_mirror/image_replayer/journal/EventPreprocessor.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "EventPreprocessor.h"
5 #include "common/debug.h"
6 #include "common/dout.h"
7 #include "common/errno.h"
8 #include "journal/Journaler.h"
9 #include "librbd/ImageCtx.h"
10 #include "librbd/ImageState.h"
11 #include "librbd/Utils.h"
12 #include "librbd/asio/ContextWQ.h"
13 #include "librbd/journal/Types.h"
14 #include <boost/variant.hpp>
16 #define dout_context g_ceph_context
17 #define dout_subsys ceph_subsys_rbd_mirror
20 #define dout_prefix *_dout << "rbd::mirror::image_replayer::journal::" \
21 << "EventPreprocessor: " << this << " " << __func__ \
26 namespace image_replayer
{
29 using librbd::util::create_context_callback
;
32 EventPreprocessor
<I
>::EventPreprocessor(I
&local_image_ctx
,
33 Journaler
&remote_journaler
,
34 const std::string
&local_mirror_uuid
,
35 MirrorPeerClientMeta
*client_meta
,
36 librbd::asio::ContextWQ
*work_queue
)
37 : m_local_image_ctx(local_image_ctx
), m_remote_journaler(remote_journaler
),
38 m_local_mirror_uuid(local_mirror_uuid
), m_client_meta(client_meta
),
39 m_work_queue(work_queue
) {
43 EventPreprocessor
<I
>::~EventPreprocessor() {
44 ceph_assert(!m_in_progress
);
48 bool EventPreprocessor
<I
>::is_required(const EventEntry
&event_entry
) {
49 SnapSeqs
snap_seqs(m_client_meta
->snap_seqs
);
50 return (prune_snap_map(&snap_seqs
) ||
51 event_entry
.get_event_type() ==
52 librbd::journal::EVENT_TYPE_SNAP_RENAME
);
56 void EventPreprocessor
<I
>::preprocess(EventEntry
*event_entry
,
58 ceph_assert(!m_in_progress
);
60 m_event_entry
= event_entry
;
61 m_on_finish
= on_finish
;
67 void EventPreprocessor
<I
>::refresh_image() {
70 Context
*ctx
= create_context_callback
<
71 EventPreprocessor
<I
>, &EventPreprocessor
<I
>::handle_refresh_image
>(this);
72 m_local_image_ctx
.state
->refresh(ctx
);
76 void EventPreprocessor
<I
>::handle_refresh_image(int r
) {
77 dout(20) << "r=" << r
<< dendl
;
80 derr
<< "error encountered during image refresh: " << cpp_strerror(r
)
90 void EventPreprocessor
<I
>::preprocess_event() {
93 m_snap_seqs
= m_client_meta
->snap_seqs
;
94 m_snap_seqs_updated
= prune_snap_map(&m_snap_seqs
);
96 int r
= boost::apply_visitor(PreprocessEventVisitor(this),
97 m_event_entry
->event
);
106 template <typename I
>
107 int EventPreprocessor
<I
>::preprocess_snap_rename(
108 librbd::journal::SnapRenameEvent
&event
) {
109 dout(20) << "remote_snap_id=" << event
.snap_id
<< ", "
110 << "src_snap_name=" << event
.src_snap_name
<< ", "
111 << "dest_snap_name=" << event
.dst_snap_name
<< dendl
;
113 auto snap_seq_it
= m_snap_seqs
.find(event
.snap_id
);
114 if (snap_seq_it
!= m_snap_seqs
.end()) {
115 dout(20) << "remapping remote snap id " << snap_seq_it
->first
<< " "
116 << "to local snap id " << snap_seq_it
->second
<< dendl
;
117 event
.snap_id
= snap_seq_it
->second
;
121 auto snap_id_it
= m_local_image_ctx
.snap_ids
.find({cls::rbd::UserSnapshotNamespace(),
122 event
.src_snap_name
});
123 if (snap_id_it
== m_local_image_ctx
.snap_ids
.end()) {
124 dout(20) << "cannot map remote snapshot '" << event
.src_snap_name
<< "' "
125 << "to local snapshot" << dendl
;
126 event
.snap_id
= CEPH_NOSNAP
;
130 dout(20) << "mapping remote snap id " << event
.snap_id
<< " "
131 << "to local snap id " << snap_id_it
->second
<< dendl
;
132 m_snap_seqs_updated
= true;
133 m_snap_seqs
[event
.snap_id
] = snap_id_it
->second
;
134 event
.snap_id
= snap_id_it
->second
;
138 template <typename I
>
139 void EventPreprocessor
<I
>::update_client() {
140 if (!m_snap_seqs_updated
) {
146 librbd::journal::MirrorPeerClientMeta
client_meta(*m_client_meta
);
147 client_meta
.snap_seqs
= m_snap_seqs
;
149 librbd::journal::ClientData
client_data(client_meta
);
151 encode(client_data
, data_bl
);
153 Context
*ctx
= create_context_callback
<
154 EventPreprocessor
<I
>, &EventPreprocessor
<I
>::handle_update_client
>(
156 m_remote_journaler
.update_client(data_bl
, ctx
);
159 template <typename I
>
160 void EventPreprocessor
<I
>::handle_update_client(int r
) {
161 dout(20) << "r=" << r
<< dendl
;
164 derr
<< "failed to update mirror peer journal client: "
165 << cpp_strerror(r
) << dendl
;
170 m_client_meta
->snap_seqs
= m_snap_seqs
;
174 template <typename I
>
175 bool EventPreprocessor
<I
>::prune_snap_map(SnapSeqs
*snap_seqs
) {
178 std::shared_lock image_locker
{m_local_image_ctx
.image_lock
};
179 for (auto it
= snap_seqs
->begin(); it
!= snap_seqs
->end(); ) {
180 auto current_it(it
++);
181 if (m_local_image_ctx
.snap_info
.count(current_it
->second
) == 0) {
182 snap_seqs
->erase(current_it
);
189 template <typename I
>
190 void EventPreprocessor
<I
>::finish(int r
) {
191 dout(20) << "r=" << r
<< dendl
;
193 Context
*on_finish
= m_on_finish
;
194 m_on_finish
= nullptr;
195 m_event_entry
= nullptr;
196 m_in_progress
= false;
197 m_snap_seqs_updated
= false;
198 m_work_queue
->queue(on_finish
, r
);
201 } // namespace journal
202 } // namespace image_replayer
203 } // namespace mirror
206 template class rbd::mirror::image_replayer::journal::EventPreprocessor
<librbd::ImageCtx
>;