]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: fix rbd close race with rewatch 21141/head
authorSong Shun <song.shun3@zte.com.cn>
Tue, 10 Apr 2018 05:41:18 +0000 (13:41 +0800)
committerSong Shun <song.shun3@zte.com.cn>
Wed, 11 Apr 2018 01:39:01 +0000 (09:39 +0800)
  fix rbd close race with rewatch

Signed-off-by: Song Shun <song.shun3@zte.com.cn>
src/librbd/Watcher.cc
src/librbd/watcher/RewatchRequest.cc
src/test/librbd/watcher/test_mock_RewatchRequest.cc

index 37fdaaebed6d6ca8f6135ec2f900f4acbd666771..9c3ef192745e3926041e52bfb8cae8610f658f1f 100644 (file)
@@ -250,13 +250,22 @@ void Watcher::rewatch() {
 }
 
 void Watcher::handle_rewatch(int r) {
-  ldout(m_cct, 10) "r=" << r << dendl;
+  ldout(m_cct, 10) << "r=" << r << dendl;
 
   WatchState next_watch_state = WATCH_STATE_REGISTERED;
-  if (r < 0) {
-    // only EBLACKLISTED or ENOENT can be returned
-    assert(r == -EBLACKLISTED || r == -ENOENT);
+  if (r  == -EBLACKLISTED) {
+    lderr(m_cct) << "client blacklisted" << dendl;
+    next_watch_state = WATCH_STATE_UNREGISTERED;
+  } else if (r == -ENOENT) {
+    lderr(m_cct) << "failed to unwatch: " << cpp_strerror(r) << dendl;
     next_watch_state = WATCH_STATE_UNREGISTERED;
+  } else if (r < 0) {
+    next_watch_state = WATCH_STATE_ERROR;
+    if (m_unregister_watch_ctx != nullptr) {
+      ldout(m_cct, 10) << "image is closing, skip rewatch" << dendl;
+    } else {
+      rewatch();
+    }  
   }
 
   Context *unregister_watch_ctx = nullptr;
index fe236269793a95d1e9bc9b0978eac73a4e4d98e9..22d2bb8e567888312790f3ae6e4fb968cf8f7b08 100644 (file)
@@ -78,19 +78,10 @@ void RewatchRequest::rewatch() {
 void RewatchRequest::handle_rewatch(int r) {
   CephContext *cct = reinterpret_cast<CephContext *>(m_ioctx.cct());
   ldout(cct, 10) << "r=" << r << dendl;
-
-  if (r == -EBLACKLISTED) {
-    lderr(cct) << "client blacklisted" << dendl;
-    finish(r);
-    return;
-  } else if (r == -ENOENT) {
-    ldout(cct, 5) << "object deleted" << dendl;
-    finish(r);
-    return;
-  } else if (r < 0) {
+  if (r < 0) {
     lderr(cct) << "failed to watch object: " << cpp_strerror(r)
                << dendl;
-    rewatch();
+    finish(r);
     return;
   }
 
index 33945e24ed45a19dc22ea9d6ae1f77f50a26363e..cd4dd297765bdc4459d9430a096bfd183ac82180 100644 (file)
@@ -176,7 +176,6 @@ TEST_F(TestMockWatcherRewatchRequest, WatchError) {
   InSequence seq;
   expect_aio_unwatch(mock_image_ctx, 0);
   expect_aio_watch(mock_image_ctx, -EINVAL);
-  expect_aio_watch(mock_image_ctx, 0);
 
   C_SaferCond ctx;
   MockRewatchRequest *req = MockRewatchRequest::create(mock_image_ctx.md_ctx,
@@ -189,7 +188,7 @@ TEST_F(TestMockWatcherRewatchRequest, WatchError) {
     RWLock::WLocker watch_locker(m_watch_lock);
     req->send();
   }
-  ASSERT_EQ(0, ctx.wait());
+  ASSERT_EQ(-EINVAL, ctx.wait());
 }
 
 } // namespace watcher