]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: include local pool id in resync throttle unique key 10678/head
authorJason Dillaman <dillaman@redhat.com>
Tue, 12 Jul 2016 01:58:45 +0000 (21:58 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 11 Aug 2016 15:28:19 +0000 (11:28 -0400)
Fixes: http://tracker.ceph.com/issues/16536
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 8ad36cab7cbf3492bfa972b43e4a5f75a110bfe6)

src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc
src/test/rbd_mirror/test_mock_ImageSyncThrottler.cc
src/tools/rbd_mirror/ImageSyncThrottler.cc
src/tools/rbd_mirror/ImageSyncThrottler.h
src/tools/rbd_mirror/image_replayer/BootstrapRequest.cc

index 3aae98a178c9a1884de8cd9c3cfeba444b0a618d..7d2e37e01144a2f581da040cdcb9750152a9280c 100644 (file)
@@ -81,7 +81,8 @@ struct ImageSyncThrottler<librbd::MockTestImageCtx> {
                                  librbd::journal::MirrorPeerClientMeta *client_meta,
                                  ContextWQ *work_queue, Context *on_finish,
                                  ProgressContext *progress_ctx));
-  MOCK_METHOD1(cancel_sync, void(const std::string& mirror_uuid));
+  MOCK_METHOD2(cancel_sync, void(librados::IoCtx &local_io_ctx,
+                                 const std::string& mirror_uuid));
 };
 
 namespace image_replayer {
index 01f875c93977835c9ae2c68e5733493fa7b3fc73..e624ed90e478e7cba4554e2ca67d896bd4ced8d2 100644 (file)
@@ -159,7 +159,7 @@ public:
     } else {
       EXPECT_CALL(*sync, cancel()).Times(0);
     }
-    mock_sync_throttler->cancel_sync(mirror_uuid);
+    mock_sync_throttler->cancel_sync(m_local_io_ctx, mirror_uuid);
   }
 
   librbd::ImageCtx *m_remote_image_ctx;
index fd759acbb7e25d0444d51d5dbef112bff0afbbf6..2a22b351d0c16052d4d05e1dab5f628a4816685a 100644 (file)
@@ -49,24 +49,26 @@ ImageSyncThrottler<I>::~ImageSyncThrottler() {
 }
 
 template <typename I>
-void ImageSyncThrottler<I>::start_sync(
-                            I *local_image_ctx, I *remote_image_ctx,
-                            SafeTimer *timer, Mutex *timer_lock,
-                            const std::string &mirror_uuid,
-                            Journaler *journaler,
-                            MirrorPeerClientMeta *client_meta,
-                            ContextWQ *work_queue, Context *on_finish,
-                            ProgressContext *progress_ctx) {
+void ImageSyncThrottler<I>::start_sync(I *local_image_ctx, I *remote_image_ctx,
+                                       SafeTimer *timer, Mutex *timer_lock,
+                                       const std::string &mirror_uuid,
+                                       Journaler *journaler,
+                                       MirrorPeerClientMeta *client_meta,
+                                       ContextWQ *work_queue,
+                                       Context *on_finish,
+                                       ProgressContext *progress_ctx) {
   dout(20) << dendl;
 
-  C_SyncHolder *sync_holder_ctx = new C_SyncHolder(this, local_image_ctx->id,
+  PoolImageId pool_image_id(local_image_ctx->md_ctx.get_id(),
+                            local_image_ctx->id);
+  C_SyncHolder *sync_holder_ctx = new C_SyncHolder(this, pool_image_id,
                                                    on_finish);
   sync_holder_ctx->m_sync = ImageSync<I>::create(local_image_ctx,
-                                         remote_image_ctx, timer,
-                                         timer_lock, mirror_uuid,
-                                         journaler, client_meta,
-                                         work_queue, sync_holder_ctx,
-                                        progress_ctx);
+                                                 remote_image_ctx, timer,
+                                                 timer_lock, mirror_uuid,
+                                                 journaler, client_meta,
+                                                 work_queue, sync_holder_ctx,
+                                                 progress_ctx);
   sync_holder_ctx->m_sync->get();
 
   bool start = false;
@@ -74,8 +76,8 @@ void ImageSyncThrottler<I>::start_sync(
     Mutex::Locker l(m_lock);
 
     if (m_inflight_syncs.size() < m_max_concurrent_syncs) {
-      m_inflight_syncs.insert(std::make_pair(local_image_ctx->id,
-                                             sync_holder_ctx));
+      assert(m_inflight_syncs.count(pool_image_id) == 0);
+      m_inflight_syncs[pool_image_id] = sync_holder_ctx;
       start = true;
       dout(10) << "ready to start image sync for local_image_id "
                << local_image_ctx->id << " [" << m_inflight_syncs.size() << "/"
@@ -88,12 +90,13 @@ void ImageSyncThrottler<I>::start_sync(
   }
 
   if (start) {
-      sync_holder_ctx->m_sync->send();
+    sync_holder_ctx->m_sync->send();
   }
 }
 
 template <typename I>
-void ImageSyncThrottler<I>::cancel_sync(const std::string& local_image_id) {
+void ImageSyncThrottler<I>::cancel_sync(librados::IoCtx &local_io_ctx,
+                                        const std::string local_image_id) {
   dout(20) << dendl;
 
   C_SyncHolder *sync_holder = nullptr;
@@ -101,20 +104,21 @@ void ImageSyncThrottler<I>::cancel_sync(const std::string& local_image_id) {
 
   {
     Mutex::Locker l(m_lock);
-
     if (m_inflight_syncs.empty()) {
       // no image sync currently running and neither waiting
       return;
     }
 
-    auto it = m_inflight_syncs.find(local_image_id);
+    PoolImageId local_pool_image_id(local_io_ctx.get_id(),
+                                    local_image_id);
+    auto it = m_inflight_syncs.find(local_pool_image_id);
     if (it != m_inflight_syncs.end()) {
       sync_holder = it->second;
     }
 
     if (!sync_holder) {
-      for (auto it=m_sync_queue.begin(); it != m_sync_queue.end(); ++it) {
-        if ((*it)->m_local_image_id == local_image_id) {
+      for (auto it = m_sync_queue.begin(); it != m_sync_queue.end(); ++it) {
+        if ((*it)->m_local_pool_image_id == local_pool_image_id) {
           sync_holder = (*it);
           m_sync_queue.erase(it);
           running_sync = false;
@@ -127,11 +131,11 @@ void ImageSyncThrottler<I>::cancel_sync(const std::string& local_image_id) {
   if (sync_holder) {
     if (running_sync) {
       dout(10) << "canceled running image sync for local_image_id "
-               << sync_holder->m_local_image_id << dendl;
+               << sync_holder->m_local_pool_image_id.second << dendl;
       sync_holder->m_sync->cancel();
     } else {
       dout(10) << "canceled waiting image sync for local_image_id "
-               << sync_holder->m_local_image_id << dendl;
+               << sync_holder->m_local_pool_image_id.second << dendl;
       sync_holder->m_on_finish->complete(-ECANCELED);
       sync_holder->m_sync->put();
       delete sync_holder;
@@ -147,17 +151,19 @@ void ImageSyncThrottler<I>::handle_sync_finished(C_SyncHolder *sync_holder) {
 
   {
     Mutex::Locker l(m_lock);
+    m_inflight_syncs.erase(sync_holder->m_local_pool_image_id);
 
-    m_inflight_syncs.erase(sync_holder->m_local_image_id);
-
-    if (m_inflight_syncs.size() < m_max_concurrent_syncs
-        && !m_sync_queue.empty()) {
+    if (m_inflight_syncs.size() < m_max_concurrent_syncs &&
+        !m_sync_queue.empty()) {
       next_sync_holder = m_sync_queue.back();
       m_sync_queue.pop_back();
-      m_inflight_syncs.insert(std::make_pair(next_sync_holder->m_local_image_id,
-                                             next_sync_holder));
+
+      assert(
+        m_inflight_syncs.count(next_sync_holder->m_local_pool_image_id) == 0);
+      m_inflight_syncs[next_sync_holder->m_local_pool_image_id] =
+        next_sync_holder;
       dout(10) << "ready to start image sync for local_image_id "
-               << next_sync_holder->m_local_image_id
+               << next_sync_holder->m_local_pool_image_id.second
                << " [" << m_inflight_syncs.size() << "/"
                << m_max_concurrent_syncs << "]" << dendl;
     }
@@ -188,10 +194,14 @@ void ImageSyncThrottler<I>::set_max_concurrent_syncs(uint32_t max) {
         C_SyncHolder *next_sync_holder = m_sync_queue.back();
         next_sync_holders.push_back(next_sync_holder);
         m_sync_queue.pop_back();
-        m_inflight_syncs.insert(std::make_pair(next_sync_holder->m_local_image_id,
-                                               next_sync_holder));
+
+        assert(
+          m_inflight_syncs.count(next_sync_holder->m_local_pool_image_id) == 0);
+        m_inflight_syncs[next_sync_holder->m_local_pool_image_id] =
+          next_sync_holder;
+
         dout(10) << "ready to start image sync for local_image_id "
-                 << next_sync_holder->m_local_image_id
+                 << next_sync_holder->m_local_pool_image_id.second
                  << " [" << m_inflight_syncs.size() << "/"
                  << m_max_concurrent_syncs << "]" << dendl;
     }
index 6c7fbf338ed185df95f8c9568022a43b55be5ab1..6c3edf13115aa5002bbc22dd91a9c37d780db814 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <list>
 #include <map>
+#include <utility>
 #include "common/Mutex.h"
 #include "librbd/ImageCtx.h"
 #include "include/Context.h"
@@ -59,24 +60,27 @@ public:
                   ContextWQ *work_queue, Context *on_finish,
                   ProgressContext *progress_ctx = nullptr);
 
-  void cancel_sync(const std::string& mirror_uuid);
+  void cancel_sync(librados::IoCtx &local_io_ctx,
+                   const std::string local_image_id);
 
   void set_max_concurrent_syncs(uint32_t max);
 
   void print_status(Formatter *f, std::stringstream *ss);
 
 private:
+  typedef std::pair<int64_t, std::string> PoolImageId;
 
   struct C_SyncHolder : public Context {
     ImageSyncThrottler<ImageCtxT> *m_sync_throttler;
-    std::string m_local_image_id;
-    ImageSync<ImageCtxT> *m_sync;
+    PoolImageId m_local_pool_image_id;
+    ImageSync<ImageCtxT> *m_sync = nullptr;
     Context *m_on_finish;
 
     C_SyncHolder(ImageSyncThrottler<ImageCtxT> *sync_throttler,
-                 const std::string& local_image_id, Context *on_finish)
-      : m_sync_throttler(sync_throttler), m_local_image_id(local_image_id),
-        m_sync(nullptr), m_on_finish(on_finish) {}
+                 const PoolImageId &local_pool_image_id, Context *on_finish)
+      : m_sync_throttler(sync_throttler),
+        m_local_pool_image_id(local_pool_image_id), m_on_finish(on_finish) {
+    }
 
     virtual void finish(int r) {
       m_sync_throttler->handle_sync_finished(this);
@@ -93,7 +97,7 @@ private:
   uint32_t m_max_concurrent_syncs;
   Mutex m_lock;
   std::list<C_SyncHolder *> m_sync_queue;
-  std::map<std::string, C_SyncHolder *> m_inflight_syncs;
+  std::map<PoolImageId, C_SyncHolder *> m_inflight_syncs;
 
 };
 
index 7ba1d18d351e84f4107ead16f7df7a59c33159d4..d1e64eb6c1b5ccb19c55f5f141d94c7a27827dee 100644 (file)
@@ -82,7 +82,7 @@ void BootstrapRequest<I>::cancel() {
   Mutex::Locker locker(m_lock);
   m_canceled = true;
 
-  m_image_sync_throttler->cancel_sync(m_local_image_id);
+  m_image_sync_throttler->cancel_sync(m_local_io_ctx, m_local_image_id);
 }
 
 template <typename I>