The remote mirror uuid is now polled automatically by a higher layer.
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
librados::IoCtx &,
const std::string &global_image_id,
const std::string &local_mirror_uuid,
+ const RemotePoolMeta& remote_pool_meta,
::journal::CacheManagerHandler *cache_manager_handler,
StateBuilder<librbd::MockTestImageCtx>** state_builder,
Context *on_finish) {
template<>
struct StateBuilder<librbd::MockTestImageCtx> {
std::string local_image_id;
- std::string remote_mirror_uuid;
std::string remote_image_id;
+ std::string remote_mirror_uuid;
virtual ~StateBuilder() {}
}));
}
- void expect_mirror_uuid_get(librados::IoCtx &io_ctx,
- const std::string &mirror_uuid, int r) {
- bufferlist bl;
- encode(mirror_uuid, bl);
-
- EXPECT_CALL(get_mock_io_ctx(io_ctx),
- exec(RBD_MIRRORING, _, StrEq("rbd"), StrEq("mirror_uuid_get"), _, _, _))
- .WillOnce(DoAll(WithArg<5>(Invoke([bl](bufferlist *out_bl) {
- *out_bl = bl;
- })),
- Return(r)));
- }
-
void expect_get_mirror_image(librados::IoCtx &io_ctx,
cls::rbd::MirrorImageMode mode, int r) {
cls::rbd::MirrorImage mirror_image;
MockThreads mock_threads(m_threads);
InSequence seq;
- expect_mirror_uuid_get(m_remote_io_ctx, "remote mirror uuid", 0);
MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
expect_get_mirror_image_id(mock_get_mirror_image_id_request,
"remote image id", 0);
m_remote_io_ctx,
"global image id",
"local mirror uuid",
+ {"remote mirror uuid", ""},
nullptr,
&mock_state_builder,
&ctx);
ASSERT_EQ(0, ctx.wait());
ASSERT_TRUE(mock_state_builder != nullptr);
- ASSERT_EQ(std::string("remote mirror uuid"),
- mock_journal_state_builder.remote_mirror_uuid);
ASSERT_EQ(std::string("remote image id"),
mock_journal_state_builder.remote_image_id);
ASSERT_TRUE(mock_journal_state_builder.remote_journaler != nullptr);
MockThreads mock_threads(m_threads);
InSequence seq;
- expect_mirror_uuid_get(m_remote_io_ctx, "remote mirror uuid", 0);
MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
expect_get_mirror_image_id(mock_get_mirror_image_id_request,
"remote image id", 0);
m_remote_io_ctx,
"global image id",
"local mirror uuid",
+ {"remote mirror uuid", ""},
nullptr,
&mock_state_builder,
&ctx);
ASSERT_EQ(0, ctx.wait());
ASSERT_TRUE(mock_state_builder != nullptr);
- ASSERT_EQ(std::string("remote mirror uuid"),
- mock_journal_state_builder.remote_mirror_uuid);
ASSERT_EQ(std::string("remote image id"),
mock_journal_state_builder.remote_image_id);
ASSERT_TRUE(mock_journal_state_builder.remote_journaler != nullptr);
mock_journal_state_builder.remote_client_state);
}
-TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, MirrorUuidError) {
- ::journal::MockJournaler mock_remote_journaler;
- MockThreads mock_threads(m_threads);
-
- InSequence seq;
- expect_mirror_uuid_get(m_remote_io_ctx, "", -EINVAL);
-
- MockJournalStateBuilder mock_journal_state_builder;
- MockStateBuilder* mock_state_builder = nullptr;
- C_SaferCond ctx;
- auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
- m_local_io_ctx,
- m_remote_io_ctx,
- "global image id",
- "local mirror uuid",
- nullptr,
- &mock_state_builder,
- &ctx);
- req->send();
-
- ASSERT_EQ(-EINVAL, ctx.wait());
- ASSERT_EQ(std::string(""), mock_journal_state_builder.remote_mirror_uuid);
- ASSERT_TRUE(mock_journal_state_builder.remote_journaler == nullptr);
-}
-
TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, MirrorImageIdError) {
::journal::MockJournaler mock_remote_journaler;
MockThreads mock_threads(m_threads);
InSequence seq;
- expect_mirror_uuid_get(m_remote_io_ctx, "remote mirror uuid", 0);
MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
expect_get_mirror_image_id(mock_get_mirror_image_id_request, "", -EINVAL);
m_remote_io_ctx,
"global image id",
"local mirror uuid",
+ {"remote mirror uuid", ""},
nullptr,
&mock_state_builder,
&ctx);
req->send();
ASSERT_EQ(-EINVAL, ctx.wait());
- ASSERT_EQ(std::string("remote mirror uuid"),
- mock_journal_state_builder.remote_mirror_uuid);
ASSERT_TRUE(mock_journal_state_builder.remote_journaler == nullptr);
}
MockThreads mock_threads(m_threads);
InSequence seq;
- expect_mirror_uuid_get(m_remote_io_ctx, "remote mirror uuid", 0);
MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
expect_get_mirror_image_id(mock_get_mirror_image_id_request,
"remote image id", 0);
m_remote_io_ctx,
"global image id",
"local mirror uuid",
+ {"remote mirror uuid", ""},
nullptr,
&mock_state_builder,
&ctx);
MockThreads mock_threads(m_threads);
InSequence seq;
- expect_mirror_uuid_get(m_remote_io_ctx, "remote mirror uuid", 0);
MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
expect_get_mirror_image_id(mock_get_mirror_image_id_request,
"remote image id", 0);
m_remote_io_ctx,
"global image id",
"local mirror uuid",
+ {"remote mirror uuid", ""},
nullptr,
&mock_state_builder,
&ctx);
MockThreads mock_threads(m_threads);
InSequence seq;
- expect_mirror_uuid_get(m_remote_io_ctx, "remote mirror uuid", 0);
MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
expect_get_mirror_image_id(mock_get_mirror_image_id_request,
"remote image id", 0);
m_remote_io_ctx,
"global image id",
"local mirror uuid",
+ {"remote mirror uuid", ""},
nullptr,
&mock_state_builder,
&ctx);
m_global_image_id, m_threads.get(),
m_instance_watcher, m_local_status_updater,
nullptr, &m_pool_meta_cache);
- m_replayer->add_peer({"peer uuid", m_remote_ioctx, {}, nullptr});
+ m_replayer->add_peer({"peer uuid", m_remote_ioctx,
+ {m_remote_mirror_uuid, "remote mirror peer uuid"},
+ nullptr});
}
void start()
BootstrapRequest, &BootstrapRequest<I>::handle_prepare_remote_image>(this);
auto req = image_replayer::PrepareRemoteImageRequest<I>::create(
m_threads, m_local_io_ctx, m_remote_io_ctx, m_global_image_id,
- m_local_mirror_uuid, m_cache_manager_handler, m_state_builder, ctx);
+ m_local_mirror_uuid, m_remote_pool_meta, m_cache_manager_handler,
+ m_state_builder, ctx);
req->send();
}
dout(10) << "r=" << r << dendl;
auto state_builder = *m_state_builder;
+ ceph_assert(state_builder == nullptr ||
+ !state_builder->remote_mirror_uuid.empty());
+
if (state_builder != nullptr && state_builder->is_local_primary()) {
dout(5) << "local image is primary" << dendl;
finish(-ENOMSG);
template <typename I>
void PrepareRemoteImageRequest<I>::send() {
- get_remote_mirror_uuid();
-}
-
-template <typename I>
-void PrepareRemoteImageRequest<I>::get_remote_mirror_uuid() {
- dout(10) << dendl;
-
- librados::ObjectReadOperation op;
- librbd::cls_client::mirror_uuid_get_start(&op);
-
- librados::AioCompletion *aio_comp = create_rados_callback<
- PrepareRemoteImageRequest<I>,
- &PrepareRemoteImageRequest<I>::handle_get_remote_mirror_uuid>(this);
- int r = m_remote_io_ctx.aio_operate(RBD_MIRRORING, aio_comp, &op, &m_out_bl);
- ceph_assert(r == 0);
- aio_comp->release();
-}
-
-template <typename I>
-void PrepareRemoteImageRequest<I>::handle_get_remote_mirror_uuid(int r) {
- if (r >= 0) {
- auto it = m_out_bl.cbegin();
- r = librbd::cls_client::mirror_uuid_get_finish(&it, &m_remote_mirror_uuid);
- if (r >= 0 && m_remote_mirror_uuid.empty()) {
- r = -ENOENT;
- }
- }
-
- dout(10) << "r=" << r << dendl;
- if (r < 0) {
- if (r == -ENOENT) {
- dout(5) << "remote mirror uuid missing" << dendl;
- } else {
- derr << "failed to retrieve remote mirror uuid: " << cpp_strerror(r)
- << dendl;
- }
- finish(r);
- return;
- }
-
- auto state_builder = *m_state_builder;
- if (state_builder != nullptr) {
- // if the local image exists but the remote image doesn't, we still
- // want to populate the remote mirror uuid that we've looked up
- state_builder->remote_mirror_uuid = m_remote_mirror_uuid;
+ if (*m_state_builder != nullptr) {
+ (*m_state_builder)->remote_mirror_uuid = m_remote_pool_meta.mirror_uuid;
}
get_remote_image_id();
*m_state_builder = state_builder;
}
- state_builder->remote_mirror_uuid = m_remote_mirror_uuid;
+ state_builder->remote_mirror_uuid = m_remote_pool_meta.mirror_uuid;
state_builder->remote_image_id = m_remote_image_id;
state_builder->remote_journaler = m_remote_journaler;
state_builder->remote_client_state = client_state;
#include "journal/Settings.h"
#include "librbd/journal/Types.h"
#include "librbd/journal/TypeTraits.h"
+#include "tools/rbd_mirror/Types.h"
#include <string>
namespace journal { class Journaler; }
librados::IoCtx &remote_io_ctx,
const std::string &global_image_id,
const std::string &local_mirror_uuid,
+ const RemotePoolMeta& remote_pool_meta,
::journal::CacheManagerHandler *cache_manager_handler,
StateBuilder<ImageCtxT>** state_builder,
Context *on_finish) {
return new PrepareRemoteImageRequest(threads, local_io_ctx, remote_io_ctx,
global_image_id, local_mirror_uuid,
+ remote_pool_meta,
cache_manager_handler, state_builder,
on_finish);
}
librados::IoCtx &remote_io_ctx,
const std::string &global_image_id,
const std::string &local_mirror_uuid,
+ const RemotePoolMeta& remote_pool_meta,
::journal::CacheManagerHandler *cache_manager_handler,
StateBuilder<ImageCtxT>** state_builder,
Context *on_finish)
m_remote_io_ctx(remote_io_ctx),
m_global_image_id(global_image_id),
m_local_mirror_uuid(local_mirror_uuid),
+ m_remote_pool_meta(remote_pool_meta),
m_cache_manager_handler(cache_manager_handler),
m_state_builder(state_builder),
m_on_finish(on_finish) {
* <start>
* |
* v
- * GET_REMOTE_MIRROR_UUID
- * |
- * v
* GET_REMOTE_IMAGE_ID
* |
* v
librados::IoCtx &m_remote_io_ctx;
std::string m_global_image_id;
std::string m_local_mirror_uuid;
+ RemotePoolMeta m_remote_pool_meta;
::journal::CacheManagerHandler *m_cache_manager_handler;
StateBuilder<ImageCtxT>** m_state_builder;
Context *m_on_finish;
bufferlist m_out_bl;
- std::string m_remote_mirror_uuid;
std::string m_remote_image_id;
// journal-based mirroring
Journaler *m_remote_journaler = nullptr;
cls::journal::Client m_client;
- void get_remote_mirror_uuid();
- void handle_get_remote_mirror_uuid(int r);
-
void get_remote_image_id();
void handle_get_remote_image_id(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);