]>
git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd_mirror/image_replayer/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 "common/WorkQueue.h"
9 #include "journal/Journaler.h"
10 #include "librbd/ImageCtx.h"
11 #include "librbd/ImageState.h"
12 #include "librbd/Utils.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::EventPreprocessor: " \
21 << this << " " << __func__
25 namespace image_replayer
{
27 using librbd::util::create_context_callback
;
30 EventPreprocessor
<I
>::EventPreprocessor(I
&local_image_ctx
,
31 Journaler
&remote_journaler
,
32 const std::string
&local_mirror_uuid
,
33 MirrorPeerClientMeta
*client_meta
,
34 ContextWQ
*work_queue
)
35 : m_local_image_ctx(local_image_ctx
), m_remote_journaler(remote_journaler
),
36 m_local_mirror_uuid(local_mirror_uuid
), m_client_meta(client_meta
),
37 m_work_queue(work_queue
) {
41 EventPreprocessor
<I
>::~EventPreprocessor() {
42 assert(!m_in_progress
);
46 bool EventPreprocessor
<I
>::is_required(const EventEntry
&event_entry
) {
47 SnapSeqs
snap_seqs(m_client_meta
->snap_seqs
);
48 return (prune_snap_map(&snap_seqs
) ||
49 event_entry
.get_event_type() ==
50 librbd::journal::EVENT_TYPE_SNAP_RENAME
);
54 void EventPreprocessor
<I
>::preprocess(EventEntry
*event_entry
,
56 assert(!m_in_progress
);
58 m_event_entry
= event_entry
;
59 m_on_finish
= on_finish
;
65 void EventPreprocessor
<I
>::refresh_image() {
68 Context
*ctx
= create_context_callback
<
69 EventPreprocessor
<I
>, &EventPreprocessor
<I
>::handle_refresh_image
>(this);
70 m_local_image_ctx
.state
->refresh(ctx
);
74 void EventPreprocessor
<I
>::handle_refresh_image(int r
) {
75 dout(20) << ": r=" << r
<< dendl
;
78 derr
<< "error encountered during image refresh: " << cpp_strerror(r
)
88 void EventPreprocessor
<I
>::preprocess_event() {
91 m_snap_seqs
= m_client_meta
->snap_seqs
;
92 m_snap_seqs_updated
= prune_snap_map(&m_snap_seqs
);
94 int r
= boost::apply_visitor(PreprocessEventVisitor(this),
95 m_event_entry
->event
);
104 template <typename I
>
105 int EventPreprocessor
<I
>::preprocess_snap_rename(
106 librbd::journal::SnapRenameEvent
&event
) {
108 << "remote_snap_id=" << event
.snap_id
<< ", "
109 << "src_snap_name=" << event
.src_snap_name
<< ", "
110 << "dest_snap_name=" << event
.dst_snap_name
<< dendl
;
112 auto snap_seq_it
= m_snap_seqs
.find(event
.snap_id
);
113 if (snap_seq_it
!= m_snap_seqs
.end()) {
114 dout(20) << ": remapping remote snap id " << snap_seq_it
->first
<< " "
115 << "to local snap id " << snap_seq_it
->second
<< dendl
;
116 event
.snap_id
= snap_seq_it
->second
;
120 auto snap_id_it
= m_local_image_ctx
.snap_ids
.find({cls::rbd::UserSnapshotNamespace(),
121 event
.src_snap_name
});
122 if (snap_id_it
== m_local_image_ctx
.snap_ids
.end()) {
123 dout(20) << ": cannot map remote snapshot '" << event
.src_snap_name
<< "' "
124 << "to local snapshot" << dendl
;
125 event
.snap_id
= CEPH_NOSNAP
;
129 dout(20) << ": mapping remote snap id " << event
.snap_id
<< " "
130 << "to local snap id " << snap_id_it
->second
<< dendl
;
131 m_snap_seqs_updated
= true;
132 m_snap_seqs
[event
.snap_id
] = snap_id_it
->second
;
133 event
.snap_id
= snap_id_it
->second
;
137 template <typename I
>
138 void EventPreprocessor
<I
>::update_client() {
139 if (!m_snap_seqs_updated
) {
145 librbd::journal::MirrorPeerClientMeta
client_meta(*m_client_meta
);
146 client_meta
.snap_seqs
= m_snap_seqs
;
148 librbd::journal::ClientData
client_data(client_meta
);
150 ::encode(client_data
, data_bl
);
152 Context
*ctx
= create_context_callback
<
153 EventPreprocessor
<I
>, &EventPreprocessor
<I
>::handle_update_client
>(
155 m_remote_journaler
.update_client(data_bl
, ctx
);
158 template <typename I
>
159 void EventPreprocessor
<I
>::handle_update_client(int r
) {
160 dout(20) << ": r=" << r
<< dendl
;
163 derr
<< "failed to update mirror peer journal client: "
164 << cpp_strerror(r
) << dendl
;
169 m_client_meta
->snap_seqs
= m_snap_seqs
;
173 template <typename I
>
174 bool EventPreprocessor
<I
>::prune_snap_map(SnapSeqs
*snap_seqs
) {
177 RWLock::RLocker
snap_locker(m_local_image_ctx
.snap_lock
);
178 for (auto it
= snap_seqs
->begin(); it
!= snap_seqs
->end(); ) {
179 auto current_it(it
++);
180 if (m_local_image_ctx
.snap_info
.count(current_it
->second
) == 0) {
181 snap_seqs
->erase(current_it
);
188 template <typename I
>
189 void EventPreprocessor
<I
>::finish(int r
) {
190 dout(20) << ": r=" << r
<< dendl
;
192 Context
*on_finish
= m_on_finish
;
193 m_on_finish
= nullptr;
194 m_event_entry
= nullptr;
195 m_in_progress
= false;
196 m_snap_seqs_updated
= false;
197 m_work_queue
->queue(on_finish
, r
);
200 } // namespace image_replayer
201 } // namespace mirror
204 template class rbd::mirror::image_replayer::EventPreprocessor
<librbd::ImageCtx
>;