]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: potential duplicate snap removal can result in crash 9440/head
authorJason Dillaman <dillaman@redhat.com>
Tue, 7 Jun 2016 02:34:30 +0000 (22:34 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 7 Jun 2016 02:34:30 +0000 (22:34 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/operation/SnapshotRemoveRequest.cc
src/test/librbd/operation/test_mock_SnapshotRemoveRequest.cc

index 1bdba71e3ced5cbc5aa407febaf9cb98986778ee..8ad123b2a1063b8f8673d08186549df046ff13b0 100644 (file)
@@ -101,10 +101,17 @@ void SnapshotRemoveRequest<I>::send_remove_object_map() {
   assert(image_ctx.owner_lock.is_locked());
 
   {
+    CephContext *cct = image_ctx.cct;
     RWLock::WLocker snap_locker(image_ctx.snap_lock);
     RWLock::RLocker object_map_locker(image_ctx.object_map_lock);
+    if (image_ctx.snap_info.find(m_snap_id) == image_ctx.snap_info.end()) {
+      lderr(cct) << this << " " << __func__ << ": snapshot doesn't exist"
+                 << dendl;
+      this->async_complete(-ENOENT);
+      return;
+    }
+
     if (image_ctx.object_map != nullptr) {
-      CephContext *cct = image_ctx.cct;
       ldout(cct, 5) << this << " " << __func__ << dendl;
       m_state = STATE_REMOVE_OBJECT_MAP;
 
index 4dcf3c8b44f355b70fb906be8d121850b030fb84..67a0e6deccceb4ac2e13f5792f825fb782f8d44f 100644 (file)
@@ -356,5 +356,36 @@ TEST_F(TestMockOperationSnapshotRemoveRequest, RemoveSnapError) {
   ASSERT_EQ(-ENOENT, cond_ctx.wait());
 }
 
+TEST_F(TestMockOperationSnapshotRemoveRequest, MissingSnap) {
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  MockImageCtx mock_image_ctx(*ictx);
+
+  MockExclusiveLock mock_exclusive_lock;
+  if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
+    mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
+  }
+
+  MockObjectMap mock_object_map;
+  if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
+    mock_image_ctx.object_map = &mock_object_map;
+  }
+
+  expect_op_work_queue(mock_image_ctx);
+
+  ::testing::InSequence seq;
+  uint64_t snap_id = 456;
+
+  C_SaferCond cond_ctx;
+  MockSnapshotRemoveRequest *req = new MockSnapshotRemoveRequest(
+    mock_image_ctx, &cond_ctx, "snap1", snap_id);
+  {
+    RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
+    req->send();
+  }
+  ASSERT_EQ(-ENOENT, cond_ctx.wait());
+}
+
 } // namespace operation
 } // namespace librbd