From 680c41634882d5d54237a2be88b2171f0042a55c Mon Sep 17 00:00:00 2001 From: sdong Date: Mon, 4 May 2020 14:15:55 -0700 Subject: [PATCH] Avoid Swallowing Some File Consistency Checking Bugs (#6793) Summary: We are swallowing some file consistency checking failures. This is not expected. We are fixing two cases: DB reopen and manifest dump. More places are not fixed and need follow-up. Error from CheckConsistencyForDeletes() is also swallowed, which is not fixed in this PR. Pull Request resolved: https://github.com/facebook/rocksdb/pull/6793 Test Plan: Add a unit test to cover the reopen case. Reviewed By: riversand963 Differential Revision: D21366525 fbshipit-source-id: eb438a322237814e8d5125f916a3c6de97f39ded --- HISTORY.md | 1 + db/db_test2.cc | 18 ++++++++++++++++++ db/version_builder.cc | 5 ++++- db/version_set.cc | 8 ++++++-- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index c9ea5355b..17e13f3c8 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,6 +9,7 @@ * Fix a bug caused by not including user timestamp in MultiGet LookupKey construction. This can lead to wrong query result since the trailing bytes of a user key, if not shorter than timestamp, will be mistaken for user timestamp. * Fix a bug caused by using wrong compare function when sorting the input keys of MultiGet with timestamps. * Upgraded version of bzip library (1.0.6 -> 1.0.8) used with RocksJava to address potential vulnerabilities if an attacker can manipulate compressed data saved and loaded by RocksDB (not normal). See issue #6703. +* Fix consistency checking error swallowing in some cases when options.force_consistency_checks = true. ### Public API Change * Add a ConfigOptions argument to the APIs dealing with converting options to and from strings and files. The ConfigOptions is meant to replace some of the options (such as input_strings_escaped and ignore_unknown_options) and allow for more parameters to be passed in the future without changing the function signature. diff --git a/db/db_test2.cc b/db/db_test2.cc index 3444c4772..0296d7a7b 100644 --- a/db/db_test2.cc +++ b/db/db_test2.cc @@ -4328,6 +4328,24 @@ TEST_F(DBTest2, SameSmallestInSameLevel) { ASSERT_EQ("2,3,4,5,6,7,8", Get("key")); } +TEST_F(DBTest2, FileConsistencyCheckInOpen) { + Put("foo", "bar"); + Flush(); + + SyncPoint::GetInstance()->SetCallBack( + "VersionBuilder::CheckConsistencyBeforeReturn", [&](void* arg) { + Status* ret_s = static_cast(arg); + *ret_s = Status::Corruption("fcc"); + }); + SyncPoint::GetInstance()->EnableProcessing(); + + Options options = CurrentOptions(); + options.force_consistency_checks = true; + ASSERT_NOK(TryReopen(options)); + + SyncPoint::GetInstance()->DisableProcessing(); +} + TEST_F(DBTest2, BlockBasedTablePrefixIndexSeekForPrev) { // create a DB with block prefix index BlockBasedTableOptions table_options; diff --git a/db/version_builder.cc b/db/version_builder.cc index 38e407e38..30bd7af77 100644 --- a/db/version_builder.cc +++ b/db/version_builder.cc @@ -316,7 +316,10 @@ class VersionBuilder::Rep { } } - return Status::OK(); + Status ret_s; + TEST_SYNC_POINT_CALLBACK("VersionBuilder::CheckConsistencyBeforeReturn", + &ret_s); + return ret_s; } Status CheckConsistencyForDeletes(VersionEdit* /*edit*/, uint64_t number, diff --git a/db/version_set.cc b/db/version_set.cc index 4bfbbce91..0d1687500 100644 --- a/db/version_set.cc +++ b/db/version_set.cc @@ -4594,7 +4594,11 @@ Status VersionSet::Recover( Version* v = new Version(cfd, this, file_options_, *cfd->GetLatestMutableCFOptions(), current_version_number_++); - builder->SaveTo(v->storage_info()); + s = builder->SaveTo(v->storage_info()); + if (!s.ok()) { + delete v; + return s; + } // Install recovered version v->PrepareApply(*cfd->GetLatestMutableCFOptions(), @@ -5145,7 +5149,7 @@ Status VersionSet::DumpManifest(Options& options, std::string& dscname, Version* v = new Version(cfd, this, file_options_, *cfd->GetLatestMutableCFOptions(), current_version_number_++); - builder->SaveTo(v->storage_info()); + s = builder->SaveTo(v->storage_info()); v->PrepareApply(*cfd->GetLatestMutableCFOptions(), false); printf("--------------- Column family \"%s\" (ID %" PRIu32