]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: connect to remote cluster using optional mon_host/key values
authorJason Dillaman <dillaman@redhat.com>
Tue, 11 Sep 2018 12:21:06 +0000 (08:21 -0400)
committerJason Dillaman <dillaman@redhat.com>
Wed, 12 Sep 2018 18:25:02 +0000 (14:25 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/test/librados_test_stub/LibradosTestStub.cc
src/test/librados_test_stub/MockTestMemCluster.h
src/test/librados_test_stub/MockTestMemRadosClient.h
src/test/librbd/test_mock_fixture.cc
src/test/rbd_mirror/CMakeLists.txt
src/test/rbd_mirror/test_mock_PoolReplayer.cc [new file with mode: 0644]
src/test/rbd_mirror/test_mock_fixture.cc
src/test/rbd_mirror/test_mock_fixture.h
src/tools/rbd_mirror/PoolReplayer.cc
src/tools/rbd_mirror/PoolReplayer.h

index 38a948a8571204b3d7eb5713a3c136826aba4b7d..6fec692e5b70ddbfee73bd66d7e506f0431b1863 100644 (file)
@@ -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<CephContext*>(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<rados_t *>(&client), id);
 }
 
+int Rados::init_with_context(config_t cct_) {
+  return rados_create_with_context(reinterpret_cast<rados_t *>(&client), cct_);
+}
+
 int Rados::ioctx_create(const char *name, IoCtx &io) {
   rados_ioctx_t p;
   int ret = rados_ioctx_create(reinterpret_cast<rados_t>(client), name, &p);
index 68e639c4b82a68b9fd7b11a60a1e7c75bfbf2965..685621a8c75d22616c6c984b0bbe7d197f6f256a 100644 (file)
@@ -16,11 +16,19 @@ class TestRadosClient;
 
 class MockTestMemCluster : public TestMemCluster {
 public:
-  TestRadosClient *create_rados_client(CephContext *cct) override {
-    return new ::testing::NiceMock<librados::MockTestMemRadosClient>(
-      cct, this);
+  MockTestMemCluster() {
+    default_to_dispatch();
   }
 
+  MOCK_METHOD1(create_rados_client, TestRadosClient*(CephContext*));
+  MockTestMemRadosClient* do_create_rados_client(CephContext *cct) {
+    return new ::testing::NiceMock<MockTestMemRadosClient>(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
index 1f44c499ded576038983c52406f76da50d04401f..92ad65733e792053eac39d36dc33b7febe3c840a 100644 (file)
@@ -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<MockTestMemIoCtxImpl>(
       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));
index fba57b739ccec6f4a7f78ae18a9d19a02940dfd5..0a467c1613733ccd7c2c46435a44d53969862638 100644 (file)
@@ -28,7 +28,7 @@ void TestMockFixture::SetUpTestCase() {
 
   // use a mock version of the in-memory cluster
   librados_test_stub::set_cluster(boost::shared_ptr<librados::TestCluster>(
-    new librados::MockTestMemCluster()));
+    new ::testing::NiceMock<librados::MockTestMemCluster>()));
   TestFixture::SetUpTestCase();
 }
 
@@ -45,6 +45,8 @@ void TestMockFixture::TearDown() {
 
   ::testing::Mock::VerifyAndClear(mock_rados_client);
   mock_rados_client->default_to_dispatch();
+  dynamic_cast<librados::MockTestMemCluster*>(
+    librados_test_stub::get_cluster().get())->default_to_dispatch();
 
   TestFixture::TearDown();
 }
index 3346f08c35a0fbbadd5a30fe793e3426137d8ddc..0b8497180ba506062905f9bbb3e03857c50acfd7 100644 (file)
@@ -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 (file)
index 0000000..0709201
--- /dev/null
@@ -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<librbd::MockTestImageCtx> {
+  static ImageDeleter* s_instance;
+
+  static ImageDeleter* create(librados::IoCtx &ioctx,
+                              Threads<librbd::MockTestImageCtx> *threads,
+                              ServiceDaemon<librbd::MockTestImageCtx> *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<librbd::MockTestImageCtx>* ImageDeleter<librbd::MockTestImageCtx>::s_instance = nullptr;
+
+template<>
+struct ImageMap<librbd::MockTestImageCtx> {
+  static ImageMap* s_instance;
+
+  static ImageMap *create(librados::IoCtx &ioctx,
+                          Threads<librbd::MockTestImageCtx> *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<std::string>&));
+  MOCK_METHOD1(update_instances_removed, void(const std::vector<std::string>&));
+
+  MOCK_METHOD3(update_images_mock, void(const std::string&,
+                                        const std::set<std::string>&,
+                                        const std::set<std::string>&));
+  void update_images(const std::string& mirror_uuid,
+                     std::set<std::string>&& added,
+                     std::set<std::string>&& removed) {
+    update_images_mock(mirror_uuid, added, removed);
+  }
+
+  ImageMap() {
+    s_instance = this;
+  }
+};
+
+ImageMap<librbd::MockTestImageCtx>* ImageMap<librbd::MockTestImageCtx>::s_instance = nullptr;
+
+template<>
+struct InstanceReplayer<librbd::MockTestImageCtx> {
+  static InstanceReplayer* s_instance;
+
+  static InstanceReplayer* create(Threads<librbd::MockTestImageCtx> *threads,
+                                  ServiceDaemon<librbd::MockTestImageCtx> *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<librbd::MockTestImageCtx>* InstanceReplayer<librbd::MockTestImageCtx>::s_instance = nullptr;
+
+template<>
+struct InstanceWatcher<librbd::MockTestImageCtx> {
+  static InstanceWatcher* s_instance;
+
+  static InstanceWatcher* create(librados::IoCtx &ioctx,
+                                 MockContextWQ* work_queue,
+                                 InstanceReplayer<librbd::MockTestImageCtx>* 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<librbd::MockTestImageCtx>* InstanceWatcher<librbd::MockTestImageCtx>::s_instance = nullptr;
+
+template<>
+struct LeaderWatcher<librbd::MockTestImageCtx> {
+  static LeaderWatcher* s_instance;
+
+  static LeaderWatcher *create(Threads<librbd::MockTestImageCtx> *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<std::string>*));
+
+  MOCK_METHOD0(init, int());
+  MOCK_METHOD0(shut_down, int());
+
+  LeaderWatcher() {
+    s_instance = this;
+  }
+
+};
+
+LeaderWatcher<librbd::MockTestImageCtx>* LeaderWatcher<librbd::MockTestImageCtx>::s_instance = nullptr;
+
+template<>
+struct PoolWatcher<librbd::MockTestImageCtx> {
+  static PoolWatcher* s_instance;
+
+  static PoolWatcher *create(Threads<librbd::MockTestImageCtx> *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<librbd::MockTestImageCtx>* PoolWatcher<librbd::MockTestImageCtx>::s_instance = nullptr;
+
+template<>
+struct ServiceDaemon<librbd::MockTestImageCtx> {
+  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<librbd::MockTestImageCtx> {
+  MockSafeTimer *timer;
+  Mutex &timer_lock;
+  Cond timer_cond;
+
+  MockContextWQ *work_queue;
+
+  Threads(Threads<librbd::ImageCtx> *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<librbd::MockTestImageCtx> MockPoolReplayer;
+  typedef ImageMap<librbd::MockTestImageCtx> MockImageMap;
+  typedef InstanceReplayer<librbd::MockTestImageCtx> MockInstanceReplayer;
+  typedef InstanceWatcher<librbd::MockTestImageCtx> MockInstanceWatcher;
+  typedef LeaderWatcher<librbd::MockTestImageCtx> MockLeaderWatcher;
+  typedef PoolWatcher<librbd::MockTestImageCtx> MockPoolWatcher;
+  typedef ServiceDaemon<librbd::MockTestImageCtx> MockServiceDaemon;
+  typedef Threads<librbd::MockTestImageCtx> 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<std::string>("mon_host"));
+  ASSERT_EQ("234", remote_cct->_conf.get_val<std::string>("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
index d5c6c7caf278744435594577693d1b105122ce07..9e308a63bcb5fce6160609d37459131a59a6a16d 100644 (file)
@@ -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<librados::TestCluster>(
-    new librados::MockTestMemCluster()));
+    new ::testing::NiceMock<librados::MockTestMemCluster>()));
   TestFixture::SetUpTestCase();
 }
 
@@ -39,6 +39,8 @@ void TestMockFixture::TearDown() {
 
   ::testing::Mock::VerifyAndClear(mock_rados_client);
   mock_rados_client->default_to_dispatch();
+  dynamic_cast<librados::MockTestMemCluster*>(
+    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
 
index 1fd2f9e70ce8fa636e2d1234723ecec9f83d6059..e6874b81722c73d0aa5fa2848c07828d5f8b86e4 100644 (file)
@@ -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;
 };
index ffdebde4039cf932063335bb59886712c3a8fbfb..2dbaf93f8f6038e893778ede398eb8bad908ce34 100644 (file)
@@ -279,7 +279,7 @@ void PoolReplayer<I>::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<I>::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<I>::init()
 
   dout(10) << "connected to " << m_peer << dendl;
 
-  m_instance_replayer.reset(InstanceReplayer<>::create(
+  m_instance_replayer.reset(InstanceReplayer<I>::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<I>::shut_down() {
 template <typename I>
 int PoolReplayer<I>::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<I>::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<I>::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);
index bcd428749cb74a304eb3f394339413c1953e0b04..ef6d8276452831ebde86d36f97f52923e6dae753 100644 (file)
@@ -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<ImageDeleter<ImageCtxT>> m_image_deleter;
 
   ImageMapListener m_image_map_listener;
-  std::unique_ptr<ImageMap<librbd::ImageCtx>> m_image_map;
+  std::unique_ptr<ImageMap<ImageCtxT>> m_image_map;
 
   std::string m_asok_hook_name;
   AdminSocketHook *m_asok_hook = nullptr;