From: Jason Dillaman Date: Tue, 11 Sep 2018 12:21:06 +0000 (-0400) Subject: rbd-mirror: connect to remote cluster using optional mon_host/key values X-Git-Tag: v14.0.1~288^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a7fd06637a9242ed6609f48b78408dca7c2e5b8a;p=ceph.git rbd-mirror: connect to remote cluster using optional mon_host/key values Signed-off-by: Jason Dillaman --- diff --git a/src/test/librados_test_stub/LibradosTestStub.cc b/src/test/librados_test_stub/LibradosTestStub.cc index 38a948a8571..6fec692e5b7 100644 --- a/src/test/librados_test_stub/LibradosTestStub.cc +++ b/src/test/librados_test_stub/LibradosTestStub.cc @@ -184,6 +184,13 @@ extern "C" int rados_create(rados_t *cluster, const char * const id) { return 0; } +extern "C" int rados_create_with_context(rados_t *cluster, + rados_config_t cct_) { + auto cct = reinterpret_cast(cct_); + *cluster = librados_test_stub::get_cluster()->create_rados_client(cct); + return 0; +} + extern "C" rados_config_t rados_ioctx_cct(rados_ioctx_t ioctx) { librados::TestIoCtxImpl *ctx = @@ -1031,6 +1038,10 @@ int Rados::init(const char * const id) { return rados_create(reinterpret_cast(&client), id); } +int Rados::init_with_context(config_t cct_) { + return rados_create_with_context(reinterpret_cast(&client), cct_); +} + int Rados::ioctx_create(const char *name, IoCtx &io) { rados_ioctx_t p; int ret = rados_ioctx_create(reinterpret_cast(client), name, &p); diff --git a/src/test/librados_test_stub/MockTestMemCluster.h b/src/test/librados_test_stub/MockTestMemCluster.h index 68e639c4b82..685621a8c75 100644 --- a/src/test/librados_test_stub/MockTestMemCluster.h +++ b/src/test/librados_test_stub/MockTestMemCluster.h @@ -16,11 +16,19 @@ class TestRadosClient; class MockTestMemCluster : public TestMemCluster { public: - TestRadosClient *create_rados_client(CephContext *cct) override { - return new ::testing::NiceMock( - cct, this); + MockTestMemCluster() { + default_to_dispatch(); } + MOCK_METHOD1(create_rados_client, TestRadosClient*(CephContext*)); + MockTestMemRadosClient* do_create_rados_client(CephContext *cct) { + return new ::testing::NiceMock(cct, this); + } + + void default_to_dispatch() { + using namespace ::testing; + ON_CALL(*this, create_rados_client(_)).WillByDefault(Invoke(this, &MockTestMemCluster::do_create_rados_client)); + } }; } // namespace librados diff --git a/src/test/librados_test_stub/MockTestMemRadosClient.h b/src/test/librados_test_stub/MockTestMemRadosClient.h index 1f44c499ded..92ad65733e7 100644 --- a/src/test/librados_test_stub/MockTestMemRadosClient.h +++ b/src/test/librados_test_stub/MockTestMemRadosClient.h @@ -19,10 +19,15 @@ public: default_to_dispatch(); } + MOCK_METHOD0(connect, int()); + int do_connect() { + return TestMemRadosClient::connect(); + } + MOCK_METHOD2(create_ioctx, TestIoCtxImpl *(int64_t pool_id, const std::string &pool_name)); - TestIoCtxImpl *do_create_ioctx(int64_t pool_id, - const std::string &pool_name) { + MockTestMemIoCtxImpl* do_create_ioctx(int64_t pool_id, + const std::string &pool_name) { return new ::testing::NiceMock( this, this, pool_id, pool_name, get_mem_cluster()->get_pool(pool_name)); @@ -63,6 +68,7 @@ public: void default_to_dispatch() { using namespace ::testing; + ON_CALL(*this, connect()).WillByDefault(Invoke(this, &MockTestMemRadosClient::do_connect)); ON_CALL(*this, create_ioctx(_, _)).WillByDefault(Invoke(this, &MockTestMemRadosClient::do_create_ioctx)); ON_CALL(*this, blacklist_add(_, _)).WillByDefault(Invoke(this, &MockTestMemRadosClient::do_blacklist_add)); ON_CALL(*this, get_min_compatible_client(_, _)).WillByDefault(Invoke(this, &MockTestMemRadosClient::do_get_min_compatible_client)); diff --git a/src/test/librbd/test_mock_fixture.cc b/src/test/librbd/test_mock_fixture.cc index fba57b739cc..0a467c16137 100644 --- a/src/test/librbd/test_mock_fixture.cc +++ b/src/test/librbd/test_mock_fixture.cc @@ -28,7 +28,7 @@ void TestMockFixture::SetUpTestCase() { // use a mock version of the in-memory cluster librados_test_stub::set_cluster(boost::shared_ptr( - new librados::MockTestMemCluster())); + new ::testing::NiceMock())); TestFixture::SetUpTestCase(); } @@ -45,6 +45,8 @@ void TestMockFixture::TearDown() { ::testing::Mock::VerifyAndClear(mock_rados_client); mock_rados_client->default_to_dispatch(); + dynamic_cast( + librados_test_stub::get_cluster().get())->default_to_dispatch(); TestFixture::TearDown(); } diff --git a/src/test/rbd_mirror/CMakeLists.txt b/src/test/rbd_mirror/CMakeLists.txt index 3346f08c35a..0b8497180ba 100644 --- a/src/test/rbd_mirror/CMakeLists.txt +++ b/src/test/rbd_mirror/CMakeLists.txt @@ -25,6 +25,7 @@ add_executable(unittest_rbd_mirror test_mock_InstanceReplayer.cc test_mock_InstanceWatcher.cc test_mock_LeaderWatcher.cc + test_mock_PoolReplayer.cc test_mock_PoolWatcher.cc image_deleter/test_mock_RemoveRequest.cc image_deleter/test_mock_SnapshotPurgeRequest.cc diff --git a/src/test/rbd_mirror/test_mock_PoolReplayer.cc b/src/test/rbd_mirror/test_mock_PoolReplayer.cc new file mode 100644 index 00000000000..0709201f310 --- /dev/null +++ b/src/test/rbd_mirror/test_mock_PoolReplayer.cc @@ -0,0 +1,413 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "test/librbd/mock/MockImageCtx.h" +#include "test/librados_test_stub/MockTestMemCluster.h" +#include "test/librados_test_stub/MockTestMemIoCtxImpl.h" +#include "test/librados_test_stub/MockTestMemRadosClient.h" +#include "test/rbd_mirror/test_mock_fixture.h" +#include "test/rbd_mirror/mock/MockContextWQ.h" +#include "test/rbd_mirror/mock/MockSafeTimer.h" +#include "tools/rbd_mirror/PoolReplayer.h" +#include "tools/rbd_mirror/ImageDeleter.h" +#include "tools/rbd_mirror/ImageMap.h" +#include "tools/rbd_mirror/InstanceWatcher.h" +#include "tools/rbd_mirror/InstanceReplayer.h" +#include "tools/rbd_mirror/LeaderWatcher.h" +#include "tools/rbd_mirror/PoolWatcher.h" +#include "tools/rbd_mirror/ServiceDaemon.h" +#include "tools/rbd_mirror/Threads.h" + +namespace librbd { + +namespace { + +struct MockTestImageCtx : public MockImageCtx { + MockTestImageCtx(librbd::ImageCtx &image_ctx) + : librbd::MockImageCtx(image_ctx) { + } +}; + +} // anonymous namespace + +} // namespace librbd + +namespace rbd { +namespace mirror { + +template <> +struct ImageDeleter { + static ImageDeleter* s_instance; + + static ImageDeleter* create(librados::IoCtx &ioctx, + Threads *threads, + ServiceDaemon *service_daemon) { + ceph_assert(s_instance != nullptr); + return s_instance; + } + + MOCK_METHOD1(init, void(Context*)); + MOCK_METHOD1(shut_down, void(Context*)); + MOCK_METHOD2(print_status, void(Formatter*, std::stringstream*)); + + ImageDeleter() { + s_instance = this; + } +}; + +ImageDeleter* ImageDeleter::s_instance = nullptr; + +template<> +struct ImageMap { + static ImageMap* s_instance; + + static ImageMap *create(librados::IoCtx &ioctx, + Threads *threads, + const std::string& instance_id, + image_map::Listener &listener) { + ceph_assert(s_instance != nullptr); + return s_instance; + } + + MOCK_METHOD1(init, void(Context*)); + MOCK_METHOD1(shut_down, void(Context*)); + + MOCK_METHOD1(update_instances_added, void(const std::vector&)); + MOCK_METHOD1(update_instances_removed, void(const std::vector&)); + + MOCK_METHOD3(update_images_mock, void(const std::string&, + const std::set&, + const std::set&)); + void update_images(const std::string& mirror_uuid, + std::set&& added, + std::set&& removed) { + update_images_mock(mirror_uuid, added, removed); + } + + ImageMap() { + s_instance = this; + } +}; + +ImageMap* ImageMap::s_instance = nullptr; + +template<> +struct InstanceReplayer { + static InstanceReplayer* s_instance; + + static InstanceReplayer* create(Threads *threads, + ServiceDaemon *service_daemon, + RadosRef rados, const std::string& uuid, + int64_t pool_id) { + ceph_assert(s_instance != nullptr); + return s_instance; + } + + MOCK_METHOD0(start, void()); + MOCK_METHOD0(stop, void()); + MOCK_METHOD0(restart, void()); + MOCK_METHOD0(flush, void()); + + MOCK_METHOD2(print_status, void(Formatter*, std::stringstream*)); + + MOCK_METHOD2(add_peer, void(const std::string&, librados::IoCtx&)); + + MOCK_METHOD0(init, void()); + MOCK_METHOD0(shut_down, void()); + MOCK_METHOD1(release_all, void(Context*)); + + InstanceReplayer() { + s_instance = this; + } +}; + +InstanceReplayer* InstanceReplayer::s_instance = nullptr; + +template<> +struct InstanceWatcher { + static InstanceWatcher* s_instance; + + static InstanceWatcher* create(librados::IoCtx &ioctx, + MockContextWQ* work_queue, + InstanceReplayer* instance_replayer) { + ceph_assert(s_instance != nullptr); + return s_instance; + } + + MOCK_METHOD0(handle_acquire_leader, void()); + MOCK_METHOD0(handle_release_leader, void()); + + MOCK_METHOD0(get_instance_id, std::string()); + + MOCK_METHOD2(print_sync_status, void(Formatter*, std::stringstream*)); + + MOCK_METHOD0(init, int()); + MOCK_METHOD0(shut_down, void()); + + MOCK_METHOD3(notify_image_acquire, void(const std::string&, + const std::string&, + Context*)); + MOCK_METHOD3(notify_image_release, void(const std::string&, + const std::string&, + Context*)); + MOCK_METHOD4(notify_peer_image_removed, void(const std::string&, + const std::string&, + const std::string&, + Context*)); + + MOCK_METHOD1(handle_update_leader, void(const std::string&)); + + InstanceWatcher() { + s_instance = this; + } + +}; + +InstanceWatcher* InstanceWatcher::s_instance = nullptr; + +template<> +struct LeaderWatcher { + static LeaderWatcher* s_instance; + + static LeaderWatcher *create(Threads *threads, + librados::IoCtx &ioctx, + leader_watcher::Listener* listener) { + ceph_assert(s_instance != nullptr); + return s_instance; + } + + MOCK_METHOD0(is_leader, bool()); + MOCK_METHOD0(release_leader, void()); + + MOCK_METHOD1(get_leader_instance_id, void(std::string*)); + MOCK_METHOD1(list_instances, void(std::vector*)); + + MOCK_METHOD0(init, int()); + MOCK_METHOD0(shut_down, int()); + + LeaderWatcher() { + s_instance = this; + } + +}; + +LeaderWatcher* LeaderWatcher::s_instance = nullptr; + +template<> +struct PoolWatcher { + static PoolWatcher* s_instance; + + static PoolWatcher *create(Threads *threads, + librados::IoCtx &ioctx, + pool_watcher::Listener& listener) { + ceph_assert(s_instance != nullptr); + return s_instance; + } + + MOCK_METHOD0(is_blacklisted, bool()); + + MOCK_METHOD0(get_image_count, uint64_t()); + + MOCK_METHOD1(init, void(Context*)); + MOCK_METHOD1(shut_down, void(Context*)); + + PoolWatcher() { + s_instance = this; + } + +}; + +PoolWatcher* PoolWatcher::s_instance = nullptr; + +template<> +struct ServiceDaemon { + MOCK_METHOD3(add_or_update_attribute, + void(int64_t, const std::string&, + const service_daemon::AttributeValue&)); + MOCK_METHOD2(remove_attribute, + void(int64_t, const std::string&)); + + MOCK_METHOD4(add_or_update_callout, uint64_t(int64_t, uint64_t, + service_daemon::CalloutLevel, + const std::string&)); + MOCK_METHOD2(remove_callout, void(int64_t, uint64_t)); +}; + +template <> +struct Threads { + MockSafeTimer *timer; + Mutex &timer_lock; + Cond timer_cond; + + MockContextWQ *work_queue; + + Threads(Threads *threads) + : timer(new MockSafeTimer()), + timer_lock(threads->timer_lock), + work_queue(new MockContextWQ()) { + } + ~Threads() { + delete timer; + delete work_queue; + } +}; + +} // namespace mirror +} // namespace rbd + +// template definitions +#include "tools/rbd_mirror/PoolReplayer.cc" + +namespace rbd { +namespace mirror { + +using ::testing::_; +using ::testing::DoAll; +using ::testing::InSequence; +using ::testing::Invoke; +using ::testing::Return; +using ::testing::StrEq; +using ::testing::WithArg; + +class TestMockPoolReplayer : public TestMockFixture { +public: + typedef PoolReplayer MockPoolReplayer; + typedef ImageMap MockImageMap; + typedef InstanceReplayer MockInstanceReplayer; + typedef InstanceWatcher MockInstanceWatcher; + typedef LeaderWatcher MockLeaderWatcher; + typedef PoolWatcher MockPoolWatcher; + typedef ServiceDaemon MockServiceDaemon; + typedef Threads MockThreads; + + void expect_connect(librados::MockTestMemCluster& mock_cluster, + librados::MockTestMemRadosClient* mock_rados_client, + const std::string& cluster_name, CephContext** cct_ref) { + EXPECT_CALL(mock_cluster, create_rados_client(_)) + .WillOnce(Invoke([cluster_name, mock_rados_client, cct_ref](CephContext* cct) { + EXPECT_EQ(cluster_name, cct->_conf->cluster); + if (cct_ref != nullptr) { + cct->get(); + *cct_ref = cct; + } + + return mock_rados_client; + })); + } + + void expect_create_ioctx(librados::MockTestMemRadosClient* mock_rados_client, + librados::MockTestMemIoCtxImpl* mock_io_ctx_impl) { + EXPECT_CALL(*mock_rados_client, create_ioctx(_, _)) + .WillOnce(Invoke([mock_io_ctx_impl](int64_t id, const std::string& name) { + return mock_io_ctx_impl; + })); + } + + void expect_mirror_uuid_get(librados::MockTestMemIoCtxImpl *io_ctx_impl, + const std::string &uuid, int r) { + bufferlist out_bl; + encode(uuid, out_bl); + + EXPECT_CALL(*io_ctx_impl, + exec(RBD_MIRRORING, _, StrEq("rbd"), StrEq("mirror_uuid_get"), + _, _, _)) + .WillOnce(DoAll(WithArg<5>(Invoke([out_bl](bufferlist *bl) { + *bl = out_bl; + })), + Return(r))); + } + + void expect_instance_replayer_init(MockInstanceReplayer& mock_instance_replayer) { + EXPECT_CALL(mock_instance_replayer, init()); + } + + void expect_instance_replayer_shut_down(MockInstanceReplayer& mock_instance_replayer) { + EXPECT_CALL(mock_instance_replayer, shut_down()); + } + + void expect_instance_replayer_stop(MockInstanceReplayer& mock_instance_replayer) { + EXPECT_CALL(mock_instance_replayer, stop()); + } + + void expect_instance_replayer_add_peer(MockInstanceReplayer& mock_instance_replayer, + const std::string& uuid) { + EXPECT_CALL(mock_instance_replayer, add_peer(uuid, _)); + } + + void expect_instance_watcher_init(MockInstanceWatcher& mock_instance_watcher, + int r) { + EXPECT_CALL(mock_instance_watcher, init()) + .WillOnce(Return(r)); + } + + void expect_instance_watcher_shut_down(MockInstanceWatcher& mock_instance_watcher) { + EXPECT_CALL(mock_instance_watcher, shut_down()); + } + + void expect_leader_watcher_init(MockLeaderWatcher& mock_leader_watcher, + int r) { + EXPECT_CALL(mock_leader_watcher, init()) + .WillOnce(Return(r)); + } + + void expect_leader_watcher_shut_down(MockLeaderWatcher& mock_leader_watcher) { + EXPECT_CALL(mock_leader_watcher, shut_down()); + } + +}; + +TEST_F(TestMockPoolReplayer, ConfigKeyOverride) { + PeerSpec peer_spec{"uuid", "cluster name", "client.name"}; + peer_spec.mon_host = "123"; + peer_spec.key = "234"; + + InSequence seq; + + auto& mock_cluster = get_mock_cluster(); + auto mock_local_rados_client = mock_cluster.do_create_rados_client( + g_ceph_context); + expect_connect(mock_cluster, mock_local_rados_client, "ceph", nullptr); + + auto mock_remote_rados_client = mock_cluster.do_create_rados_client( + g_ceph_context); + CephContext* remote_cct = nullptr; + expect_connect(mock_cluster, mock_remote_rados_client, "cluster name", + &remote_cct); + + auto mock_local_io_ctx = mock_local_rados_client->do_create_ioctx( + m_local_io_ctx.get_id(), m_local_io_ctx.get_pool_name()); + expect_create_ioctx(mock_local_rados_client, mock_local_io_ctx); + + expect_mirror_uuid_get(mock_local_io_ctx, "uuid", 0); + + auto mock_instance_replayer = new MockInstanceReplayer(); + expect_instance_replayer_init(*mock_instance_replayer); + expect_instance_replayer_add_peer(*mock_instance_replayer, "uuid"); + + auto mock_instance_watcher = new MockInstanceWatcher(); + expect_instance_watcher_init(*mock_instance_watcher, 0); + + auto mock_leader_watcher = new MockLeaderWatcher(); + expect_leader_watcher_init(*mock_leader_watcher, 0); + + MockThreads mock_threads(m_threads); + MockServiceDaemon mock_service_daemon; + MockPoolReplayer pool_replayer(&mock_threads, &mock_service_daemon, + m_local_io_ctx.get_id(), peer_spec, {}); + pool_replayer.init(); + + ASSERT_TRUE(remote_cct != nullptr); + ASSERT_EQ("123", remote_cct->_conf.get_val("mon_host")); + ASSERT_EQ("234", remote_cct->_conf.get_val("key")); + remote_cct->put(); + + expect_instance_replayer_stop(*mock_instance_replayer); + expect_leader_watcher_shut_down(*mock_leader_watcher); + expect_instance_watcher_shut_down(*mock_instance_watcher); + expect_instance_replayer_shut_down(*mock_instance_replayer); + + pool_replayer.shut_down(); +} + +} // namespace mirror +} // namespace rbd diff --git a/src/test/rbd_mirror/test_mock_fixture.cc b/src/test/rbd_mirror/test_mock_fixture.cc index d5c6c7caf27..9e308a63bcb 100644 --- a/src/test/rbd_mirror/test_mock_fixture.cc +++ b/src/test/rbd_mirror/test_mock_fixture.cc @@ -22,7 +22,7 @@ void TestMockFixture::SetUpTestCase() { // use a mock version of the in-memory rados client librados_test_stub::set_cluster(boost::shared_ptr( - new librados::MockTestMemCluster())); + new ::testing::NiceMock())); TestFixture::SetUpTestCase(); } @@ -39,6 +39,8 @@ void TestMockFixture::TearDown() { ::testing::Mock::VerifyAndClear(mock_rados_client); mock_rados_client->default_to_dispatch(); + dynamic_cast( + librados_test_stub::get_cluster().get())->default_to_dispatch(); TestFixture::TearDown(); } @@ -50,6 +52,13 @@ void TestMockFixture::expect_test_features(librbd::MockImageCtx &mock_image_ctx) }))); } +librados::MockTestMemCluster& TestMockFixture::get_mock_cluster() { + librados::MockTestMemCluster* mock_cluster = dynamic_cast< + librados::MockTestMemCluster*>(librados_test_stub::get_cluster().get()); + ceph_assert(mock_cluster != nullptr); + return *mock_cluster; +} + } // namespace mirror } // namespace rbd diff --git a/src/test/rbd_mirror/test_mock_fixture.h b/src/test/rbd_mirror/test_mock_fixture.h index 1fd2f9e70ce..e6874b81722 100644 --- a/src/test/rbd_mirror/test_mock_fixture.h +++ b/src/test/rbd_mirror/test_mock_fixture.h @@ -13,6 +13,7 @@ namespace librados { class TestRadosClient; +class MockTestMemCluster; class MockTestMemIoCtxImpl; class MockTestMemRadosClient; } @@ -58,6 +59,8 @@ public: void expect_test_features(librbd::MockImageCtx &mock_image_ctx); + librados::MockTestMemCluster& get_mock_cluster(); + private: static TestClusterRef s_test_cluster; }; diff --git a/src/tools/rbd_mirror/PoolReplayer.cc b/src/tools/rbd_mirror/PoolReplayer.cc index ffdebde4039..2dbaf93f8f6 100644 --- a/src/tools/rbd_mirror/PoolReplayer.cc +++ b/src/tools/rbd_mirror/PoolReplayer.cc @@ -279,7 +279,7 @@ void PoolReplayer::init() dout(10) << "replaying for " << m_peer << dendl; int r = init_rados(g_ceph_context->_conf->cluster, g_ceph_context->_conf->name.to_str(), - "local cluster", &m_local_rados, false); + "", "", "local cluster", &m_local_rados, false); if (r < 0) { m_callout_id = m_service_daemon->add_or_update_callout( m_local_pool_id, m_callout_id, service_daemon::CALLOUT_LEVEL_ERROR, @@ -288,6 +288,7 @@ void PoolReplayer::init() } r = init_rados(m_peer.cluster_name, m_peer.client_name, + m_peer.mon_host, m_peer.key, std::string("remote peer ") + stringify(m_peer), &m_remote_rados, true); if (r < 0) { @@ -329,7 +330,7 @@ void PoolReplayer::init() dout(10) << "connected to " << m_peer << dendl; - m_instance_replayer.reset(InstanceReplayer<>::create( + m_instance_replayer.reset(InstanceReplayer::create( m_threads, m_service_daemon, m_local_rados, local_mirror_uuid, m_local_pool_id)); m_instance_replayer->init(); @@ -400,6 +401,8 @@ void PoolReplayer::shut_down() { template int PoolReplayer::init_rados(const std::string &cluster_name, const std::string &client_name, + const std::string &mon_host, + const std::string &key, const std::string &description, RadosRef *rados_ref, bool strip_cluster_overrides) { @@ -421,7 +424,7 @@ int PoolReplayer::init_rados(const std::string &cluster_name, // librados::Rados::conf_read_file int r = cct->_conf.parse_config_files(nullptr, nullptr, 0); - if (r < 0) { + if (r < 0 && r != -ENOENT) { derr << "could not read ceph conf for " << description << ": " << cpp_strerror(r) << dendl; cct->put(); @@ -483,6 +486,26 @@ int PoolReplayer::init_rados(const std::string &cluster_name, "$run_dir/$name.$pid.$cluster.$cctid.asok"); } + if (!mon_host.empty()) { + r = cct->_conf.set_val("mon_host", mon_host); + if (r < 0) { + derr << "failed to set mon_host config for " << description << ": " + << cpp_strerror(r) << dendl; + cct->put(); + return r; + } + } + + if (!key.empty()) { + r = cct->_conf.set_val("key", key); + if (r < 0) { + derr << "failed to set key config for " << description << ": " + << cpp_strerror(r) << dendl; + cct->put(); + return r; + } + } + // disable unnecessary librbd cache cct->_conf.set_val_or_die("rbd_cache", "false"); cct->_conf.apply_changes(nullptr); diff --git a/src/tools/rbd_mirror/PoolReplayer.h b/src/tools/rbd_mirror/PoolReplayer.h index bcd428749cb..ef6d8276452 100644 --- a/src/tools/rbd_mirror/PoolReplayer.h +++ b/src/tools/rbd_mirror/PoolReplayer.h @@ -162,6 +162,8 @@ private: int init_rados(const std::string &cluster_name, const std::string &client_name, + const std::string &mon_host, + const std::string &key, const std::string &description, RadosRef *rados_ref, bool strip_cluster_overrides); @@ -236,7 +238,7 @@ private: std::unique_ptr> m_image_deleter; ImageMapListener m_image_map_listener; - std::unique_ptr> m_image_map; + std::unique_ptr> m_image_map; std::string m_asok_hook_name; AdminSocketHook *m_asok_hook = nullptr;