]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: ignore snap unprotect -EBUSY errors during journal replay
authorJason Dillaman <dillaman@redhat.com>
Thu, 23 Jun 2016 12:45:59 +0000 (08:45 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 23 Jun 2016 12:50:38 +0000 (08:50 -0400)
Fixes: http://tracker.ceph.com/issues/16445
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/journal/Replay.cc
src/librbd/journal/Replay.h
src/test/librbd/journal/test_mock_Replay.cc

index 2de4de9c7f14014fb8b6332467a32345c38e7113..fbe8890a60b76d2554b6e9477b8f41fa345ba360 100644 (file)
@@ -345,6 +345,7 @@ void Replay<I>::handle_event(const journal::OpFinishEvent &event,
                  << "op_tid=" << event.op_tid << dendl;
 
   bool op_in_progress;
+  bool filter_ret_val;
   Context *on_op_complete = nullptr;
   Context *on_op_finish_event = nullptr;
   {
@@ -365,6 +366,10 @@ void Replay<I>::handle_event(const journal::OpFinishEvent &event,
     op_in_progress = op_event.op_in_progress;
     std::swap(on_op_complete, op_event.on_op_complete);
     std::swap(on_op_finish_event, op_event.on_op_finish_event);
+
+    // special errors which indicate op never started but was recorded
+    // as failed in the journal
+    filter_ret_val = (op_event.op_finish_error_codes.count(event.r) != 0);
   }
 
   if (event.r < 0) {
@@ -378,7 +383,7 @@ void Replay<I>::handle_event(const journal::OpFinishEvent &event,
       // creating the op event
       delete on_op_complete;
       delete on_op_finish_event;
-      handle_op_complete(event.op_tid, event.r);
+      handle_op_complete(event.op_tid, filter_ret_val ? 0 : event.r);
     }
     return;
   }
@@ -508,6 +513,9 @@ void Replay<I>::handle_event(const journal::SnapUnprotectEvent &event,
                                                                event,
                                                                on_op_complete));
 
+  // ignore errors recorded in the journal
+  op_event->op_finish_error_codes = {-EBUSY};
+
   // ignore errors caused due to replay
   op_event->ignore_error_codes = {-EINVAL};
 
index bbea390f784b337b7137da05573395c45b825dea..69a2c83c39cb607d5caa7602bf23c2481009a661 100644 (file)
@@ -52,6 +52,7 @@ private:
     Context *on_finish_ready = nullptr;
     Context *on_finish_safe = nullptr;
     Context *on_op_complete = nullptr;
+    ReturnValues op_finish_error_codes;
     ReturnValues ignore_error_codes;
   };
 
index 43f2909b2bb1ce47aa67994c9fed3aef0a53ac0d..8a9c86941d8b24f8776c13551f6e576a6f6ab1c2 100644 (file)
@@ -972,6 +972,34 @@ TEST_F(TestMockJournalReplay, SnapUnprotectEvent) {
   ASSERT_EQ(0, on_finish_safe.wait());
 }
 
+TEST_F(TestMockJournalReplay, SnapUnprotectOpFinishBusy) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockReplayImageCtx mock_image_ctx(*ictx);
+  MockJournalReplay mock_journal_replay(mock_image_ctx);
+  expect_op_work_queue(mock_image_ctx);
+
+  InSequence seq;
+  C_SaferCond on_start_ready;
+  C_SaferCond on_start_safe;
+  when_process(mock_journal_replay, EventEntry{SnapUnprotectEvent(123, "snap")},
+               &on_start_ready, &on_start_safe);
+  ASSERT_EQ(0, on_start_ready.wait());
+
+  // aborts the snap unprotect op if image had children
+  C_SaferCond on_finish_ready;
+  C_SaferCond on_finish_safe;
+  when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, -EBUSY)},
+               &on_finish_ready, &on_finish_safe);
+
+  ASSERT_EQ(0, on_start_safe.wait());
+  ASSERT_EQ(0, on_finish_safe.wait());
+  ASSERT_EQ(0, on_finish_ready.wait());
+}
+
 TEST_F(TestMockJournalReplay, SnapUnprotectEventInvalid) {
   REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);