std::string local_image_id;
librbd::mirror::PromotionState local_promotion_state;
- std::string local_primary_mirror_uuid;
};
GetMirrorImageIdRequest<librbd::MockTestImageCtx>* GetMirrorImageIdRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
cls::rbd::MirrorImageMode mirror_image_mode =
cls::rbd::MIRROR_IMAGE_MODE_JOURNAL;
+ std::string local_primary_mirror_uuid;
+
static StateBuilder* create(const std::string&) {
ceph_assert(s_instance != nullptr);
return s_instance;
mock_journal_state_builder.mirror_image_mode);
ASSERT_EQ(librbd::mirror::PROMOTION_STATE_NON_PRIMARY,
mock_journal_state_builder.local_promotion_state);
- ASSERT_EQ(std::string("remote mirror uuid"),
- mock_journal_state_builder.local_primary_mirror_uuid);
}
TEST_F(TestMockImageReplayerPrepareLocalImageRequest, MirrorImageIdError) {
template<>
struct StateBuilder<librbd::MockTestImageCtx> {
std::string local_image_id;
+ librbd::mirror::PromotionState local_promotion_state =
+ librbd::mirror::PROMOTION_STATE_NON_PRIMARY;
std::string remote_image_id;
std::string remote_mirror_uuid;
librbd::mirror::PromotionState remote_promotion_state;
finish(r);
return;
} else if (r == -ENOENT || state_builder == nullptr) {
- dout(10) << "remote image does not exist" << dendl;
+ dout(10) << "remote image does not exist";
+ if (state_builder != nullptr) {
+ *_dout << ": "
+ << "local_image_id=" << state_builder->local_image_id << ", "
+ << "remote_image_id=" << state_builder->remote_image_id << ", "
+ << "is_linked=" << state_builder->is_linked();
+ }
+ *_dout << dendl;
// TODO need to support multiple remote images
if (state_builder != nullptr &&
switch (m_mirror_image.mode) {
case cls::rbd::MIRROR_IMAGE_MODE_JOURNAL:
// journal-based local image exists
- *m_state_builder = journal::StateBuilder<I>::create(m_global_image_id);
+ {
+ auto state_builder = journal::StateBuilder<I>::create(m_global_image_id);
+ state_builder->local_primary_mirror_uuid = m_primary_mirror_uuid;
+ *m_state_builder = state_builder;
+ }
break;
case cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT:
// snapshot-based local image exists
break;
}
+ dout(10) << "local_image_id=" << m_local_image_id << ", "
+ << "local_promotion_state=" << m_promotion_state << ", "
+ << "local_primary_mirror_uuid=" << m_primary_mirror_uuid << dendl;
(*m_state_builder)->local_image_id = m_local_image_id;
(*m_state_builder)->local_promotion_state = m_promotion_state;
- (*m_state_builder)->local_primary_mirror_uuid = m_primary_mirror_uuid;
finish(0);
}
dout(10) << "r=" << r << ", "
<< "remote_image_id=" << m_remote_image_id << dendl;
- if (r < 0) {
+ if (r == -ENOENT) {
+ finalize_snapshot_state_builder(r);
+ finish(r);
+ return;
+ } else if (r < 0) {
finish(r);
return;
}
if (r == -ENOENT) {
dout(10) << "image " << m_global_image_id << " not mirrored" << dendl;
+ finalize_snapshot_state_builder(r);
finish(r);
return;
} else if (r < 0) {
return;
} else if (m_promotion_state != librbd::mirror::PROMOTION_STATE_PRIMARY &&
(state_builder == nullptr ||
- state_builder->local_image_id.empty())) {
+ state_builder->local_image_id.empty() ||
+ state_builder->local_promotion_state ==
+ librbd::mirror::PROMOTION_STATE_UNKNOWN)) {
// no local image and remote isn't primary -- don't sync it
dout(5) << "remote image is not primary -- not syncing" << dendl;
finish(-EREMOTEIO);
get_client();
break;
case cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT:
- finalize_snapshot_state_builder();
+ finalize_snapshot_state_builder(0);
finish(0);
break;
default:
}
template <typename I>
-void PrepareRemoteImageRequest<I>::finalize_snapshot_state_builder() {
+void PrepareRemoteImageRequest<I>::finalize_snapshot_state_builder(int r) {
snapshot::StateBuilder<I>* state_builder = nullptr;
if (*m_state_builder != nullptr) {
- // already verified that it's a matching builder in
- // 'handle_get_mirror_info'
state_builder = dynamic_cast<snapshot::StateBuilder<I>*>(*m_state_builder);
- ceph_assert(state_builder != nullptr);
- } else {
+ } else if (r >= 0) {
state_builder = snapshot::StateBuilder<I>::create(m_global_image_id);
*m_state_builder = state_builder;
}
+ if (state_builder == nullptr) {
+ // local image prepare failed or is using journal-based mirroring
+ return;
+ }
+
+ dout(10) << "remote_mirror_uuid=" << m_remote_pool_meta.mirror_uuid << ", "
+ << "remote_mirror_peer_uuid="
+ << m_remote_pool_meta.mirror_peer_uuid << ", "
+ << "remote_image_id=" << m_remote_image_id << ", "
+ << "remote_promotion_state=" << m_promotion_state << dendl;
+ ceph_assert(state_builder != nullptr);
state_builder->remote_mirror_uuid = m_remote_pool_meta.mirror_uuid;
state_builder->remote_mirror_peer_uuid = m_remote_pool_meta.mirror_peer_uuid;
state_builder->remote_image_id = m_remote_image_id;
bufferlist m_out_bl;
std::string m_remote_image_id;
cls::rbd::MirrorImage m_mirror_image;
- librbd::mirror::PromotionState m_promotion_state;
+ librbd::mirror::PromotionState m_promotion_state =
+ librbd::mirror::PROMOTION_STATE_UNKNOWN;
std::string m_primary_mirror_uuid;
// journal-based mirroring
void finalize_journal_state_builder(cls::journal::ClientState client_state,
const MirrorPeerClientMeta& client_meta);
- void finalize_snapshot_state_builder();
+ void finalize_snapshot_state_builder(int r);
void finish(int r);
};
template <typename I>
bool StateBuilder<I>::is_linked() const {
- ceph_assert(!remote_mirror_uuid.empty());
return (local_promotion_state ==
- librbd::mirror::PROMOTION_STATE_NON_PRIMARY &&
- local_primary_mirror_uuid == remote_mirror_uuid);
+ librbd::mirror::PROMOTION_STATE_NON_PRIMARY);
}
template <typename I>
std::string local_image_id;
librbd::mirror::PromotionState local_promotion_state =
librbd::mirror::PROMOTION_STATE_PRIMARY;
- std::string local_primary_mirror_uuid;
ImageCtxT* local_image_ctx = nullptr;
std::string remote_mirror_uuid;
return (remote_client_state == cls::journal::CLIENT_STATE_DISCONNECTED);
}
+template <typename I>
+bool StateBuilder<I>::is_linked() const {
+ ceph_assert(!this->remote_mirror_uuid.empty());
+ return (image_replayer::StateBuilder<I>::is_linked() &&
+ local_primary_mirror_uuid == this->remote_mirror_uuid);
+}
+
template <typename I>
cls::rbd::MirrorImageMode StateBuilder<I>::get_mirror_image_mode() const {
return cls::rbd::MIRROR_IMAGE_MODE_JOURNAL;
void close(Context* on_finish) override;
bool is_disconnected() const override;
+ bool is_linked() const override;
cls::rbd::MirrorImageMode get_mirror_image_mode() const override;
PoolMetaCache* pool_meta_cache,
ReplayerListener* replayer_listener) override;
+ std::string local_primary_mirror_uuid;
+
Journaler* remote_journaler = nullptr;
cls::journal::ClientState remote_client_state =
cls::journal::CLIENT_STATE_CONNECTED;