]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: convert ImageDeleter to template
authorJason Dillaman <dillaman@redhat.com>
Tue, 11 Jul 2017 20:49:58 +0000 (16:49 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 18 Jul 2017 14:28:13 +0000 (10:28 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
14 files changed:
src/test/rbd_mirror/test_ImageDeleter.cc
src/test/rbd_mirror/test_ImageReplayer.cc
src/test/rbd_mirror/test_mock_ImageReplayer.cc
src/test/rbd_mirror/test_mock_InstanceReplayer.cc
src/tools/rbd_mirror/ImageDeleter.cc
src/tools/rbd_mirror/ImageDeleter.h
src/tools/rbd_mirror/ImageReplayer.cc
src/tools/rbd_mirror/ImageReplayer.h
src/tools/rbd_mirror/InstanceReplayer.cc
src/tools/rbd_mirror/InstanceReplayer.h
src/tools/rbd_mirror/Mirror.cc
src/tools/rbd_mirror/Mirror.h
src/tools/rbd_mirror/PoolReplayer.cc
src/tools/rbd_mirror/PoolReplayer.h

index 2aa0b3e9319b66e8ed8764e3f105443a54f1440a..24f52574949473b579f63cb5e7fc43be3761272b 100644 (file)
@@ -64,9 +64,9 @@ public:
 
     librbd::api::Mirror<>::mode_set(m_local_io_ctx, RBD_MIRROR_MODE_IMAGE);
 
-    m_deleter = new rbd::mirror::ImageDeleter(m_threads->work_queue,
-                                              m_threads->timer,
-                                              &m_threads->timer_lock);
+    m_deleter = new rbd::mirror::ImageDeleter<>(m_threads->work_queue,
+                                                m_threads->timer,
+                                                &m_threads->timer_lock);
 
     EXPECT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, 1 << 20));
     ImageCtx *ictx = new ImageCtx(m_image_name, "", "", m_local_io_ctx,
@@ -210,7 +210,7 @@ public:
 
   librbd::RBD rbd;
   std::string m_local_image_id;
-  rbd::mirror::ImageDeleter *m_deleter;
+  rbd::mirror::ImageDeleter<> *m_deleter;
 };
 
 int64_t TestImageDeleter::m_local_pool_id;
@@ -238,7 +238,7 @@ TEST_F(TestImageDeleter, Fail_Delete_Primary_Image) {
   C_SaferCond ctx;
   m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
                                          &ctx);
-  EXPECT_EQ(-rbd::mirror::ImageDeleter::EISPRM, ctx.wait());
+  EXPECT_EQ(-rbd::mirror::ImageDeleter<>::EISPRM, ctx.wait());
 
   ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
   ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
index 04259e4d12b24458d251738d10a9e12cd5fe758a..9b9791c48b46c203ce91e96b9a25ee753ebcdbdc 100644 (file)
@@ -115,9 +115,8 @@ public:
     m_threads = new rbd::mirror::Threads<>(reinterpret_cast<CephContext*>(
       m_local_ioctx.cct()));
 
-    m_image_deleter.reset(new rbd::mirror::ImageDeleter(m_threads->work_queue,
-                                                        m_threads->timer,
-                                                        &m_threads->timer_lock));
+    m_image_deleter.reset(new rbd::mirror::ImageDeleter<>(
+      m_threads->work_queue, m_threads->timer, &m_threads->timer_lock));
     m_instance_watcher = rbd::mirror::InstanceWatcher<>::create(
         m_local_ioctx, m_threads->work_queue, nullptr);
     m_instance_watcher->handle_acquire_leader();
@@ -140,7 +139,7 @@ public:
   template <typename ImageReplayerT = rbd::mirror::ImageReplayer<> >
   void create_replayer() {
     m_replayer = new ImageReplayerT(
-        m_threads, m_image_deleter, m_instance_watcher,
+        m_threads, m_image_deleter.get(), m_instance_watcher,
         rbd::mirror::RadosRef(new librados::Rados(m_local_ioctx)),
         m_local_mirror_uuid, m_local_ioctx.get_id(), "global image id");
     m_replayer->add_remote_image(m_remote_mirror_uuid, m_remote_image_id,
@@ -367,7 +366,7 @@ public:
   static int _image_number;
 
   rbd::mirror::Threads<> *m_threads = nullptr;
-  std::shared_ptr<rbd::mirror::ImageDeleter> m_image_deleter;
+  std::unique_ptr<rbd::mirror::ImageDeleter<>> m_image_deleter;
   std::shared_ptr<librados::Rados> m_local_cluster;
   librados::Rados m_remote_cluster;
   rbd::mirror::InstanceWatcher<> *m_instance_watcher;
index c95a92e6684427de855a77de952eba9d53e230be..7cff043ba7ad323bd3e0b4d86d174cef30eb9603 100644 (file)
@@ -4,6 +4,7 @@
 #include "cls/journal/cls_journal_types.h"
 #include "librbd/journal/Replay.h"
 #include "librbd/journal/Types.h"
+#include "tools/rbd_mirror/ImageDeleter.h"
 #include "tools/rbd_mirror/ImageReplayer.h"
 #include "tools/rbd_mirror/InstanceWatcher.h"
 #include "tools/rbd_mirror/image_replayer/BootstrapRequest.h"
@@ -60,6 +61,12 @@ struct MirrorPeerClientMeta;
 namespace rbd {
 namespace mirror {
 
+template <>
+struct ImageDeleter<librbd::MockTestImageCtx> {
+  MOCK_METHOD3(schedule_image_delete, void(RadosRef, int64_t,
+                                           const std::string&));
+};
+
 template<>
 class InstanceWatcher<librbd::MockTestImageCtx> {
 };
@@ -250,6 +257,7 @@ namespace mirror {
 
 class TestMockImageReplayer : public TestMockFixture {
 public:
+  typedef ImageDeleter<librbd::MockTestImageCtx> MockImageDeleter;
   typedef BootstrapRequest<librbd::MockTestImageCtx> MockBootstrapRequest;
   typedef CloseImageRequest<librbd::MockTestImageCtx> MockCloseImageRequest;
   typedef EventPreprocessor<librbd::MockTestImageCtx> MockEventPreprocessor;
@@ -265,16 +273,6 @@ public:
     librbd::RBD rbd;
     ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size));
     ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
-
-    m_image_deleter.reset(new rbd::mirror::ImageDeleter(m_threads->work_queue,
-                                                        m_threads->timer,
-                                                        &m_threads->timer_lock));
-    m_image_replayer = new MockImageReplayer(
-      m_threads, m_image_deleter, &m_instance_watcher,
-      rbd::mirror::RadosRef(new librados::Rados(m_local_io_ctx)),
-      "local_mirror_uuid", m_local_io_ctx.get_id(), "global image id");
-    m_image_replayer->add_remote_image(
-      "remote_mirror_uuid", m_remote_image_ctx->id, m_remote_io_ctx);
   }
 
   void TearDown() override {
@@ -446,11 +444,19 @@ public:
                       WithArg<2>(CompleteContext(on_commit_r))));
   }
 
+  void create_image_replayer(MockImageDeleter &mock_image_deleter) {
+    m_image_replayer = new MockImageReplayer(
+      m_threads, &mock_image_deleter, &m_instance_watcher,
+      rbd::mirror::RadosRef(new librados::Rados(m_local_io_ctx)),
+      "local_mirror_uuid", m_local_io_ctx.get_id(), "global image id");
+    m_image_replayer->add_remote_image(
+      "remote_mirror_uuid", m_remote_image_ctx->id, m_remote_io_ctx);
+  }
+
   librbd::ImageCtx *m_remote_image_ctx;
   librbd::ImageCtx *m_local_image_ctx = nullptr;
-  std::shared_ptr<rbd::mirror::ImageDeleter> m_image_deleter;
   MockInstanceWatcher m_instance_watcher;
-  MockImageReplayer *m_image_replayer;
+  MockImageReplayer *m_image_replayer = nullptr;
 };
 
 TEST_F(TestMockImageReplayer, StartStop) {
@@ -488,6 +494,9 @@ TEST_F(TestMockImageReplayer, StartStop) {
 
   EXPECT_CALL(mock_remote_journaler, start_live_replay(_, _));
 
+  MockImageDeleter mock_image_deleter;
+  create_image_replayer(mock_image_deleter);
+
   C_SaferCond start_ctx;
   m_image_replayer->start(&start_ctx);
   ASSERT_EQ(0, start_ctx.wait());
@@ -523,6 +532,9 @@ TEST_F(TestMockImageReplayer, LocalImagePrimary) {
   expect_send(mock_prepare_local_image_request, mock_local_image_ctx.id,
               "", 0);
 
+  MockImageDeleter mock_image_deleter;
+  create_image_replayer(mock_image_deleter);
+
   C_SaferCond start_ctx;
   m_image_replayer->start(&start_ctx);
   ASSERT_EQ(0, start_ctx.wait());
@@ -547,6 +559,9 @@ TEST_F(TestMockImageReplayer, LocalImageDNE) {
   EXPECT_CALL(mock_remote_journaler, remove_listener(_));
   expect_shut_down(mock_remote_journaler, 0);
 
+  MockImageDeleter mock_image_deleter;
+  create_image_replayer(mock_image_deleter);
+
   C_SaferCond start_ctx;
   m_image_replayer->start(&start_ctx);
   ASSERT_EQ(0, start_ctx.wait());
@@ -565,6 +580,9 @@ TEST_F(TestMockImageReplayer, PrepareLocalImageError) {
   expect_send(mock_prepare_local_image_request, mock_local_image_ctx.id,
               "remote mirror uuid", -EINVAL);
 
+  MockImageDeleter mock_image_deleter;
+  create_image_replayer(mock_image_deleter);
+
   C_SaferCond start_ctx;
   m_image_replayer->start(&start_ctx);
   ASSERT_EQ(-EINVAL, start_ctx.wait());
@@ -591,6 +609,9 @@ TEST_F(TestMockImageReplayer, BootstrapError) {
   EXPECT_CALL(mock_remote_journaler, remove_listener(_));
   expect_shut_down(mock_remote_journaler, 0);
 
+  MockImageDeleter mock_image_deleter;
+  create_image_replayer(mock_image_deleter);
+
   C_SaferCond start_ctx;
   m_image_replayer->start(&start_ctx);
   ASSERT_EQ(-EINVAL, start_ctx.wait());
@@ -636,6 +657,9 @@ TEST_F(TestMockImageReplayer, StartExternalReplayError) {
   EXPECT_CALL(mock_remote_journaler, remove_listener(_));
   expect_shut_down(mock_remote_journaler, 0);
 
+  MockImageDeleter mock_image_deleter;
+  create_image_replayer(mock_image_deleter);
+
   C_SaferCond start_ctx;
   m_image_replayer->start(&start_ctx);
   ASSERT_EQ(-EINVAL, start_ctx.wait());
@@ -676,6 +700,9 @@ TEST_F(TestMockImageReplayer, StopError) {
 
   EXPECT_CALL(mock_remote_journaler, start_live_replay(_, _));
 
+  MockImageDeleter mock_image_deleter;
+  create_image_replayer(mock_image_deleter);
+
   C_SaferCond start_ctx;
   m_image_replayer->start(&start_ctx);
   ASSERT_EQ(0, start_ctx.wait());
@@ -736,6 +763,9 @@ TEST_F(TestMockImageReplayer, Replay) {
 
   EXPECT_CALL(mock_remote_journaler, start_live_replay(_, _));
 
+  MockImageDeleter mock_image_deleter;
+  create_image_replayer(mock_image_deleter);
+
   C_SaferCond start_ctx;
   m_image_replayer->start(&start_ctx);
   ASSERT_EQ(0, start_ctx.wait());
@@ -833,6 +863,9 @@ TEST_F(TestMockImageReplayer, DecodeError) {
 
   EXPECT_CALL(mock_remote_journaler, start_live_replay(_, _));
 
+  MockImageDeleter mock_image_deleter;
+  create_image_replayer(mock_image_deleter);
+
   C_SaferCond start_ctx;
   m_image_replayer->start(&start_ctx);
   ASSERT_EQ(0, start_ctx.wait());
@@ -924,6 +957,9 @@ TEST_F(TestMockImageReplayer, DelayedReplay) {
 
   EXPECT_CALL(mock_remote_journaler, start_live_replay(_, _));
 
+  MockImageDeleter mock_image_deleter;
+  create_image_replayer(mock_image_deleter);
+
   C_SaferCond start_ctx;
   m_image_replayer->start(&start_ctx);
   ASSERT_EQ(0, start_ctx.wait());
index f2a1d1b34f1f82ecaea4c82585533d949df00c5d..f577aa47ba42a7078c3923f4c18a225f1085ca6a 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "test/librbd/mock/MockImageCtx.h"
 #include "test/rbd_mirror/test_mock_fixture.h"
+#include "tools/rbd_mirror/ImageDeleter.h"
 #include "tools/rbd_mirror/ImageReplayer.h"
 #include "tools/rbd_mirror/InstanceWatcher.h"
 #include "tools/rbd_mirror/InstanceReplayer.h"
@@ -37,6 +38,14 @@ struct Threads<librbd::MockTestImageCtx> {
   }
 };
 
+template <>
+struct ImageDeleter<librbd::MockTestImageCtx> {
+  MOCK_METHOD3(schedule_image_delete, void(RadosRef, int64_t,
+                                           const std::string&));
+  MOCK_METHOD4(wait_for_scheduled_deletion,
+               void(int64_t, const std::string&, Context*, bool));
+};
+
 template<>
 struct InstanceWatcher<librbd::MockTestImageCtx> {
 };
@@ -48,7 +57,7 @@ struct ImageReplayer<librbd::MockTestImageCtx> {
 
   static ImageReplayer *create(
     Threads<librbd::MockTestImageCtx> *threads,
-    std::shared_ptr<ImageDeleter> image_deleter,
+    ImageDeleter<librbd::MockTestImageCtx>* image_deleter,
     InstanceWatcher<librbd::MockTestImageCtx> *instance_watcher,
     RadosRef local, const std::string &local_mirror_uuid, int64_t local_pool_id,
     const std::string &global_image_id) {
@@ -103,9 +112,11 @@ using ::testing::InSequence;
 using ::testing::Invoke;
 using ::testing::Return;
 using ::testing::ReturnRef;
+using ::testing::WithArg;
 
 class TestMockInstanceReplayer : public TestMockFixture {
 public:
+  typedef ImageDeleter<librbd::MockTestImageCtx> MockImageDeleter;
   typedef ImageReplayer<librbd::MockTestImageCtx> MockImageReplayer;
   typedef InstanceReplayer<librbd::MockTestImageCtx> MockInstanceReplayer;
   typedef InstanceWatcher<librbd::MockTestImageCtx> MockInstanceWatcher;
@@ -115,10 +126,6 @@ public:
     TestMockFixture::SetUp();
 
     m_mock_threads = new MockThreads(m_threads);
-
-    m_image_deleter.reset(
-      new rbd::mirror::ImageDeleter(m_threads->work_queue, m_threads->timer,
-                                    &m_threads->timer_lock));
   }
 
   void TearDown() override {
@@ -126,15 +133,25 @@ public:
     TestMockFixture::TearDown();
   }
 
+  void expect_wait_for_scheduled_deletion(MockImageDeleter& mock_image_deleter,
+                                          const std::string& global_image_id,
+                                          int r) {
+    EXPECT_CALL(mock_image_deleter,
+                wait_for_scheduled_deletion(_, global_image_id, _, false))
+      .WillOnce(WithArg<2>(Invoke([this, r](Context *ctx) {
+                             m_threads->work_queue->queue(ctx, r);
+                           })));
+  }
+
   MockThreads *m_mock_threads;
-  std::shared_ptr<rbd::mirror::ImageDeleter> m_image_deleter;
 };
 
 TEST_F(TestMockInstanceReplayer, AcquireReleaseImage) {
+  MockImageDeleter mock_image_deleter;
   MockInstanceWatcher mock_instance_watcher;
   MockImageReplayer mock_image_replayer;
   MockInstanceReplayer instance_replayer(
-    m_mock_threads, m_image_deleter,
+    m_mock_threads, &mock_image_deleter,
     rbd::mirror::RadosRef(new librados::Rados(m_local_io_ctx)),
     "local_mirror_uuid", m_local_io_ctx.get_id());
 
@@ -145,6 +162,8 @@ TEST_F(TestMockInstanceReplayer, AcquireReleaseImage) {
   EXPECT_CALL(mock_image_replayer, is_blacklisted())
     .WillRepeatedly(Return(false));
 
+  expect_wait_for_scheduled_deletion(mock_image_deleter, "global_image_id", 0);
+
   InSequence seq;
 
   instance_replayer.init();
index b3b1c4429d3bfb01bec06acd5bfcb5aaa42307d7..a0047d353c4dd38d07b6fda7a21885ac5318025f 100644 (file)
@@ -11,6 +11,7 @@
  * Foundation.  See file COPYING.
  *
  */
+
 #include <boost/bind.hpp>
 #include <map>
 #include <set>
@@ -61,9 +62,10 @@ public:
   virtual bool call(Formatter *f, stringstream *ss) = 0;
 };
 
+template <typename I>
 class StatusCommand : public ImageDeleterAdminSocketCommand {
 public:
-  explicit StatusCommand(ImageDeleter *image_del) : image_del(image_del) {}
+  explicit StatusCommand(ImageDeleter<I> *image_del) : image_del(image_del) {}
 
   bool call(Formatter *f, stringstream *ss) override {
     image_del->print_status(f, ss);
@@ -71,7 +73,7 @@ public:
   }
 
 private:
-  ImageDeleter *image_del;
+  ImageDeleter<I> *image_del;
 };
 
 struct DeleteJournalPolicy : public librbd::journal::Policy {
@@ -89,9 +91,10 @@ struct DeleteJournalPolicy : public librbd::journal::Policy {
 
 } // anonymous namespace
 
+template <typename I>
 class ImageDeleterAdminSocketHook : public AdminSocketHook {
 public:
-  ImageDeleterAdminSocketHook(CephContext *cct, ImageDeleter *image_del) :
+  ImageDeleterAdminSocketHook(CephContext *cct, ImageDeleter<I> *image_del) :
     admin_socket(cct->get_admin_socket()) {
 
     std::string command;
@@ -101,7 +104,7 @@ public:
     r = admin_socket->register_command(command, command, this,
                                       "get status for image deleter");
     if (r == 0) {
-      commands[command] = new StatusCommand(image_del);
+      commands[command] = new StatusCommand<I>(image_del);
     }
 
   }
@@ -132,21 +135,23 @@ private:
   Commands commands;
 };
 
-ImageDeleter::ImageDeleter(ContextWQ *work_queue, SafeTimer *timer,
-                           Mutex *timer_lock)
+template <typename I>
+ImageDeleter<I>::ImageDeleter(ContextWQ *work_queue, SafeTimer *timer,
+                              Mutex *timer_lock)
   : m_running(true),
     m_work_queue(work_queue),
     m_delete_lock("rbd::mirror::ImageDeleter::Delete"),
     m_image_deleter_thread(this),
     m_failed_timer(timer),
     m_failed_timer_lock(timer_lock),
-    m_asok_hook(new ImageDeleterAdminSocketHook(g_ceph_context, this))
+    m_asok_hook(new ImageDeleterAdminSocketHook<I>(g_ceph_context, this))
 {
   set_failed_timer_interval(g_ceph_context->_conf->rbd_mirror_delete_retry_interval);
   m_image_deleter_thread.create("image_deleter");
 }
 
-ImageDeleter::~ImageDeleter() {
+template <typename I>
+ImageDeleter<I>::~ImageDeleter() {
   dout(20) << "enter" << dendl;
 
   m_running = false;
@@ -162,7 +167,8 @@ ImageDeleter::~ImageDeleter() {
   dout(20) << "return" << dendl;
 }
 
-void ImageDeleter::run() {
+template <typename I>
+void ImageDeleter<I>::run() {
   dout(20) << "enter" << dendl;
   while(m_running) {
     m_delete_lock.Lock();
@@ -196,9 +202,10 @@ void ImageDeleter::run() {
   }
 }
 
-void ImageDeleter::schedule_image_delete(RadosRef local_rados,
-                                         int64_t local_pool_id,
-                                         const std::string& global_image_id) {
+template <typename I>
+void ImageDeleter<I>::schedule_image_delete(RadosRef local_rados,
+                                            int64_t local_pool_id,
+                                            const std::string& global_image_id) {
   dout(20) << "enter" << dendl;
 
   Mutex::Locker locker(m_delete_lock);
@@ -216,10 +223,11 @@ void ImageDeleter::schedule_image_delete(RadosRef local_rados,
   m_delete_queue_cond.Signal();
 }
 
-void ImageDeleter::wait_for_scheduled_deletion(int64_t local_pool_id,
-                                               const std::string &global_image_id,
-                                               Context *ctx,
-                                               bool notify_on_failed_retry) {
+template <typename I>
+void ImageDeleter<I>::wait_for_scheduled_deletion(int64_t local_pool_id,
+                                                  const std::string &global_image_id,
+                                                  Context *ctx,
+                                                  bool notify_on_failed_retry) {
 
   ctx = new FunctionContext([this, ctx](int r) {
       m_work_queue->queue(ctx, r);
@@ -243,8 +251,9 @@ void ImageDeleter::wait_for_scheduled_deletion(int64_t local_pool_id,
   (*del_info)->notify_on_failed_retry = notify_on_failed_retry;
 }
 
-void ImageDeleter::cancel_waiter(int64_t local_pool_id,
-                                 const std::string &global_image_id) {
+template <typename I>
+void ImageDeleter<I>::cancel_waiter(int64_t local_pool_id,
+                                    const std::string &global_image_id) {
   Mutex::Locker locker(m_delete_lock);
   auto del_info = find_delete_info(local_pool_id, global_image_id);
   if (!del_info) {
@@ -257,8 +266,8 @@ void ImageDeleter::cancel_waiter(int64_t local_pool_id,
   }
 }
 
-bool ImageDeleter::process_image_delete() {
-
+template <typename I>
+bool ImageDeleter<I>::process_image_delete() {
   stringstream ss;
   m_active_delete->to_string(ss);
   std::string del_info_str = ss.str();
@@ -458,10 +467,10 @@ bool ImageDeleter::process_image_delete() {
   return true;
 }
 
-int ImageDeleter::image_has_snapshots_and_children(IoCtx *ioctx,
-                                                   string& image_id,
-                                                   bool *has_snapshots) {
-
+template <typename I>
+int ImageDeleter<I>::image_has_snapshots_and_children(IoCtx *ioctx,
+                                                      string& image_id,
+                                                      bool *has_snapshots) {
   string header_oid = librbd::util::header_name(image_id);
   ::SnapContext snapc;
   int r = cls_client::get_snapcontext(ioctx, header_oid, &snapc);
@@ -476,7 +485,8 @@ int ImageDeleter::image_has_snapshots_and_children(IoCtx *ioctx,
   return 0;
 }
 
-void ImageDeleter::complete_active_delete(int r) {
+template <typename I>
+void ImageDeleter<I>::complete_active_delete(int r) {
   dout(20) << dendl;
 
   Mutex::Locker delete_locker(m_delete_lock);
@@ -484,7 +494,8 @@ void ImageDeleter::complete_active_delete(int r) {
   m_active_delete.reset();
 }
 
-void ImageDeleter::enqueue_failed_delete(int error_code) {
+template <typename I>
+void ImageDeleter<I>::enqueue_failed_delete(int error_code) {
   dout(20) << "enter" << dendl;
 
   if (error_code == -EBLACKLISTED) {
@@ -503,13 +514,14 @@ void ImageDeleter::enqueue_failed_delete(int error_code) {
   m_delete_lock.Unlock();
   if (was_empty) {
     FunctionContext *ctx = new FunctionContext(
-      boost::bind(&ImageDeleter::retry_failed_deletions, this));
+      boost::bind(&ImageDeleter<I>::retry_failed_deletions, this));
     Mutex::Locker l(*m_failed_timer_lock);
     m_failed_timer->add_event_after(m_failed_interval, ctx);
   }
 }
 
-void ImageDeleter::retry_failed_deletions() {
+template <typename I>
+void ImageDeleter<I>::retry_failed_deletions() {
   dout(20) << "enter" << dendl;
 
   Mutex::Locker l(m_delete_lock);
@@ -525,8 +537,10 @@ void ImageDeleter::retry_failed_deletions() {
   }
 }
 
-unique_ptr<ImageDeleter::DeleteInfo> const* ImageDeleter::find_delete_info(
-    int64_t local_pool_id, const std::string &global_image_id) {
+template <typename I>
+unique_ptr<typename ImageDeleter<I>::DeleteInfo> const*
+ImageDeleter<I>::find_delete_info(int64_t local_pool_id,
+                                  const std::string &global_image_id) {
   assert(m_delete_lock.is_locked());
 
   if (m_active_delete && m_active_delete->match(local_pool_id,
@@ -549,7 +563,8 @@ unique_ptr<ImageDeleter::DeleteInfo> const* ImageDeleter::find_delete_info(
   return nullptr;
 }
 
-void ImageDeleter::print_status(Formatter *f, stringstream *ss) {
+template <typename I>
+void ImageDeleter<I>::print_status(Formatter *f, stringstream *ss) {
   dout(20) << "enter" << dendl;
 
   if (f) {
@@ -578,7 +593,8 @@ void ImageDeleter::print_status(Formatter *f, stringstream *ss) {
   }
 }
 
-void ImageDeleter::DeleteInfo::notify(int r) {
+template <typename I>
+void ImageDeleter<I>::DeleteInfo::notify(int r) {
   if (on_delete) {
     dout(20) << "executing image deletion handler r=" << r << dendl;
 
@@ -588,13 +604,15 @@ void ImageDeleter::DeleteInfo::notify(int r) {
   }
 }
 
-void ImageDeleter::DeleteInfo::to_string(stringstream& ss) {
+template <typename I>
+void ImageDeleter<I>::DeleteInfo::to_string(stringstream& ss) {
   ss << "[" << "local_pool_id=" << local_pool_id << ", ";
   ss << "global_image_id=" << global_image_id << "]";
 }
 
-void ImageDeleter::DeleteInfo::print_status(Formatter *f, stringstream *ss,
-                                            bool print_failure_info) {
+template <typename I>
+void ImageDeleter<I>::DeleteInfo::print_status(Formatter *f, stringstream *ss,
+                                               bool print_failure_info) {
   if (f) {
     f->open_object_section("delete_info");
     f->dump_int("local_pool_id", local_pool_id);
@@ -610,7 +628,8 @@ void ImageDeleter::DeleteInfo::print_status(Formatter *f, stringstream *ss,
   }
 }
 
-vector<string> ImageDeleter::get_delete_queue_items() {
+template <typename I>
+vector<string> ImageDeleter<I>::get_delete_queue_items() {
   vector<string> items;
 
   Mutex::Locker l(m_delete_lock);
@@ -621,7 +640,8 @@ vector<string> ImageDeleter::get_delete_queue_items() {
   return items;
 }
 
-vector<pair<string, int> > ImageDeleter::get_failed_queue_items() {
+template <typename I>
+vector<pair<string, int> > ImageDeleter<I>::get_failed_queue_items() {
   vector<pair<string, int> > items;
 
   Mutex::Locker l(m_delete_lock);
@@ -633,9 +653,12 @@ vector<pair<string, int> > ImageDeleter::get_failed_queue_items() {
   return items;
 }
 
-void ImageDeleter::set_failed_timer_interval(double interval) {
+template <typename I>
+void ImageDeleter<I>::set_failed_timer_interval(double interval) {
   this->m_failed_interval = interval;
 }
 
 } // namespace mirror
 } // namespace rbd
+
+template class rbd::mirror::ImageDeleter<librbd::ImageCtx>;
index c91f2fbc6ff138a3680f2f8bdbf67442c4da5d35..e55337680f090cee3b68bfe1b5d1b0aae281f8b6 100644 (file)
 #include <vector>
 #include <atomic>
 
+class AdminSocketHook;
 class ContextWQ;
+namespace librbd { struct ImageCtx; }
 
 namespace rbd {
 namespace mirror {
 
-class ImageDeleterAdminSocketHook;
-
 /**
  * Manage deletion of non-primary images.
  */
+template <typename ImageCtxT = librbd::ImageCtx>
 class ImageDeleter {
 public:
   static const int EISPRM = 1000;
@@ -116,7 +117,7 @@ private:
   SafeTimer *m_failed_timer;
   Mutex *m_failed_timer_lock;
 
-  ImageDeleterAdminSocketHook *m_asok_hook;
+  AdminSocketHook *m_asok_hook;
 
   void run();
   bool process_image_delete();
@@ -136,4 +137,6 @@ private:
 } // namespace mirror
 } // namespace rbd
 
+extern template class rbd::mirror::ImageDeleter<librbd::ImageCtx>;
+
 #endif // CEPH_RBD_MIRROR_IMAGEDELETER_H
index b025566d5315125bc4d3d1d00bc27e231e5d49fc..fb3cb89a83ac1b81d69842ceffa8d3b2e806dbab 100644 (file)
@@ -271,7 +271,7 @@ void ImageReplayer<I>::RemoteJournalerListener::handle_update(
 
 template <typename I>
 ImageReplayer<I>::ImageReplayer(Threads<librbd::ImageCtx> *threads,
-                                shared_ptr<ImageDeleter> image_deleter,
+                                ImageDeleter<I>* image_deleter,
                                 InstanceWatcher<I> *instance_watcher,
                                 RadosRef local,
                                 const std::string &local_mirror_uuid,
index 9e4597a3da863584d91bb295b1f11b7b32023932..1e3eca583954b00fc5c8cad3f8b2c5d776196cc0 100644 (file)
@@ -72,8 +72,7 @@ public:
   };
 
   static ImageReplayer *create(
-    Threads<librbd::ImageCtx> *threads,
-    std::shared_ptr<ImageDeleter> image_deleter,
+    Threads<librbd::ImageCtx> *threads, ImageDeleter<ImageCtxT>* image_deleter,
     InstanceWatcher<ImageCtxT> *instance_watcher,
     RadosRef local, const std::string &local_mirror_uuid, int64_t local_pool_id,
     const std::string &global_image_id) {
@@ -86,7 +85,7 @@ public:
   }
 
   ImageReplayer(Threads<librbd::ImageCtx> *threads,
-                std::shared_ptr<ImageDeleter> image_deleter,
+                ImageDeleter<ImageCtxT>* image_deleter,
                 InstanceWatcher<ImageCtxT> *instance_watcher,
                 RadosRef local, const std::string &local_mirror_uuid,
                 int64_t local_pool_id, const std::string &global_image_id);
@@ -283,7 +282,7 @@ private:
   };
 
   Threads<librbd::ImageCtx> *m_threads;
-  std::shared_ptr<ImageDeleter> m_image_deleter;
+  ImageDeleter<ImageCtxT>* m_image_deleter;
   InstanceWatcher<ImageCtxT> *m_instance_watcher;
 
   RemoteImages m_remote_images;
index 2b732617d8ae31f8f049acf7f538b459a4022ca3..74efb295759eeeb6eb0b68e7b4b26d939660519c 100644 (file)
@@ -24,7 +24,7 @@ using librbd::util::create_context_callback;
 
 template <typename I>
 InstanceReplayer<I>::InstanceReplayer(
-    Threads<I> *threads, std::shared_ptr<ImageDeleter> image_deleter,
+    Threads<I> *threads, ImageDeleter<I>* image_deleter,
     RadosRef local_rados, const std::string &local_mirror_uuid,
     int64_t local_pool_id)
   : m_threads(threads), m_image_deleter(image_deleter),
index 501218ba0663423958d0bcdfbfdf807953b52639..b704f1785cf13775df181524b25171aa7e389d70 100644 (file)
@@ -17,8 +17,7 @@ namespace librbd { class ImageCtx; }
 namespace rbd {
 namespace mirror {
 
-class ImageDeleter;
-
+template <typename> class ImageDeleter;
 template <typename> class ImageReplayer;
 template <typename> class InstanceWatcher;
 template <typename> struct Threads;
@@ -27,7 +26,8 @@ template <typename ImageCtxT = librbd::ImageCtx>
 class InstanceReplayer {
 public:
   static InstanceReplayer* create(
-      Threads<ImageCtxT> *threads, std::shared_ptr<ImageDeleter> image_deleter,
+      Threads<ImageCtxT> *threads,
+      ImageDeleter<ImageCtxT>* image_deleter,
       RadosRef local_rados, const std::string &local_mirror_uuid,
       int64_t local_pool_id) {
     return new InstanceReplayer(threads, image_deleter, local_rados,
@@ -38,7 +38,7 @@ public:
   }
 
   InstanceReplayer(Threads<ImageCtxT> *threads,
-                  std::shared_ptr<ImageDeleter> image_deleter,
+                  ImageDeleter<ImageCtxT>* image_deleter,
                   RadosRef local_rados, const std::string &local_mirror_uuid,
                   int64_t local_pool_id);
   ~InstanceReplayer();
@@ -109,7 +109,7 @@ private:
   typedef std::set<Peer> Peers;
 
   Threads<ImageCtxT> *m_threads;
-  std::shared_ptr<ImageDeleter> m_image_deleter;
+  ImageDeleter<ImageCtxT>* m_image_deleter;
   RadosRef m_local_rados;
   std::string m_local_mirror_uuid;
   int64_t m_local_pool_id;
index d383a8b0af5bbbd14843470c2ea7d4848a6e1115..4697d37b67357623d302e86b6f9831d92a7a9831 100644 (file)
@@ -238,9 +238,9 @@ int Mirror::init()
 
   m_local_cluster_watcher.reset(new ClusterWatcher(m_local, m_lock));
 
-  m_image_deleter.reset(new ImageDeleter(m_threads->work_queue,
-                                         m_threads->timer,
-                                         &m_threads->timer_lock));
+  m_image_deleter.reset(new ImageDeleter<>(m_threads->work_queue,
+                                           m_threads->timer,
+                                           &m_threads->timer_lock));
 
   return r;
 }
@@ -399,7 +399,7 @@ void Mirror::update_pool_replayers(const PoolPeers &pool_peers)
       if (m_pool_replayers.find(pool_peer) == m_pool_replayers.end()) {
         dout(20) << "starting pool replayer for " << peer << dendl;
         unique_ptr<PoolReplayer> pool_replayer(new PoolReplayer(
-         m_threads, m_image_deleter, kv.first, peer, m_args));
+         m_threads, m_image_deleter.get(), kv.first, peer, m_args));
 
         // TODO: make async, and retry connecting within pool replayer
         int r = pool_replayer->init();
index cda474f19135de87f596eaa825c13acb4d311915..17d712f37d9f2de7aab505ab1210c73527c0f131 100644 (file)
@@ -64,7 +64,7 @@ private:
 
   // monitor local cluster for config changes in peers
   std::unique_ptr<ClusterWatcher> m_local_cluster_watcher;
-  std::shared_ptr<ImageDeleter> m_image_deleter;
+  std::unique_ptr<ImageDeleter<>> m_image_deleter;
   std::map<PoolPeer, std::unique_ptr<PoolReplayer> > m_pool_replayers;
   std::atomic<bool> m_stopping = { false };
   bool m_manual_stop = false;
index a5a727ecd20b18a315b6ae3c0f1e447f0393e6a0..f63828eadce73b8e7012c2c8c17559b527f99631 100644 (file)
@@ -206,7 +206,7 @@ private:
 } // anonymous namespace
 
 PoolReplayer::PoolReplayer(Threads<librbd::ImageCtx> *threads,
-                          std::shared_ptr<ImageDeleter> image_deleter,
+                          ImageDeleter<>* image_deleter,
                           int64_t local_pool_id, const peer_t &peer,
                           const std::vector<const char*> &args) :
   m_threads(threads),
index 09ad6835d9c5a85ad2b9f8db1e84ab29ca3866e5..1c4170a0a0b7aaac885b54cb9762b74e5752bceb 100644 (file)
@@ -39,7 +39,7 @@ template <typename> class InstanceWatcher;
 class PoolReplayer {
 public:
   PoolReplayer(Threads<librbd::ImageCtx> *threads,
-              std::shared_ptr<ImageDeleter> image_deleter,
+              ImageDeleter<>* image_deleter,
               int64_t local_pool_id, const peer_t &peer,
               const std::vector<const char*> &args);
   ~PoolReplayer();
@@ -102,7 +102,7 @@ private:
   void handle_update_leader(const std::string &leader_instance_id);
 
   Threads<librbd::ImageCtx> *m_threads;
-  std::shared_ptr<ImageDeleter> m_image_deleter;
+  ImageDeleter<>* m_image_deleter;
   mutable Mutex m_lock;
   Cond m_cond;
   std::atomic<bool> m_stopping = { false };