const std::string &local_mirror_uuid,
const std::string &remote_mirror_uuid,
Journaler *journaler,
+ cls::journal::ClientState *client_state,
MirrorPeerClientMeta *client_meta,
Context *on_finish,
bool *do_resync,
m_timer(timer), m_timer_lock(timer_lock),
m_local_mirror_uuid(local_mirror_uuid),
m_remote_mirror_uuid(remote_mirror_uuid), m_journaler(journaler),
- m_client_meta(client_meta), m_progress_ctx(progress_ctx),
- m_do_resync(do_resync),
+ m_client_state(client_state), m_client_meta(client_meta),
+ m_progress_ctx(progress_ctx), m_do_resync(do_resync),
m_lock(unique_lock_name("BootstrapRequest::m_lock", this)) {
}
return;
}
- get_client();
-}
-
-template <typename I>
-void BootstrapRequest<I>::get_client() {
- dout(20) << dendl;
-
- update_progress("GET_CLIENT");
-
- Context *ctx = create_context_callback<
- BootstrapRequest<I>, &BootstrapRequest<I>::handle_get_client>(
- this);
- m_journaler->get_client(m_local_mirror_uuid, &m_client, ctx);
-}
-
-template <typename I>
-void BootstrapRequest<I>::handle_get_client(int r) {
- dout(20) << ": r=" << r << dendl;
-
- if (r == -ENOENT) {
- dout(10) << ": client not registered" << dendl;
- } else if (r < 0) {
- derr << ": failed to retrieve client: " << cpp_strerror(r) << dendl;
- m_ret_val = r;
- close_remote_image();
- return;
- } else if (decode_client_meta()) {
- // skip registration if it already exists
- is_primary();
- return;
- }
-
- register_client();
-}
-
-template <typename I>
-void BootstrapRequest<I>::register_client() {
- dout(20) << dendl;
-
- update_progress("REGISTER_CLIENT");
-
- 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_context_callback<
- BootstrapRequest<I>, &BootstrapRequest<I>::handle_register_client>(
- this);
- m_journaler->register_client(client_data_bl, ctx);
-}
-
-template <typename I>
-void BootstrapRequest<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;
- m_ret_val = r;
- close_remote_image();
- return;
- }
-
- m_client = {};
- *m_client_meta = librbd::journal::MirrorPeerClientMeta(m_local_image_id);
- m_client_meta->state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
-
is_primary();
}
return;
}
+ if (!m_client_meta->image_id.empty()) {
+ // have an image id -- use that to open the image since a deletion (resync)
+ // will leave the old image id registered in the peer
+ m_local_image_id = m_client_meta->image_id;
+ }
+
if (m_local_image_id.empty()) {
update_client_image();
return;
return;
}
- if (m_client.state == cls::journal::CLIENT_STATE_DISCONNECTED) {
+ if (*m_client_state == cls::journal::CLIENT_STATE_DISCONNECTED) {
dout(10) << ": client flagged disconnected -- skipping bootstrap" << dendl;
// The caller is expected to detect disconnect initializing remote journal.
m_ret_val = 0;
register_client();
}
+template <typename I>
+void BootstrapRequest<I>::register_client() {
+ dout(20) << dendl;
+
+ update_progress("REGISTER_CLIENT");
+
+ 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_context_callback<
+ BootstrapRequest<I>, &BootstrapRequest<I>::handle_register_client>(
+ this);
+ m_journaler->register_client(client_data_bl, ctx);
+}
+
+template <typename I>
+void BootstrapRequest<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;
+ m_ret_val = r;
+ close_remote_image();
+ 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;
+
+ is_primary();
+}
+
template <typename I>
void BootstrapRequest<I>::update_client_image() {
dout(20) << dendl;
finish(m_ret_val);
}
-template <typename I>
-bool BootstrapRequest<I>::decode_client_meta() {
- dout(20) << dendl;
-
- librbd::journal::ClientData client_data;
- bufferlist::iterator it = m_client.data.begin();
- try {
- ::decode(client_data, it);
- } catch (const buffer::error &err) {
- derr << ": failed to decode client meta data: " << err.what() << dendl;
- return false;
- }
-
- librbd::journal::MirrorPeerClientMeta *client_meta =
- boost::get<librbd::journal::MirrorPeerClientMeta>(&client_data.client_meta);
- if (client_meta == nullptr) {
- derr << ": unknown peer registration" << dendl;
- return false;
- } else if (!client_meta->image_id.empty()) {
- // have an image id -- use that to open the image
- m_local_image_id = client_meta->image_id;
- }
-
- *m_client_meta = *client_meta;
-
- dout(20) << ": client found: image_id=" << m_local_image_id
- << ", client_meta=" << *m_client_meta << dendl;
- return true;
-}
-
template <typename I>
void BootstrapRequest<I>::update_progress(const std::string &description) {
dout(20) << ": " << description << dendl;