Skip to content

Commit

Permalink
librbd: potential duplicate snap removal can result in crash
Browse files Browse the repository at this point in the history
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
  • Loading branch information
Jason Dillaman committed Jun 7, 2016
1 parent c6060ad commit 276fed6
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/librbd/operation/SnapshotRemoveRequest.cc
Expand Up @@ -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;

Expand Down
31 changes: 31 additions & 0 deletions src/test/librbd/operation/test_mock_SnapshotRemoveRequest.cc
Expand Up @@ -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

0 comments on commit 276fed6

Please sign in to comment.