]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-mirror: fix potential race between image sync and shut down 21817/head
authorJason Dillaman <dillaman@redhat.com>
Fri, 4 May 2018 13:24:43 +0000 (09:24 -0400)
committerJason Dillaman <dillaman@redhat.com>
Sun, 6 May 2018 03:44:34 +0000 (23:44 -0400)
Fixes: http://tracker.ceph.com/issues/24008
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/tools/rbd_mirror/ImageSync.cc
src/tools/rbd_mirror/InstanceWatcher.cc
src/tools/rbd_mirror/InstanceWatcher.h

index 3e09c12d5d2a2e9dd81fc67239baaa737b0d9b21..f7ececbafc4fedd4db4db329e0c07733385ba9e3 100644 (file)
@@ -27,6 +27,7 @@ namespace rbd {
 namespace mirror {
 
 using namespace image_sync;
+using librbd::util::create_async_context_callback;
 using librbd::util::create_context_callback;
 using librbd::util::unique_lock_name;
 
@@ -98,15 +99,30 @@ void ImageSync<I>::send_notify_sync_request() {
 
   dout(10) << dendl;
 
-  Context *ctx = create_context_callback<
-    ImageSync<I>, &ImageSync<I>::handle_notify_sync_request>(this);
+  m_lock.Lock();
+  if (m_canceled) {
+    m_lock.Unlock();
+    BaseRequest::finish(-ECANCELED);
+    return;
+  }
+
+  Context *ctx = create_async_context_callback(
+    m_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();
 }
 
 template <typename I>
 void ImageSync<I>::handle_notify_sync_request(int r) {
   dout(10) << ": r=" << r << dendl;
 
+  m_lock.Lock();
+  if (r == 0 && m_canceled) {
+    r = -ECANCELED;
+  }
+  m_lock.Unlock();
+
   if (r < 0) {
     BaseRequest::finish(r);
     return;
index 88faa67c07a7d9270123abf7291af978a9014860..e69890aaddf596c82d8779704ff2efd3ed1559b7 100644 (file)
@@ -536,9 +536,15 @@ void InstanceWatcher<I>::notify_sync_start(const std::string &instance_id,
 
 template <typename I>
 void InstanceWatcher<I>::notify_sync_complete(const std::string &sync_id) {
-  dout(10) << "sync_id=" << sync_id << dendl;
-
   Mutex::Locker locker(m_lock);
+  notify_sync_complete(m_lock, sync_id);
+}
+
+template <typename I>
+void InstanceWatcher<I>::notify_sync_complete(const Mutex&,
+                                              const std::string &sync_id) {
+  dout(10) << "sync_id=" << sync_id << dendl;
+  assert(m_lock.is_locked());
 
   auto it = m_inflight_sync_reqs.find(sync_id);
   assert(it != m_inflight_sync_reqs.end());
@@ -558,7 +564,6 @@ void InstanceWatcher<I>::handle_notify_sync_request(C_SyncRequest *sync_ctx,
   Context *on_start = nullptr;
   {
     Mutex::Locker locker(m_lock);
-
     assert(sync_ctx->req != nullptr);
     assert(sync_ctx->on_start != nullptr);
 
@@ -568,13 +573,13 @@ void InstanceWatcher<I>::handle_notify_sync_request(C_SyncRequest *sync_ctx,
 
     std::swap(sync_ctx->on_start, on_start);
     sync_ctx->req = nullptr;
+
+    if (r == -ECANCELED) {
+      notify_sync_complete(m_lock, sync_ctx->sync_id);
+    }
   }
 
   on_start->complete(r == -ECANCELED ? r : 0);
-
-  if (r == -ECANCELED) {
-    notify_sync_complete(sync_ctx->sync_id);
-  }
 }
 
 template <typename I>
index f9671585a2724559f67cdeb20ad120e2e42cc44e..5ec1aef0f3ccd491f0cc6e770c82f7e82affea60 100644 (file)
@@ -210,6 +210,7 @@ private:
   bool unsuspend_notify_request(C_NotifyInstanceRequest *req);
   void unsuspend_notify_requests();
 
+  void notify_sync_complete(const Mutex& lock, const std::string &sync_id);
   void handle_notify_sync_request(C_SyncRequest *sync_ctx, int r);
   void handle_notify_sync_complete(C_SyncRequest *sync_ctx, int r);