]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: add lock to resovle race condition
authorshangdehao1 <dehao.shang@intel.com>
Wed, 12 Jun 2019 21:36:35 +0000 (05:36 +0800)
committerJason Dillaman <dillaman@redhat.com>
Mon, 24 Jun 2019 21:36:54 +0000 (17:36 -0400)
possible race condition w/ multiple concurrent attempts to
re-create the cache session

Signed-off-by: Dehao Shang <dehao.shang@intel.com>
src/librbd/cache/ParentCacheObjectDispatch.cc
src/librbd/cache/ParentCacheObjectDispatch.h

index cafbd5c2c730ec4865d74abe42b8e1896ecf0d7d..65e55927da20ef5f52a7912433045cbbf4cf2ed8 100644 (file)
@@ -28,7 +28,8 @@ namespace cache {
 template <typename I>
 ParentCacheObjectDispatch<I>::ParentCacheObjectDispatch(
     I* image_ctx) : m_image_ctx(image_ctx), m_cache_client(nullptr),
-    m_object_store(nullptr), m_initialized(false), m_re_connecting(false) {
+    m_object_store(nullptr), m_initialized(false), m_re_connecting(false),
+    m_lock("librbd::cache::ParentCacheObjectDispatch::m_lock") {
   std::string controller_path =
     ((CephContext*)(m_image_ctx->cct))->_conf.get_val<std::string>("immutable_object_cache_sock");
   m_cache_client = new CacheClient(controller_path.c_str(), m_image_ctx->cct);
@@ -79,17 +80,25 @@ bool ParentCacheObjectDispatch<I>::read(
   /* if RO daemon still don't startup, or RO daemon crash,
    * or session occur any error, try to re-connect daemon.*/
   if (!m_cache_client->is_session_work()) {
-    if(!m_re_connecting.load()) {
-      ldout(cct, 20) << "try to re-connct RO daemon. " << dendl;
+    {
+      Mutex::Locker locker(m_lock);
+      if (m_re_connecting.load()) {
+        ldout(cct, 5) << "Parent cache is re-connecting RO daemon, "
+                      << "dispatch current request to lower object layer " << dendl;
+        return false;
+      }
       m_re_connecting.store(true);
-
-      Context* on_finish = new FunctionContext([this](int ret) {
-        m_re_connecting.store(false);
-      });
-      create_cache_session(on_finish, true);
     }
 
-    ldout(cct, 5) << "session don't work, dispatch current request to lower object layer " << dendl;
+    ceph_assert(m_re_connecting.load());
+
+    Context* on_finish = new FunctionContext([this](int ret) {
+      m_re_connecting.store(false);
+    });
+    create_cache_session(on_finish, true);
+
+    ldout(cct, 5) << "Parent cache initiate re-connect to RO daemon. "
+                  << "dispatch current request to lower object layer" << dendl;
     return false;
   }
   ceph_assert(m_cache_client->is_session_work());
index d4efda77d431c07720db88260a0c3a7d72abd59e..b339d721e7f5ded8828ef553d7cfe42cad3e1a48 100644 (file)
@@ -146,6 +146,7 @@ private:
   SharedPersistentObjectCacher *m_object_store;
   bool m_initialized;
   std::atomic<bool> m_re_connecting;
+  Mutex m_lock;
 };
 
 } // namespace cache