This removes all journal-specific code from the image sync path.
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
#include "tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h"
#include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.h"
#include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h"
+#include "tools/rbd_mirror/image_replayer/StateBuilder.h"
#include "tools/rbd_mirror/image_replayer/journal/CreateLocalImageRequest.h"
#include "tools/rbd_mirror/image_replayer/journal/PrepareReplayRequest.h"
+#include "tools/rbd_mirror/image_replayer/journal/StateBuilder.h"
#include "test/journal/mock/MockJournaler.h"
#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
#include "test/librbd/mock/MockImageCtx.h"
#include "test/librbd/mock/MockJournal.h"
+#include "test/rbd_mirror/mock/image_sync/MockSyncPointHandler.h"
namespace librbd {
Context *on_finish = nullptr;
static ImageSync* create(
+ Threads<librbd::MockTestImageCtx>* threads,
librbd::MockTestImageCtx *local_image_ctx,
librbd::MockTestImageCtx *remote_image_ctx,
- SafeTimer *timer, ceph::mutex *timer_lock,
- const std::string &mirror_uuid, ::journal::MockJournaler *journaler,
- librbd::journal::MirrorPeerClientMeta *client_meta, ContextWQ *work_queue,
+ const std::string &local_mirror_uuid,
+ image_sync::SyncPointHandler* sync_point_handler,
InstanceWatcher<librbd::MockTestImageCtx> *instance_watcher,
- Context *on_finish, ProgressContext *progress_ctx) {
+ ProgressContext *progress_ctx, Context *on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->on_finish = on_finish;
return s_instance;
MOCK_METHOD0(send, void());
};
+template<>
+struct StateBuilder<librbd::MockTestImageCtx> {
+ virtual ~StateBuilder() {}
+
+ void destroy_sync_point_handler() {
+ }
+ void destroy() {
+ }
+};
+
CloseImageRequest<librbd::MockTestImageCtx>*
CloseImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
OpenImageRequest<librbd::MockTestImageCtx>*
MOCK_METHOD0(send, void());
};
+template<>
+struct StateBuilder<librbd::MockTestImageCtx>
+ : image_replayer::StateBuilder<librbd::MockTestImageCtx>{
+ static StateBuilder* s_instance;
+
+ ::journal::MockJournaler* remote_journaler = nullptr;
+ librbd::journal::MirrorPeerClientMeta remote_client_meta;
+
+ image_sync::MockSyncPointHandler mock_sync_point_handler;
+
+ static StateBuilder* create(const std::string&) {
+ ceph_assert(s_instance != nullptr);
+ return s_instance;
+ }
+
+ image_sync::MockSyncPointHandler* create_sync_point_handler() {
+ return &mock_sync_point_handler;
+ }
+
+ StateBuilder() {
+ s_instance = this;
+ }
+};
+
CreateLocalImageRequest<librbd::MockTestImageCtx>*
CreateLocalImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
PrepareReplayRequest<librbd::MockTestImageCtx>*
PrepareReplayRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
+StateBuilder<librbd::MockTestImageCtx>*
+ StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr;
} // namespace journal
} // namespace image_replayer
typedef PrepareRemoteImageRequest<librbd::MockTestImageCtx> MockPrepareRemoteImageRequest;
typedef journal::CreateLocalImageRequest<librbd::MockTestImageCtx> MockCreateLocalImageRequest;
typedef journal::PrepareReplayRequest<librbd::MockTestImageCtx> MockPrepareReplayRequest;
+ typedef journal::StateBuilder<librbd::MockTestImageCtx> MockStateBuilder;
typedef librbd::mirror::GetInfoRequest<librbd::MockTestImageCtx> MockGetMirrorInfoRequest;
typedef std::list<cls::journal::Tag> Tags;
expect_prepare_replay(mock_prepare_replay_request, false, true, 0);
// image sync
+ MockStateBuilder mock_state_builder;
MockImageSync mock_image_sync;
expect_image_sync(mock_image_sync, 0);
expect_prepare_replay(mock_prepare_replay_request, false, true, 0);
// image sync
+ MockStateBuilder mock_state_builder;
MockImageSync mock_image_sync;
expect_image_sync(mock_image_sync, -EINVAL);
#include "test/rbd_mirror/test_mock_fixture.h"
#include "include/rbd/librbd.hpp"
-#include "librbd/journal/Types.h"
-#include "librbd/journal/TypeTraits.h"
-#include "test/journal/mock/MockJournaler.h"
#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
#include "test/librbd/mock/MockImageCtx.h"
+#include "test/rbd_mirror/mock/image_sync/MockSyncPointHandler.h"
#include "tools/rbd_mirror/image_sync/SyncPointCreateRequest.h"
namespace librbd {
} // anonymous namespace
-namespace journal {
-
-template <>
-struct TypeTraits<librbd::MockTestImageCtx> {
- typedef ::journal::MockJournaler Journaler;
-};
-
-} // namespace journal
} // namespace librbd
// template definitions
#include "tools/rbd_mirror/image_sync/SyncPointCreateRequest.cc"
-template class rbd::mirror::image_sync::SyncPointCreateRequest<librbd::MockTestImageCtx>;
namespace rbd {
namespace mirror {
namespace image_sync {
using ::testing::_;
+using ::testing::DoAll;
using ::testing::InSequence;
+using ::testing::Invoke;
+using ::testing::Return;
using ::testing::WithArg;
class TestMockImageSyncSyncPointCreateRequest : public TestMockFixture {
ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
}
- void expect_update_client(journal::MockJournaler &mock_journaler, int r) {
- EXPECT_CALL(mock_journaler, update_client(_, _))
- .WillOnce(WithArg<1>(CompleteContext(r)));
+ void expect_get_snap_seqs(MockSyncPointHandler& mock_sync_point_handler) {
+ EXPECT_CALL(mock_sync_point_handler, get_snap_seqs())
+ .WillRepeatedly(Return(librbd::SnapSeqs{}));
+ }
+
+ void expect_get_sync_points(MockSyncPointHandler& mock_sync_point_handler) {
+ EXPECT_CALL(mock_sync_point_handler, get_sync_points())
+ .WillRepeatedly(Invoke([this]() {
+ return m_sync_points;
+ }));
+ }
+
+ void expect_update_sync_points(MockSyncPointHandler& mock_sync_point_handler,
+ int r) {
+ EXPECT_CALL(mock_sync_point_handler, update_sync_points(_, _, false, _))
+ .WillOnce(DoAll(WithArg<1>(Invoke([this, r](const SyncPoints& sync_points) {
+ if (r >= 0) {
+ m_sync_points = sync_points;
+ }
+ })),
+ WithArg<3>(CompleteContext(r))));
}
void expect_image_refresh(librbd::MockTestImageCtx &mock_remote_image_ctx, int r) {
}
MockSyncPointCreateRequest *create_request(librbd::MockTestImageCtx &mock_remote_image_ctx,
- journal::MockJournaler &mock_journaler,
+ MockSyncPointHandler& mock_sync_point_handler,
Context *ctx) {
return new MockSyncPointCreateRequest(&mock_remote_image_ctx, "uuid",
- &mock_journaler, &m_client_meta, ctx);
+ &mock_sync_point_handler, ctx);
}
librbd::ImageCtx *m_remote_image_ctx;
- librbd::journal::MirrorPeerClientMeta m_client_meta;
+ SyncPoints m_sync_points;
};
TEST_F(TestMockImageSyncSyncPointCreateRequest, Success) {
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
- expect_update_client(mock_journaler, 0);
+ expect_update_sync_points(mock_sync_point_handler, 0);
expect_image_refresh(mock_remote_image_ctx, 0);
expect_snap_create(mock_remote_image_ctx, 0);
expect_image_refresh(mock_remote_image_ctx, 0);
C_SaferCond ctx;
MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, &ctx);
+ mock_sync_point_handler,
+ &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
- ASSERT_EQ(1U, m_client_meta.sync_points.size());
+ ASSERT_EQ(1U, m_sync_points.size());
}
TEST_F(TestMockImageSyncSyncPointCreateRequest, ResyncSuccess) {
- m_client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "start snap",
- "",
- boost::none);
- auto sync_point = m_client_meta.sync_points.front();
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "start snap",
+ "", boost::none);
+ auto sync_point = m_sync_points.front();
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
- expect_update_client(mock_journaler, 0);
+ expect_update_sync_points(mock_sync_point_handler, 0);
expect_image_refresh(mock_remote_image_ctx, 0);
expect_snap_create(mock_remote_image_ctx, 0);
expect_image_refresh(mock_remote_image_ctx, 0);
C_SaferCond ctx;
MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, &ctx);
+ mock_sync_point_handler,
+ &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
- ASSERT_EQ(2U, m_client_meta.sync_points.size());
- ASSERT_EQ(sync_point, m_client_meta.sync_points.front());
- ASSERT_EQ("start snap", m_client_meta.sync_points.back().from_snap_name);
+ ASSERT_EQ(2U, m_sync_points.size());
+ ASSERT_EQ(sync_point, m_sync_points.front());
+ ASSERT_EQ("start snap", m_sync_points.back().from_snap_name);
}
TEST_F(TestMockImageSyncSyncPointCreateRequest, SnapshotExists) {
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
- expect_update_client(mock_journaler, 0);
+ expect_update_sync_points(mock_sync_point_handler, 0);
expect_image_refresh(mock_remote_image_ctx, 0);
expect_snap_create(mock_remote_image_ctx, -EEXIST);
- expect_update_client(mock_journaler, 0);
+ expect_update_sync_points(mock_sync_point_handler, 0);
expect_image_refresh(mock_remote_image_ctx, 0);
expect_snap_create(mock_remote_image_ctx, 0);
expect_image_refresh(mock_remote_image_ctx, 0);
C_SaferCond ctx;
MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, &ctx);
+ mock_sync_point_handler,
+ &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
- ASSERT_EQ(1U, m_client_meta.sync_points.size());
+ ASSERT_EQ(1U, m_sync_points.size());
}
TEST_F(TestMockImageSyncSyncPointCreateRequest, ClientUpdateError) {
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
- expect_update_client(mock_journaler, -EINVAL);
+ expect_update_sync_points(mock_sync_point_handler, -EINVAL);
C_SaferCond ctx;
MockSyncPointCreateRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, &ctx);
+ mock_sync_point_handler,
+ &ctx);
req->send();
ASSERT_EQ(-EINVAL, ctx.wait());
- ASSERT_TRUE(m_client_meta.sync_points.empty());
+ ASSERT_TRUE(m_sync_points.empty());
}
} // namespace image_sync
#include "test/rbd_mirror/test_mock_fixture.h"
#include "include/rbd/librbd.hpp"
-#include "librbd/journal/Types.h"
-#include "librbd/journal/TypeTraits.h"
-#include "test/journal/mock/MockJournaler.h"
#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
#include "test/librbd/mock/MockImageCtx.h"
+#include "test/rbd_mirror/mock/image_sync/MockSyncPointHandler.h"
#include "tools/rbd_mirror/image_sync/SyncPointPruneRequest.h"
namespace librbd {
} // anonymous namespace
-namespace journal {
-
-template <>
-struct TypeTraits<librbd::MockTestImageCtx> {
- typedef ::journal::MockJournaler Journaler;
-};
-
-} // namespace journal
} // namespace librbd
// template definitions
namespace image_sync {
using ::testing::_;
+using ::testing::DoAll;
using ::testing::InSequence;
+using ::testing::Invoke;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::WithArg;
ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
}
- void expect_update_client(journal::MockJournaler &mock_journaler, int r) {
- EXPECT_CALL(mock_journaler, update_client(_, _))
- .WillOnce(WithArg<1>(CompleteContext(r)));
+ void expect_get_snap_seqs(MockSyncPointHandler& mock_sync_point_handler) {
+ EXPECT_CALL(mock_sync_point_handler, get_snap_seqs())
+ .WillRepeatedly(Return(librbd::SnapSeqs{}));
+ }
+
+ void expect_get_sync_points(MockSyncPointHandler& mock_sync_point_handler) {
+ EXPECT_CALL(mock_sync_point_handler, get_sync_points())
+ .WillRepeatedly(Invoke([this]() {
+ return m_sync_points;
+ }));
+ }
+
+ void expect_update_sync_points(MockSyncPointHandler& mock_sync_point_handler,
+ bool complete, int r) {
+ EXPECT_CALL(mock_sync_point_handler, update_sync_points(_, _, complete, _))
+ .WillOnce(DoAll(WithArg<1>(Invoke([this, r](const SyncPoints& sync_points) {
+ if (r >= 0) {
+ m_sync_points = sync_points;
+ }
+ })),
+ WithArg<3>(CompleteContext(r))));
}
void expect_get_snap_id(librbd::MockTestImageCtx &mock_remote_image_ctx,
}
MockSyncPointPruneRequest *create_request(librbd::MockTestImageCtx &mock_remote_image_ctx,
- journal::MockJournaler &mock_journaler,
+ MockSyncPointHandler& mock_sync_point_handler,
bool sync_complete, Context *ctx) {
return new MockSyncPointPruneRequest(&mock_remote_image_ctx, sync_complete,
- &mock_journaler, &m_client_meta, ctx);
+ &mock_sync_point_handler, ctx);
}
librbd::ImageCtx *m_remote_image_ctx;
- librbd::journal::MirrorPeerClientMeta m_client_meta;
+ SyncPoints m_sync_points;
};
TEST_F(TestMockImageSyncSyncPointPruneRequest, SyncInProgressSuccess) {
- librbd::journal::MirrorPeerClientMeta client_meta;
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap1",
- boost::none);
- m_client_meta = client_meta;
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap1",
+ "", boost::none);
+ auto sync_points = m_sync_points;
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
expect_get_snap_id(mock_remote_image_ctx, "snap1", 123);
expect_image_refresh(mock_remote_image_ctx, 0);
- expect_update_client(mock_journaler, 0);
+ expect_update_sync_points(mock_sync_point_handler, false, 0);
C_SaferCond ctx;
MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, false, &ctx);
+ mock_sync_point_handler,
+ false, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
- ASSERT_EQ(client_meta, m_client_meta);
+ ASSERT_EQ(sync_points, m_sync_points);
}
TEST_F(TestMockImageSyncSyncPointPruneRequest, RestartedSyncInProgressSuccess) {
- librbd::journal::MirrorPeerClientMeta client_meta;
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap2",
- "snap1", boost::none);
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap1",
- boost::none);
- m_client_meta = client_meta;
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap2",
+ "snap1", boost::none);
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap1", "",
+ boost::none);
+ auto sync_points = m_sync_points;
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
expect_get_snap_id(mock_remote_image_ctx, "snap1", 123);
expect_snap_remove(mock_remote_image_ctx, "snap2", 0);
expect_image_refresh(mock_remote_image_ctx, 0);
- expect_update_client(mock_journaler, 0);
+ expect_update_sync_points(mock_sync_point_handler, false, 0);
C_SaferCond ctx;
MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, false, &ctx);
+ mock_sync_point_handler,
+ false, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
- client_meta.sync_points.pop_back();
- ASSERT_EQ(client_meta, m_client_meta);
+ sync_points.pop_back();
+ ASSERT_EQ(sync_points, m_sync_points);
}
TEST_F(TestMockImageSyncSyncPointPruneRequest, SyncInProgressMissingSnapSuccess) {
- librbd::journal::MirrorPeerClientMeta client_meta;
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap2",
- "snap1",
- boost::none);
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap1",
- boost::none);
- m_client_meta = client_meta;
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap2",
+ "snap1", boost::none);
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap1", "",
+ boost::none);
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
expect_get_snap_id(mock_remote_image_ctx, "snap1", CEPH_NOSNAP);
expect_snap_remove(mock_remote_image_ctx, "snap2", 0);
expect_snap_remove(mock_remote_image_ctx, "snap1", 0);
expect_image_refresh(mock_remote_image_ctx, 0);
- expect_update_client(mock_journaler, 0);
+ expect_update_sync_points(mock_sync_point_handler, false, 0);
C_SaferCond ctx;
MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, false, &ctx);
+ mock_sync_point_handler,
+ false, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
- client_meta.sync_points.clear();
- ASSERT_EQ(client_meta, m_client_meta);
+ ASSERT_EQ(SyncPoints{}, m_sync_points);
}
TEST_F(TestMockImageSyncSyncPointPruneRequest, SyncInProgressUnexpectedFromSnapSuccess) {
- librbd::journal::MirrorPeerClientMeta client_meta;
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap2",
- "snap1",
- boost::none);
- m_client_meta = client_meta;
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap2",
+ "snap1", boost::none);
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
expect_get_snap_id(mock_remote_image_ctx, "snap2", 124);
expect_snap_remove(mock_remote_image_ctx, "snap2", 0);
expect_snap_remove(mock_remote_image_ctx, "snap1", 0);
expect_image_refresh(mock_remote_image_ctx, 0);
- expect_update_client(mock_journaler, 0);
+ expect_update_sync_points(mock_sync_point_handler, false, 0);
C_SaferCond ctx;
MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, false, &ctx);
+ mock_sync_point_handler,
+ false, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
- client_meta.sync_points.clear();
- ASSERT_EQ(client_meta, m_client_meta);
+ ASSERT_EQ(SyncPoints(), m_sync_points);
}
TEST_F(TestMockImageSyncSyncPointPruneRequest, SyncCompleteSuccess) {
- librbd::journal::MirrorPeerClientMeta client_meta;
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap1",
- boost::none);
- m_client_meta = client_meta;
- ASSERT_EQ(librbd::journal::MIRROR_PEER_STATE_SYNCING, m_client_meta.state);
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap1",
+ "", boost::none);
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
expect_snap_remove(mock_remote_image_ctx, "snap1", 0);
expect_image_refresh(mock_remote_image_ctx, 0);
- expect_update_client(mock_journaler, 0);
+ expect_update_sync_points(mock_sync_point_handler, true, 0);
C_SaferCond ctx;
MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, true, &ctx);
+ mock_sync_point_handler,
+ true, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
- ASSERT_TRUE(m_client_meta.sync_points.empty());
- ASSERT_EQ(librbd::journal::MIRROR_PEER_STATE_REPLAYING, m_client_meta.state);
+ ASSERT_TRUE(m_sync_points.empty());
}
TEST_F(TestMockImageSyncSyncPointPruneRequest, RestartedSyncCompleteSuccess) {
- librbd::journal::MirrorPeerClientMeta client_meta;
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap2",
- "snap1",
- boost::none);
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap1",
- boost::none);
- m_client_meta = client_meta;
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap2",
+ "snap1", boost::none);
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap1",
+ "", boost::none);
+ auto sync_points = m_sync_points;
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
expect_image_refresh(mock_remote_image_ctx, 0);
- expect_update_client(mock_journaler, 0);
+ expect_update_sync_points(mock_sync_point_handler, true, 0);
C_SaferCond ctx;
MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, true, &ctx);
+ mock_sync_point_handler,
+ true, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
- client_meta.sync_points.pop_front();
- ASSERT_EQ(client_meta, m_client_meta);
+ sync_points.pop_front();
+ ASSERT_EQ(sync_points, m_sync_points);
}
TEST_F(TestMockImageSyncSyncPointPruneRequest, RestartedCatchUpSyncCompleteSuccess) {
- librbd::journal::MirrorPeerClientMeta client_meta;
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap3",
- "snap2",
- boost::none);
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap2",
- "snap1",
- boost::none);
- m_client_meta = client_meta;
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap3",
+ "snap2", boost::none);
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap2",
+ "snap1", boost::none);
+ auto sync_points = m_sync_points;
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
expect_snap_remove(mock_remote_image_ctx, "snap1", 0);
expect_image_refresh(mock_remote_image_ctx, 0);
- expect_update_client(mock_journaler, 0);
+ expect_update_sync_points(mock_sync_point_handler, true, 0);
C_SaferCond ctx;
MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, true, &ctx);
+ mock_sync_point_handler,
+ true, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
- client_meta.sync_points.pop_front();
- ASSERT_EQ(client_meta, m_client_meta);
+ sync_points.pop_front();
+ ASSERT_EQ(sync_points, m_sync_points);
}
TEST_F(TestMockImageSyncSyncPointPruneRequest, SnapshotDNE) {
- librbd::journal::MirrorPeerClientMeta client_meta;
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap1",
- boost::none);
- m_client_meta = client_meta;
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap1",
+ "", boost::none);
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
expect_snap_remove(mock_remote_image_ctx, "snap1", -ENOENT);
expect_image_refresh(mock_remote_image_ctx, 0);
- expect_update_client(mock_journaler, 0);
+ expect_update_sync_points(mock_sync_point_handler, true, 0);
C_SaferCond ctx;
MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, true, &ctx);
+ mock_sync_point_handler,
+ true, &ctx);
req->send();
ASSERT_EQ(0, ctx.wait());
- ASSERT_TRUE(m_client_meta.sync_points.empty());
+ ASSERT_TRUE(m_sync_points.empty());
}
TEST_F(TestMockImageSyncSyncPointPruneRequest, ClientUpdateError) {
- librbd::journal::MirrorPeerClientMeta client_meta;
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap2",
- "snap1",
- boost::none);
- client_meta.sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(),
- "snap1",
- boost::none);
- m_client_meta = client_meta;
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap2",
+ "snap1", boost::none);
+ m_sync_points.emplace_front(cls::rbd::UserSnapshotNamespace(), "snap1",
+ "", boost::none);
+ auto sync_points = m_sync_points;
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
expect_image_refresh(mock_remote_image_ctx, 0);
- expect_update_client(mock_journaler, -EINVAL);
+ expect_update_sync_points(mock_sync_point_handler, true, -EINVAL);
C_SaferCond ctx;
MockSyncPointPruneRequest *req = create_request(mock_remote_image_ctx,
- mock_journaler, true, &ctx);
+ mock_sync_point_handler,
+ true, &ctx);
req->send();
ASSERT_EQ(-EINVAL, ctx.wait());
- ASSERT_EQ(client_meta, m_client_meta);
+ ASSERT_EQ(sync_points, m_sync_points);
}
} // namespace image_sync
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_MOCK_IMAGE_SYNC_SYNC_POINT_HANDLER_H
+#define CEPH_MOCK_IMAGE_SYNC_SYNC_POINT_HANDLER_H
+
+#include "tools/rbd_mirror/image_sync/Types.h"
+#include <gmock/gmock.h>
+
+struct Context;
+
+namespace rbd {
+namespace mirror {
+namespace image_sync {
+
+struct MockSyncPointHandler : public SyncPointHandler{
+ MOCK_CONST_METHOD0(get_sync_points, SyncPoints());
+ MOCK_CONST_METHOD0(get_snap_seqs, librbd::SnapSeqs());
+
+ MOCK_METHOD4(update_sync_points, void(const librbd::SnapSeqs&,
+ const SyncPoints&,
+ bool, Context*));
+};
+
+} // namespace image_sync
+} // namespace mirror
+} // namespace rbd
+
+#endif // CEPH_MOCK_IMAGE_SYNC_SYNC_POINT_HANDLER_H
#include "tools/rbd_mirror/InstanceWatcher.h"
#include "tools/rbd_mirror/Threads.h"
#include "tools/rbd_mirror/Throttler.h"
+#include "tools/rbd_mirror/image_replayer/journal/StateBuilder.h"
void register_test_image_sync() {
}
encode(client_data, client_data_bl);
ASSERT_EQ(0, m_remote_journaler->register_client(client_data_bl));
+
+ m_state_builder = rbd::mirror::image_replayer::journal::StateBuilder<
+ librbd::ImageCtx>::create("global image id");
+ m_state_builder->remote_journaler = m_remote_journaler;
+ m_state_builder->remote_client_meta = m_client_meta;
+ m_sync_point_handler = m_state_builder->create_sync_point_handler();
}
void TearDown() override {
m_instance_watcher->handle_release_leader();
+ m_state_builder->remote_journaler = nullptr;
+ m_state_builder->destroy_sync_point_handler();
+ m_state_builder->destroy();
+
delete m_remote_journaler;
delete m_instance_watcher;
delete m_image_sync_throttler;
}
ImageSync<> *create_request(Context *ctx) {
- return new ImageSync<>(m_local_image_ctx, m_remote_image_ctx,
- m_threads->timer, &m_threads->timer_lock,
- "mirror-uuid", m_remote_journaler, &m_client_meta,
- m_threads->work_queue, m_instance_watcher, ctx);
+ return new ImageSync<>(m_threads, m_local_image_ctx, m_remote_image_ctx,
+ "mirror-uuid", m_sync_point_handler,
+ m_instance_watcher, nullptr, ctx);
}
librbd::ImageCtx *m_remote_image_ctx;
rbd::mirror::InstanceWatcher<> *m_instance_watcher;
::journal::Journaler *m_remote_journaler;
librbd::journal::MirrorPeerClientMeta m_client_meta;
+ rbd::mirror::image_replayer::journal::StateBuilder<librbd::ImageCtx>* m_state_builder = nullptr;
+ rbd::mirror::image_sync::SyncPointHandler* m_sync_point_handler = nullptr;
};
TEST_F(TestImageSync, Empty) {
#include "test/rbd_mirror/test_mock_fixture.h"
#include "include/rbd/librbd.hpp"
#include "librbd/DeepCopyRequest.h"
-#include "librbd/journal/Types.h"
-#include "librbd/journal/TypeTraits.h"
-#include "test/journal/mock/MockJournaler.h"
#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
#include "test/librbd/mock/MockImageCtx.h"
+#include "test/rbd_mirror/mock/image_sync/MockSyncPointHandler.h"
#include "tools/rbd_mirror/ImageSync.h"
#include "tools/rbd_mirror/Threads.h"
#include "tools/rbd_mirror/image_sync/SyncPointCreateRequest.h"
} // anonymous namespace
-namespace journal {
-
-template <>
-struct TypeTraits<librbd::MockTestImageCtx> {
- typedef ::journal::MockJournaler Journaler;
-};
-
-} // namespace journal
-
template <>
class DeepCopyRequest<librbd::MockTestImageCtx> {
public:
namespace rbd {
namespace mirror {
+template <>
+struct Threads<librbd::MockTestImageCtx> {
+ ceph::mutex &timer_lock;
+ SafeTimer *timer;
+ ContextWQ *work_queue;
+
+ Threads(Threads<librbd::ImageCtx> *threads)
+ : timer_lock(threads->timer_lock), timer(threads->timer),
+ work_queue(threads->work_queue) {
+ }
+};
+
template<>
struct InstanceWatcher<librbd::MockTestImageCtx> {
MOCK_METHOD2(notify_sync_request, void(const std::string, Context *));
static SyncPointCreateRequest* create(librbd::MockTestImageCtx *remote_image_ctx,
const std::string &mirror_uuid,
- journal::MockJournaler *journaler,
- librbd::journal::MirrorPeerClientMeta *client_meta,
+ image_sync::SyncPointHandler* sync_point_handler,
Context *on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->on_finish = on_finish;
static SyncPointPruneRequest* create(librbd::MockTestImageCtx *remote_image_ctx,
bool sync_complete,
- journal::MockJournaler *journaler,
- librbd::journal::MirrorPeerClientMeta *client_meta,
+ image_sync::SyncPointHandler* sync_point_handler,
Context *on_finish) {
ceph_assert(s_instance != nullptr);
s_instance->on_finish = on_finish;
class TestMockImageSync : public TestMockFixture {
public:
+ typedef Threads<librbd::MockTestImageCtx> MockThreads;
typedef ImageSync<librbd::MockTestImageCtx> MockImageSync;
typedef InstanceWatcher<librbd::MockTestImageCtx> MockInstanceWatcher;
typedef image_sync::SyncPointCreateRequest<librbd::MockTestImageCtx> MockSyncPointCreateRequest;
typedef image_sync::SyncPointPruneRequest<librbd::MockTestImageCtx> MockSyncPointPruneRequest;
+ typedef image_sync::MockSyncPointHandler MockSyncPointHandler;
typedef librbd::DeepCopyRequest<librbd::MockTestImageCtx> MockImageCopyRequest;
void SetUp() override {
if (r == 0) {
mock_local_image_ctx.snap_ids[{cls::rbd::UserSnapshotNamespace(),
"snap1"}] = 123;
- m_client_meta.sync_points.emplace_back(cls::rbd::UserSnapshotNamespace(),
- "snap1",
- boost::none);
+ m_sync_points.emplace_back(cls::rbd::UserSnapshotNamespace(),
+ "snap1", "", boost::none);
}
m_threads->work_queue->queue(mock_sync_point_create_request.on_finish, r);
}));
}));
}
- void expect_flush_sync_point(journal::MockJournaler &mock_journaler, int r) {
- EXPECT_CALL(mock_journaler, update_client(_, _))
- .WillOnce(WithArg<1>(CompleteContext(r)));
+ void expect_flush_sync_point(MockSyncPointHandler& mock_sync_point_handler,
+ int r) {
+ EXPECT_CALL(mock_sync_point_handler, update_sync_points(_, _, false, _))
+ .WillOnce(WithArg<3>(CompleteContext(r)));
}
void expect_prune_sync_point(MockSyncPointPruneRequest &mock_sync_point_prune_request,
EXPECT_CALL(mock_sync_point_prune_request, send())
.WillOnce(Invoke([this, &mock_sync_point_prune_request, sync_complete, r]() {
ASSERT_EQ(sync_complete, mock_sync_point_prune_request.sync_complete);
- if (r == 0 && !m_client_meta.sync_points.empty()) {
+ if (r == 0 && !m_sync_points.empty()) {
if (sync_complete) {
- m_client_meta.sync_points.pop_front();
+ m_sync_points.pop_front();
} else {
- while (m_client_meta.sync_points.size() > 1) {
- m_client_meta.sync_points.pop_back();
+ while (m_sync_points.size() > 1) {
+ m_sync_points.pop_back();
}
}
}
}));
}
- MockImageSync *create_request(librbd::MockTestImageCtx &mock_remote_image_ctx,
+ void expect_get_snap_seqs(MockSyncPointHandler& mock_sync_point_handler) {
+ EXPECT_CALL(mock_sync_point_handler, get_snap_seqs())
+ .WillRepeatedly(Return(librbd::SnapSeqs{}));
+ }
+
+ void expect_get_sync_points(MockSyncPointHandler& mock_sync_point_handler) {
+ EXPECT_CALL(mock_sync_point_handler, get_sync_points())
+ .WillRepeatedly(Invoke([this]() {
+ return m_sync_points;
+ }));
+ }
+
+ MockImageSync *create_request(MockThreads& mock_threads,
+ librbd::MockTestImageCtx &mock_remote_image_ctx,
librbd::MockTestImageCtx &mock_local_image_ctx,
- journal::MockJournaler &mock_journaler,
+ MockSyncPointHandler& mock_sync_point_handler,
MockInstanceWatcher &mock_instance_watcher,
Context *ctx) {
- return new MockImageSync(&mock_local_image_ctx, &mock_remote_image_ctx,
- m_threads->timer, &m_threads->timer_lock,
- "mirror-uuid", &mock_journaler, &m_client_meta,
- m_threads->work_queue, &mock_instance_watcher,
- ctx);
+ return new MockImageSync(&mock_threads, &mock_local_image_ctx,
+ &mock_remote_image_ctx,
+ "mirror-uuid", &mock_sync_point_handler,
+ &mock_instance_watcher, nullptr, ctx);
}
librbd::ImageCtx *m_remote_image_ctx;
librbd::ImageCtx *m_local_image_ctx;
- librbd::journal::MirrorPeerClientMeta m_client_meta;
+
+ image_sync::SyncPoints m_sync_points;
};
TEST_F(TestMockImageSync, SimpleSync) {
+ MockThreads mock_threads(m_threads);
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
MockInstanceWatcher mock_instance_watcher;
MockImageCopyRequest mock_image_copy_request;
MockSyncPointCreateRequest mock_sync_point_create_request;
MockSyncPointPruneRequest mock_sync_point_prune_request;
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
+
InSequence seq;
expect_notify_sync_request(mock_instance_watcher, mock_local_image_ctx.id, 0);
expect_create_sync_point(mock_local_image_ctx, mock_sync_point_create_request, 0);
expect_get_snap_id(mock_remote_image_ctx);
expect_copy_image(mock_image_copy_request, 0);
- expect_flush_sync_point(mock_journaler, 0);
+ expect_flush_sync_point(mock_sync_point_handler, 0);
expect_prune_sync_point(mock_sync_point_prune_request, true, 0);
expect_notify_sync_complete(mock_instance_watcher, mock_local_image_ctx.id);
C_SaferCond ctx;
- MockImageSync *request = create_request(mock_remote_image_ctx,
- mock_local_image_ctx, mock_journaler,
+ MockImageSync *request = create_request(mock_threads, mock_remote_image_ctx,
+ mock_local_image_ctx,
+ mock_sync_point_handler,
mock_instance_watcher, &ctx);
request->send();
ASSERT_EQ(0, ctx.wait());
}
TEST_F(TestMockImageSync, RestartSync) {
+ MockThreads mock_threads(m_threads);
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
MockInstanceWatcher mock_instance_watcher;
MockImageCopyRequest mock_image_copy_request;
MockSyncPointCreateRequest mock_sync_point_create_request;
MockSyncPointPruneRequest mock_sync_point_prune_request;
- m_client_meta.sync_points = {{cls::rbd::UserSnapshotNamespace(), "snap1", boost::none},
- {cls::rbd::UserSnapshotNamespace(), "snap2", "snap1", boost::none}};
+ m_sync_points = {{cls::rbd::UserSnapshotNamespace(), "snap1", "", boost::none},
+ {cls::rbd::UserSnapshotNamespace(), "snap2", "snap1", boost::none}};
mock_local_image_ctx.snap_ids[{cls::rbd::UserSnapshotNamespace(), "snap1"}] = 123;
mock_local_image_ctx.snap_ids[{cls::rbd::UserSnapshotNamespace(), "snap2"}] = 234;
expect_test_features(mock_local_image_ctx);
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
expect_notify_sync_request(mock_instance_watcher, mock_local_image_ctx.id, 0);
expect_prune_sync_point(mock_sync_point_prune_request, false, 0);
expect_get_snap_id(mock_remote_image_ctx);
expect_copy_image(mock_image_copy_request, 0);
- expect_flush_sync_point(mock_journaler, 0);
+ expect_flush_sync_point(mock_sync_point_handler, 0);
expect_prune_sync_point(mock_sync_point_prune_request, true, 0);
expect_notify_sync_complete(mock_instance_watcher, mock_local_image_ctx.id);
C_SaferCond ctx;
- MockImageSync *request = create_request(mock_remote_image_ctx,
- mock_local_image_ctx, mock_journaler,
+ MockImageSync *request = create_request(mock_threads, mock_remote_image_ctx,
+ mock_local_image_ctx,
+ mock_sync_point_handler,
mock_instance_watcher, &ctx);
request->send();
ASSERT_EQ(0, ctx.wait());
}
TEST_F(TestMockImageSync, CancelNotifySyncRequest) {
+ MockThreads mock_threads(m_threads);
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
MockInstanceWatcher mock_instance_watcher;
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
+
InSequence seq;
Context *on_sync_start = nullptr;
C_SaferCond notify_sync_ctx;
}));
C_SaferCond ctx;
- MockImageSync *request = create_request(mock_remote_image_ctx,
- mock_local_image_ctx, mock_journaler,
+ MockImageSync *request = create_request(mock_threads, mock_remote_image_ctx,
+ mock_local_image_ctx,
+ mock_sync_point_handler,
mock_instance_watcher, &ctx);
request->get();
request->send();
}
TEST_F(TestMockImageSync, CancelImageCopy) {
+ MockThreads mock_threads(m_threads);
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
MockInstanceWatcher mock_instance_watcher;
MockImageCopyRequest mock_image_copy_request;
MockSyncPointCreateRequest mock_sync_point_create_request;
MockSyncPointPruneRequest mock_sync_point_prune_request;
- m_client_meta.sync_points = {{cls::rbd::UserSnapshotNamespace(), "snap1", boost::none}};
+ m_sync_points = {{cls::rbd::UserSnapshotNamespace(), "snap1", "", boost::none}};
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
InSequence seq;
expect_notify_sync_request(mock_instance_watcher, mock_local_image_ctx.id, 0);
expect_notify_sync_complete(mock_instance_watcher, mock_local_image_ctx.id);
C_SaferCond ctx;
- MockImageSync *request = create_request(mock_remote_image_ctx,
- mock_local_image_ctx, mock_journaler,
+ MockImageSync *request = create_request(mock_threads, mock_remote_image_ctx,
+ mock_local_image_ctx,
+ mock_sync_point_handler,
mock_instance_watcher, &ctx);
request->get();
request->send();
}
TEST_F(TestMockImageSync, CancelAfterCopyImage) {
+ MockThreads mock_threads(m_threads);
librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
- journal::MockJournaler mock_journaler;
+ MockSyncPointHandler mock_sync_point_handler;
MockInstanceWatcher mock_instance_watcher;
MockImageCopyRequest mock_image_copy_request;
MockSyncPointCreateRequest mock_sync_point_create_request;
MockSyncPointPruneRequest mock_sync_point_prune_request;
C_SaferCond ctx;
- MockImageSync *request = create_request(mock_remote_image_ctx,
- mock_local_image_ctx, mock_journaler,
+ MockImageSync *request = create_request(mock_threads, mock_remote_image_ctx,
+ mock_local_image_ctx,
+ mock_sync_point_handler,
mock_instance_watcher, &ctx);
+
+ expect_get_snap_seqs(mock_sync_point_handler);
+ expect_get_sync_points(mock_sync_point_handler);
+
InSequence seq;
expect_notify_sync_request(mock_instance_watcher, mock_local_image_ctx.id, 0);
expect_create_sync_point(mock_local_image_ctx, mock_sync_point_create_request, 0);
#include "common/debug.h"
#include "common/Timer.h"
#include "common/errno.h"
-#include "journal/Journaler.h"
#include "librbd/DeepCopyRequest.h"
#include "librbd/ImageCtx.h"
#include "librbd/ImageState.h"
#include "librbd/Utils.h"
#include "librbd/internal.h"
-#include "librbd/journal/Types.h"
+#include "tools/rbd_mirror/Threads.h"
#include "tools/rbd_mirror/image_sync/SyncPointCreateRequest.h"
#include "tools/rbd_mirror/image_sync/SyncPointPruneRequest.h"
+#include "tools/rbd_mirror/image_sync/Types.h"
#define dout_context g_ceph_context
#define dout_subsys ceph_subsys_rbd_mirror
};
template <typename I>
-ImageSync<I>::ImageSync(I *local_image_ctx, I *remote_image_ctx,
- SafeTimer *timer, ceph::mutex *timer_lock,
- const std::string &mirror_uuid, Journaler *journaler,
- MirrorPeerClientMeta *client_meta,
- ContextWQ *work_queue,
- InstanceWatcher<I> *instance_watcher,
- Context *on_finish, ProgressContext *progress_ctx)
+ImageSync<I>::ImageSync(
+ Threads<I>* threads,
+ I *local_image_ctx,
+ I *remote_image_ctx,
+ const std::string &local_mirror_uuid,
+ image_sync::SyncPointHandler* sync_point_handler,
+ InstanceWatcher<I> *instance_watcher,
+ ProgressContext *progress_ctx,
+ Context *on_finish)
: BaseRequest("rbd::mirror::ImageSync", local_image_ctx->cct, on_finish),
- m_local_image_ctx(local_image_ctx), m_remote_image_ctx(remote_image_ctx),
- m_timer(timer), m_timer_lock(timer_lock), m_mirror_uuid(mirror_uuid),
- m_journaler(journaler), m_client_meta(client_meta),
- m_work_queue(work_queue), m_instance_watcher(instance_watcher),
+ m_threads(threads),
+ m_local_image_ctx(local_image_ctx),
+ m_remote_image_ctx(remote_image_ctx),
+ m_local_mirror_uuid(local_mirror_uuid),
+ m_sync_point_handler(sync_point_handler),
+ m_instance_watcher(instance_watcher),
m_progress_ctx(progress_ctx),
m_lock(ceph::make_mutex(unique_lock_name("ImageSync::m_lock", this))),
- m_update_sync_point_interval(m_local_image_ctx->cct->_conf.template get_val<double>(
- "rbd_mirror_sync_point_update_age")), m_client_meta_copy(*client_meta) {
+ m_update_sync_point_interval(
+ m_local_image_ctx->cct->_conf.template get_val<double>(
+ "rbd_mirror_sync_point_update_age")) {
}
template <typename I>
}
Context *ctx = create_async_context_callback(
- m_work_queue, create_context_callback<
+ m_threads->work_queue, create_context_callback<
ImageSync<I>, &ImageSync<I>::handle_notify_sync_request>(this));
m_instance_watcher->notify_sync_request(m_local_image_ctx->id, ctx);
m_lock.unlock();
void ImageSync<I>::send_prune_catch_up_sync_point() {
update_progress("PRUNE_CATCH_UP_SYNC_POINT");
- if (m_client_meta->sync_points.empty()) {
+ if (m_sync_point_handler->get_sync_points().empty()) {
send_create_sync_point();
return;
}
Context *ctx = create_context_callback<
ImageSync<I>, &ImageSync<I>::handle_prune_catch_up_sync_point>(this);
SyncPointPruneRequest<I> *request = SyncPointPruneRequest<I>::create(
- m_remote_image_ctx, false, m_journaler, m_client_meta, ctx);
+ m_remote_image_ctx, false, m_sync_point_handler, ctx);
request->send();
}
// TODO: when support for disconnecting laggy clients is added,
// re-connect and create catch-up sync point
- if (m_client_meta->sync_points.size() > 0) {
+ if (!m_sync_point_handler->get_sync_points().empty()) {
send_copy_image();
return;
}
Context *ctx = create_context_callback<
ImageSync<I>, &ImageSync<I>::handle_create_sync_point>(this);
SyncPointCreateRequest<I> *request = SyncPointCreateRequest<I>::create(
- m_remote_image_ctx, m_mirror_uuid, m_journaler, m_client_meta, ctx);
+ m_remote_image_ctx, m_local_mirror_uuid, m_sync_point_handler, ctx);
request->send();
}
librados::snap_t snap_id_end;
librbd::deep_copy::ObjectNumber object_number;
int r = 0;
+
+ m_snap_seqs_copy = m_sync_point_handler->get_snap_seqs();
+ m_sync_points_copy = m_sync_point_handler->get_sync_points();
+ ceph_assert(!m_sync_points_copy.empty());
+ auto &sync_point = m_sync_points_copy.front();
+
{
std::shared_lock image_locker{m_remote_image_ctx->image_lock};
- ceph_assert(!m_client_meta->sync_points.empty());
- auto &sync_point = m_client_meta->sync_points.front();
snap_id_end = m_remote_image_ctx->get_snap_id(
cls::rbd::UserSnapshotNamespace(), sync_point.snap_name);
if (snap_id_end == CEPH_NOSNAP) {
m_image_copy_prog_ctx = new ImageCopyProgressContext(this);
m_image_copy_request = librbd::DeepCopyRequest<I>::create(
m_remote_image_ctx, m_local_image_ctx, snap_id_start, snap_id_end,
- false, object_number, m_work_queue, &m_client_meta->snap_seqs,
+ false, object_number, m_threads->work_queue, &m_snap_seqs_copy,
m_image_copy_prog_ctx, ctx);
m_image_copy_request->get();
m_lock.unlock();
dout(10) << ": r=" << r << dendl;
{
- std::scoped_lock locker{*m_timer_lock, m_lock};
+ std::scoped_lock locker{m_threads->timer_lock, m_lock};
m_image_copy_request->put();
m_image_copy_request = nullptr;
delete m_image_copy_prog_ctx;
}
if (m_update_sync_ctx != nullptr) {
- m_timer->cancel_event(m_update_sync_ctx);
+ m_threads->timer->cancel_event(m_update_sync_ctx);
m_update_sync_ctx = nullptr;
}
return;
}
- auto sync_point = &m_client_meta->sync_points.front();
+ ceph_assert(!m_sync_points_copy.empty());
+ auto sync_point = &m_sync_points_copy.front();
- if (m_client_meta->sync_object_count == m_image_copy_object_count &&
- sync_point->object_number &&
+ if (sync_point->object_number &&
(m_image_copy_object_no - 1) == sync_point->object_number.get()) {
// update sync point did not progress since last sync
return;
m_updating_sync_point = true;
- m_client_meta_copy = *m_client_meta;
- m_client_meta->sync_object_count = m_image_copy_object_count;
if (m_image_copy_object_no > 0) {
sync_point->object_number = m_image_copy_object_no - 1;
}
- CephContext *cct = m_local_image_ctx->cct;
- ldout(cct, 20) << ": sync_point=" << *sync_point << dendl;
-
- bufferlist client_data_bl;
- librbd::journal::ClientData client_data(*m_client_meta);
- encode(client_data, client_data_bl);
-
- Context *ctx = create_context_callback<
- ImageSync<I>, &ImageSync<I>::handle_update_sync_point>(
- this);
- m_journaler->update_client(client_data_bl, ctx);
+ auto ctx = create_context_callback<
+ ImageSync<I>, &ImageSync<I>::handle_update_sync_point>(this);
+ m_sync_point_handler->update_sync_points(m_snap_seqs_copy,
+ m_sync_points_copy, false, ctx);
}
template <typename I>
CephContext *cct = m_local_image_ctx->cct;
ldout(cct, 20) << ": r=" << r << dendl;
- if (r < 0) {
- *m_client_meta = m_client_meta_copy;
- lderr(cct) << ": failed to update client data: " << cpp_strerror(r)
- << dendl;
- }
-
{
- std::scoped_lock locker{*m_timer_lock, m_lock};
+ std::scoped_lock locker{m_threads->timer_lock, m_lock};
m_updating_sync_point = false;
if (m_image_copy_request != nullptr) {
std::lock_guard locker{m_lock};
this->send_update_sync_point();
});
- m_timer->add_event_after(m_update_sync_point_interval,
- m_update_sync_ctx);
+ m_threads->timer->add_event_after(
+ m_update_sync_point_interval, m_update_sync_ctx);
return;
}
}
update_progress("FLUSH_SYNC_POINT");
- m_client_meta_copy = *m_client_meta;
- m_client_meta->sync_object_count = m_image_copy_object_count;
- auto sync_point = &m_client_meta->sync_points.front();
+ ceph_assert(!m_sync_points_copy.empty());
+ auto sync_point = &m_sync_points_copy.front();
+
if (m_image_copy_object_no > 0) {
sync_point->object_number = m_image_copy_object_no - 1;
} else {
sync_point->object_number = boost::none;
}
- dout(10) << ": sync_point=" << *sync_point << dendl;
-
- bufferlist client_data_bl;
- librbd::journal::ClientData client_data(*m_client_meta);
- encode(client_data, client_data_bl);
-
- Context *ctx = create_context_callback<
- ImageSync<I>, &ImageSync<I>::handle_flush_sync_point>(
- this);
- m_journaler->update_client(client_data_bl, ctx);
+ auto ctx = create_context_callback<
+ ImageSync<I>, &ImageSync<I>::handle_flush_sync_point>(this);
+ m_sync_point_handler->update_sync_points(m_snap_seqs_copy,
+ m_sync_points_copy, false, ctx);
}
template <typename I>
dout(10) << ": r=" << r << dendl;
if (r < 0) {
- *m_client_meta = m_client_meta_copy;
-
derr << ": failed to update client data: " << cpp_strerror(r)
<< dendl;
finish(r);
Context *ctx = create_context_callback<
ImageSync<I>, &ImageSync<I>::handle_prune_sync_points>(this);
SyncPointPruneRequest<I> *request = SyncPointPruneRequest<I>::create(
- m_remote_image_ctx, true, m_journaler, m_client_meta, ctx);
+ m_remote_image_ctx, true, m_sync_point_handler, ctx);
request->send();
}
return;
}
- if (!m_client_meta->sync_points.empty()) {
+ if (!m_sync_point_handler->get_sync_points().empty()) {
send_copy_image();
return;
}
#include "include/int_types.h"
#include "librbd/ImageCtx.h"
-#include "librbd/journal/TypeTraits.h"
-#include "librbd/journal/Types.h"
+#include "librbd/Types.h"
#include "common/ceph_mutex.h"
#include "tools/rbd_mirror/BaseRequest.h"
-#include <map>
-#include <vector>
+#include "tools/rbd_mirror/image_sync/Types.h"
class Context;
class ContextWQ;
namespace journal { class Journaler; }
namespace librbd { class ProgressContext; }
namespace librbd { template <typename> class DeepCopyRequest; }
-namespace librbd { namespace journal { struct MirrorPeerClientMeta; } }
namespace rbd {
namespace mirror {
class ProgressContext;
-
template <typename> class InstanceWatcher;
+template <typename> class Threads;
+
+namespace image_sync { struct SyncPointHandler; }
template <typename ImageCtxT = librbd::ImageCtx>
class ImageSync : public BaseRequest {
public:
- typedef librbd::journal::TypeTraits<ImageCtxT> TypeTraits;
- typedef typename TypeTraits::Journaler Journaler;
- typedef librbd::journal::MirrorPeerClientMeta MirrorPeerClientMeta;
-
- static ImageSync* create(ImageCtxT *local_image_ctx,
- ImageCtxT *remote_image_ctx,
- SafeTimer *timer, ceph::mutex *timer_lock,
- const std::string &mirror_uuid,
- Journaler *journaler,
- MirrorPeerClientMeta *client_meta,
- ContextWQ *work_queue,
- InstanceWatcher<ImageCtxT> *instance_watcher,
- Context *on_finish,
- ProgressContext *progress_ctx = nullptr) {
- return new ImageSync(local_image_ctx, remote_image_ctx, timer, timer_lock,
- mirror_uuid, journaler, client_meta, work_queue,
- instance_watcher, on_finish, progress_ctx);
+ static ImageSync* create(
+ Threads<ImageCtxT>* threads,
+ ImageCtxT *local_image_ctx,
+ ImageCtxT *remote_image_ctx,
+ const std::string &local_mirror_uuid,
+ image_sync::SyncPointHandler* sync_point_handler,
+ InstanceWatcher<ImageCtxT> *instance_watcher,
+ ProgressContext *progress_ctx,
+ Context *on_finish) {
+ return new ImageSync(threads, local_image_ctx, remote_image_ctx,
+ local_mirror_uuid, sync_point_handler,
+ instance_watcher, progress_ctx, on_finish);
}
- ImageSync(ImageCtxT *local_image_ctx, ImageCtxT *remote_image_ctx,
- SafeTimer *timer, ceph::mutex *timer_lock, const std::string &mirror_uuid,
- Journaler *journaler, MirrorPeerClientMeta *client_meta,
- ContextWQ *work_queue, InstanceWatcher<ImageCtxT> *instance_watcher,
- Context *on_finish, ProgressContext *progress_ctx = nullptr);
+ ImageSync(
+ Threads<ImageCtxT>* threads,
+ ImageCtxT *local_image_ctx,
+ ImageCtxT *remote_image_ctx,
+ const std::string &local_mirror_uuid,
+ image_sync::SyncPointHandler* sync_point_handler,
+ InstanceWatcher<ImageCtxT> *instance_watcher,
+ ProgressContext *progress_ctx,
+ Context *on_finish);
~ImageSync() override;
void send() override;
* @endverbatim
*/
- typedef std::vector<librados::snap_t> SnapIds;
- typedef std::map<librados::snap_t, SnapIds> SnapMap;
class ImageCopyProgressContext;
+ Threads<ImageCtxT>* m_threads;
ImageCtxT *m_local_image_ctx;
ImageCtxT *m_remote_image_ctx;
- SafeTimer *m_timer;
- ceph::mutex *m_timer_lock;
- std::string m_mirror_uuid;
- Journaler *m_journaler;
- MirrorPeerClientMeta *m_client_meta;
- ContextWQ *m_work_queue;
+ std::string m_local_mirror_uuid;
+ image_sync::SyncPointHandler* m_sync_point_handler;
InstanceWatcher<ImageCtxT> *m_instance_watcher;
ProgressContext *m_progress_ctx;
- SnapMap m_snap_map;
-
ceph::mutex m_lock;
bool m_canceled = false;
double m_update_sync_point_interval;
uint64_t m_image_copy_object_no = 0;
uint64_t m_image_copy_object_count = 0;
- MirrorPeerClientMeta m_client_meta_copy;
+
+ librbd::SnapSeqs m_snap_seqs_copy;
+ image_sync::SyncPoints m_sync_points_copy;
int m_ret_val = 0;
#include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h"
#include "tools/rbd_mirror/image_replayer/journal/CreateLocalImageRequest.h"
#include "tools/rbd_mirror/image_replayer/journal/PrepareReplayRequest.h"
+#include "tools/rbd_mirror/image_replayer/journal/StateBuilder.h"
+#include "tools/rbd_mirror/image_replayer/journal/SyncPointHandler.h"
#define dout_context g_ceph_context
#define dout_subsys ceph_subsys_rbd_mirror
dout(15) << dendl;
ceph_assert(m_image_sync == nullptr);
+ // TODO temporary
+ m_state_builder = journal::StateBuilder<I>::create(m_global_image_id);
+ m_state_builder->remote_journaler = *m_remote_journaler;
+ m_state_builder->remote_client_meta = m_client_meta;
+ auto sync_point_handler = m_state_builder->create_sync_point_handler();
+
Context *ctx = create_context_callback<
BootstrapRequest<I>, &BootstrapRequest<I>::handle_image_sync>(this);
m_image_sync = ImageSync<I>::create(
- *m_local_image_ctx, m_remote_image_ctx, m_threads->timer,
- &m_threads->timer_lock, m_local_mirror_uuid, *m_remote_journaler,
- &m_client_meta, m_threads->work_queue, m_instance_watcher, ctx,
- m_progress_ctx);
+ m_threads, *m_local_image_ctx, m_remote_image_ctx, m_local_mirror_uuid,
+ sync_point_handler, m_instance_watcher, m_progress_ctx, ctx);
m_image_sync->get();
locker.unlock();
std::lock_guard locker{m_lock};
m_image_sync->put();
m_image_sync = nullptr;
+
+ m_state_builder->destroy_sync_point_handler();
+
+ // TODO
+ m_state_builder->remote_journaler = nullptr;
+ m_state_builder->destroy();
+ m_state_builder = nullptr;
}
if (r < 0) {
namespace image_replayer {
+// TODO
+namespace journal { template <typename> class StateBuilder; }
+
template <typename ImageCtxT = librbd::ImageCtx>
class BootstrapRequest : public BaseRequest {
public:
bool m_syncing = false;
ImageSync<ImageCtxT> *m_image_sync = nullptr;
+ // TODO temporary
+ journal::StateBuilder<ImageCtxT>* m_state_builder = nullptr;
+
void prepare_local_image();
void handle_prepare_local_image(int r);
#include "include/uuid.h"
#include "common/debug.h"
#include "common/errno.h"
-#include "journal/Journaler.h"
#include "librbd/ImageCtx.h"
#include "librbd/ImageState.h"
#include "librbd/Operations.h"
#include "librbd/Utils.h"
+#include "tools/rbd_mirror/image_sync/Types.h"
#define dout_context g_ceph_context
#define dout_subsys ceph_subsys_rbd_mirror
using librbd::util::create_context_callback;
template <typename I>
-SyncPointCreateRequest<I>::SyncPointCreateRequest(I *remote_image_ctx,
- const std::string &mirror_uuid,
- Journaler *journaler,
- MirrorPeerClientMeta *client_meta,
- Context *on_finish)
- : m_remote_image_ctx(remote_image_ctx), m_mirror_uuid(mirror_uuid),
- m_journaler(journaler), m_client_meta(client_meta), m_on_finish(on_finish),
- m_client_meta_copy(*client_meta) {
- ceph_assert(m_client_meta->sync_points.size() < 2);
+SyncPointCreateRequest<I>::SyncPointCreateRequest(
+ I *remote_image_ctx,
+ const std::string &local_mirror_uuid,
+ SyncPointHandler* sync_point_handler,
+ Context *on_finish)
+ : m_remote_image_ctx(remote_image_ctx),
+ m_local_mirror_uuid(local_mirror_uuid),
+ m_sync_point_handler(sync_point_handler),
+ m_on_finish(on_finish) {
+ m_sync_points_copy = m_sync_point_handler->get_sync_points();
+ ceph_assert(m_sync_points_copy.size() < 2);
// initialize the updated client meta with the new sync point
- m_client_meta_copy.sync_points.emplace_back();
- if (m_client_meta_copy.sync_points.size() > 1) {
- m_client_meta_copy.sync_points.back().from_snap_name =
- m_client_meta_copy.sync_points.front().snap_name;
+ m_sync_points_copy.emplace_back();
+ if (m_sync_points_copy.size() > 1) {
+ m_sync_points_copy.back().from_snap_name =
+ m_sync_points_copy.front().snap_name;
}
}
template <typename I>
void SyncPointCreateRequest<I>::send() {
- send_update_client();
+ send_update_sync_points();
}
template <typename I>
-void SyncPointCreateRequest<I>::send_update_client() {
+void SyncPointCreateRequest<I>::send_update_sync_points() {
uuid_d uuid_gen;
uuid_gen.generate_random();
- MirrorPeerSyncPoint &sync_point = m_client_meta_copy.sync_points.back();
- sync_point.snap_name = SNAP_NAME_PREFIX + "." + m_mirror_uuid + "." +
+ auto& sync_point = m_sync_points_copy.back();
+ sync_point.snap_name = SNAP_NAME_PREFIX + "." + m_local_mirror_uuid + "." +
uuid_gen.to_string();
- dout(20) << ": sync_point=" << sync_point << dendl;
-
- bufferlist client_data_bl;
- librbd::journal::ClientData client_data(m_client_meta_copy);
- encode(client_data, client_data_bl);
-
- Context *ctx = create_context_callback<
- SyncPointCreateRequest<I>, &SyncPointCreateRequest<I>::handle_update_client>(
- this);
- m_journaler->update_client(client_data_bl, ctx);
+ auto ctx = create_context_callback<
+ SyncPointCreateRequest<I>,
+ &SyncPointCreateRequest<I>::handle_update_sync_points>(this);
+ m_sync_point_handler->update_sync_points(
+ m_sync_point_handler->get_snap_seqs(), m_sync_points_copy, false, ctx);
}
template <typename I>
-void SyncPointCreateRequest<I>::handle_update_client(int r) {
+void SyncPointCreateRequest<I>::handle_update_sync_points(int r) {
dout(20) << ": r=" << r << dendl;
if (r < 0) {
return;
}
- // update provided meta structure to reflect reality
- *m_client_meta = m_client_meta_copy;
-
send_refresh_image();
}
void SyncPointCreateRequest<I>::send_create_snap() {
dout(20) << dendl;
- MirrorPeerSyncPoint &sync_point = m_client_meta_copy.sync_points.back();
+ auto& sync_point = m_sync_points_copy.back();
Context *ctx = create_context_callback<
SyncPointCreateRequest<I>, &SyncPointCreateRequest<I>::handle_create_snap>(
dout(20) << ": r=" << r << dendl;
if (r == -EEXIST) {
- send_update_client();
+ send_update_sync_points();
return;
} else if (r < 0) {
derr << ": failed to create snapshot: " << cpp_strerror(r) << dendl;
#ifndef RBD_MIRROR_IMAGE_SYNC_SYNC_POINT_CREATE_REQUEST_H
#define RBD_MIRROR_IMAGE_SYNC_SYNC_POINT_CREATE_REQUEST_H
-#include "librbd/journal/Types.h"
-#include "librbd/journal/TypeTraits.h"
+#include "Types.h"
#include <string>
class Context;
template <typename ImageCtxT = librbd::ImageCtx>
class SyncPointCreateRequest {
public:
- typedef librbd::journal::TypeTraits<ImageCtxT> TypeTraits;
- typedef typename TypeTraits::Journaler Journaler;
- typedef librbd::journal::MirrorPeerClientMeta MirrorPeerClientMeta;
- typedef librbd::journal::MirrorPeerSyncPoint MirrorPeerSyncPoint;
-
- static SyncPointCreateRequest* create(ImageCtxT *remote_image_ctx,
- const std::string &mirror_uuid,
- Journaler *journaler,
- MirrorPeerClientMeta *client_meta,
- Context *on_finish) {
- return new SyncPointCreateRequest(remote_image_ctx, mirror_uuid, journaler,
- client_meta, on_finish);
+ static SyncPointCreateRequest* create(
+ ImageCtxT *remote_image_ctx,
+ const std::string &local_mirror_uuid,
+ SyncPointHandler* sync_point_handler,
+ Context *on_finish) {
+ return new SyncPointCreateRequest(remote_image_ctx, local_mirror_uuid,
+ sync_point_handler, on_finish);
}
- SyncPointCreateRequest(ImageCtxT *remote_image_ctx,
- const std::string &mirror_uuid, Journaler *journaler,
- MirrorPeerClientMeta *client_meta, Context *on_finish);
+ SyncPointCreateRequest(
+ ImageCtxT *remote_image_ctx,
+ const std::string &local_mirror_uuid,
+ SyncPointHandler* sync_point_handler,
+ Context *on_finish);
void send();
* <start>
* |
* v
- * UPDATE_CLIENT < . .
- * | .
- * v .
- * REFRESH_IMAGE .
- * | . (repeat on EEXIST)
- * v .
- * CREATE_SNAP . . . .
+ * UPDATE_SYNC_POINTS < . .
+ * | .
+ * v .
+ * REFRESH_IMAGE .
+ * | . (repeat on EEXIST)
+ * v .
+ * CREATE_SNAP . . . . . .
* |
* v
* REFRESH_IMAGE
*/
ImageCtxT *m_remote_image_ctx;
- std::string m_mirror_uuid;
- Journaler *m_journaler;
- MirrorPeerClientMeta *m_client_meta;
+ std::string m_local_mirror_uuid;
+ SyncPointHandler* m_sync_point_handler;
Context *m_on_finish;
- MirrorPeerClientMeta m_client_meta_copy;
+ SyncPoints m_sync_points_copy;
- void send_update_client();
- void handle_update_client(int r);
+ void send_update_sync_points();
+ void handle_update_sync_points(int r);
void send_refresh_image();
void handle_refresh_image(int r);
#include "SyncPointPruneRequest.h"
#include "common/debug.h"
#include "common/errno.h"
-#include "journal/Journaler.h"
#include "librbd/ImageCtx.h"
#include "librbd/ImageState.h"
#include "librbd/Operations.h"
using librbd::util::create_context_callback;
template <typename I>
-SyncPointPruneRequest<I>::SyncPointPruneRequest(I *remote_image_ctx,
- bool sync_complete,
- Journaler *journaler,
- MirrorPeerClientMeta *client_meta,
- Context *on_finish)
- : m_remote_image_ctx(remote_image_ctx), m_sync_complete(sync_complete),
- m_journaler(journaler), m_client_meta(client_meta), m_on_finish(on_finish),
- m_client_meta_copy(*client_meta) {
+SyncPointPruneRequest<I>::SyncPointPruneRequest(
+ I *remote_image_ctx,
+ bool sync_complete,
+ SyncPointHandler* sync_point_handler,
+ Context *on_finish)
+ : m_remote_image_ctx(remote_image_ctx),
+ m_sync_complete(sync_complete),
+ m_sync_point_handler(sync_point_handler),
+ m_on_finish(on_finish) {
+ m_sync_points_copy = m_sync_point_handler->get_sync_points();
}
template <typename I>
void SyncPointPruneRequest<I>::send() {
- if (m_client_meta->sync_points.empty()) {
+ if (m_sync_points_copy.empty()) {
send_remove_snap();
return;
}
if (m_sync_complete) {
// if sync is complete, we can remove the master sync point
- auto it = m_client_meta_copy.sync_points.begin();
- MirrorPeerSyncPoint &sync_point = *it;
+ auto it = m_sync_points_copy.begin();
+ auto& sync_point = *it;
++it;
- if (it == m_client_meta_copy.sync_points.end() ||
+ if (it == m_sync_points_copy.end() ||
it->from_snap_name != sync_point.snap_name) {
m_snap_names.push_back(sync_point.snap_name);
}
// trim them off
std::shared_lock image_locker{m_remote_image_ctx->image_lock};
std::set<std::string> snap_names;
- for (auto it = m_client_meta_copy.sync_points.rbegin();
- it != m_client_meta_copy.sync_points.rend(); ++it) {
- MirrorPeerSyncPoint &sync_point = *it;
- if (&sync_point == &m_client_meta_copy.sync_points.front()) {
+ for (auto it = m_sync_points_copy.rbegin();
+ it != m_sync_points_copy.rend(); ++it) {
+ auto& sync_point = *it;
+ if (&sync_point == &m_sync_points_copy.front()) {
if (m_remote_image_ctx->get_snap_id(
cls::rbd::UserSnapshotNamespace(), sync_point.snap_name) ==
CEPH_NOSNAP) {
m_snap_names.push_back(sync_point.snap_name);
}
- MirrorPeerSyncPoint &front_sync_point =
- m_client_meta_copy.sync_points.front();
+ auto& front_sync_point = m_sync_points_copy.front();
if (!sync_point.from_snap_name.empty() &&
snap_names.count(sync_point.from_snap_name) == 0 &&
sync_point.from_snap_name != front_sync_point.snap_name) {
return;
}
- send_update_client();
+ send_update_sync_points();
}
template <typename I>
-void SyncPointPruneRequest<I>::send_update_client() {
+void SyncPointPruneRequest<I>::send_update_sync_points() {
dout(20) << dendl;
if (m_sync_complete) {
- m_client_meta_copy.sync_points.pop_front();
- if (m_client_meta_copy.sync_points.empty()) {
- m_client_meta_copy.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
- }
+ m_sync_points_copy.pop_front();
} else {
- while (m_client_meta_copy.sync_points.size() > 1) {
- m_client_meta_copy.sync_points.pop_back();
+ while (m_sync_points_copy.size() > 1) {
+ m_sync_points_copy.pop_back();
}
if (m_invalid_master_sync_point) {
// all subsequent sync points would have been pruned
- m_client_meta_copy.sync_points.clear();
+ m_sync_points_copy.clear();
}
}
- bufferlist client_data_bl;
- librbd::journal::ClientData client_data(m_client_meta_copy);
- encode(client_data, client_data_bl);
-
- Context *ctx = create_context_callback<
- SyncPointPruneRequest<I>, &SyncPointPruneRequest<I>::handle_update_client>(
- this);
- m_journaler->update_client(client_data_bl, ctx);
+ auto ctx = create_context_callback<
+ SyncPointPruneRequest<I>,
+ &SyncPointPruneRequest<I>::handle_update_sync_points>(this);
+ m_sync_point_handler->update_sync_points(
+ m_sync_point_handler->get_snap_seqs(), m_sync_points_copy,
+ m_sync_complete, ctx);
}
template <typename I>
-void SyncPointPruneRequest<I>::handle_update_client(int r) {
+void SyncPointPruneRequest<I>::handle_update_sync_points(int r) {
dout(20) << ": r=" << r << dendl;
if (r < 0) {
return;
}
- // update provided meta structure to reflect reality
- *m_client_meta = m_client_meta_copy;
finish(0);
}
#ifndef RBD_MIRROR_IMAGE_SYNC_SYNC_POINT_PRUNE_REQUEST_H
#define RBD_MIRROR_IMAGE_SYNC_SYNC_POINT_PRUNE_REQUEST_H
-#include "librbd/journal/Types.h"
-#include "librbd/journal/TypeTraits.h"
+#include "tools/rbd_mirror/image_sync/Types.h"
#include <list>
#include <string>
template <typename ImageCtxT = librbd::ImageCtx>
class SyncPointPruneRequest {
public:
- typedef librbd::journal::TypeTraits<ImageCtxT> TypeTraits;
- typedef typename TypeTraits::Journaler Journaler;
- typedef librbd::journal::MirrorPeerClientMeta MirrorPeerClientMeta;
- typedef librbd::journal::MirrorPeerSyncPoint MirrorPeerSyncPoint;
-
- static SyncPointPruneRequest* create(ImageCtxT *remote_image_ctx,
- bool sync_complete,
- Journaler *journaler,
- MirrorPeerClientMeta *client_meta,
- Context *on_finish) {
- return new SyncPointPruneRequest(remote_image_ctx, sync_complete, journaler,
- client_meta, on_finish);
+ static SyncPointPruneRequest* create(
+ ImageCtxT *remote_image_ctx,
+ bool sync_complete,
+ SyncPointHandler* sync_point_handler,
+ Context *on_finish) {
+ return new SyncPointPruneRequest(remote_image_ctx, sync_complete,
+ sync_point_handler, on_finish);
}
- SyncPointPruneRequest(ImageCtxT *remote_image_ctx, bool sync_complete,
- Journaler *journaler, MirrorPeerClientMeta *client_meta,
- Context *on_finish);
+ SyncPointPruneRequest(
+ ImageCtxT *remote_image_ctx,
+ bool sync_complete,
+ SyncPointHandler* sync_point_handler,
+ Context *on_finish);
void send();
ImageCtxT *m_remote_image_ctx;
bool m_sync_complete;
- Journaler *m_journaler;
- MirrorPeerClientMeta *m_client_meta;
+ SyncPointHandler* m_sync_point_handler;
Context *m_on_finish;
- MirrorPeerClientMeta m_client_meta_copy;
+ SyncPoints m_sync_points_copy;
std::list<std::string> m_snap_names;
bool m_invalid_master_sync_point = false;
void send_refresh_image();
void handle_refresh_image(int r);
- void send_update_client();
- void handle_update_client(int r);
+ void send_update_sync_points();
+ void handle_update_sync_points(int r);
void finish(int r);
};