Remove corruption error injection in FaultInjectionTestFS (#8616)

Summary:
```FaultInjectionTestFS``` injects various types of read errors in ```FileSystem``` APIs. One type of error is corruption errors, where data is intentionally corrupted or truncated. There is corresponding validation in db_stress to verify that an injected error results in a user visible Get/MultiGet error. However, for corruption errors, its hard to know when a corruption is supposed to be detected by the user request, due to prefetching and, in case of direct IO, padding. This results in false positives. So remove that functionality.

Block checksum validation for Get/MultiGet is confined to ```BlockFetcher```, so we don't lose a lot by disabling this since its a small surface area to test.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/8616

Reviewed By: zhichao-cao

Differential Revision: D30074422

Pulled By: anand1976

fbshipit-source-id: 6a61fac18f95514c15364b75013799ddf83294df
This commit is contained in:
anand76 2021-08-04 15:48:10 -07:00 committed by Facebook GitHub Bot
parent dbe3810c74
commit c268859aaa

View File

@ -730,10 +730,9 @@ void FaultInjectionTestFS::UntrackFile(const std::string& f) {
open_files_.erase(f); open_files_.erase(f);
} }
IOStatus FaultInjectionTestFS::InjectThreadSpecificReadError(ErrorOperation op, IOStatus FaultInjectionTestFS::InjectThreadSpecificReadError(
Slice* result, ErrorOperation /*op*/, Slice* /*result*/, bool /*direct_io*/,
bool direct_io, char* /*scratch*/) {
char* scratch) {
ErrorContext* ctx = ErrorContext* ctx =
static_cast<ErrorContext*>(thread_local_error_->Get()); static_cast<ErrorContext*>(thread_local_error_->Get());
if (ctx == nullptr || !ctx->enable_error_injection || !ctx->one_in) { if (ctx == nullptr || !ctx->enable_error_injection || !ctx->one_in) {
@ -746,63 +745,7 @@ IOStatus FaultInjectionTestFS::InjectThreadSpecificReadError(ErrorOperation op,
free(ctx->callstack); free(ctx->callstack);
} }
ctx->callstack = port::SaveStack(&ctx->frames); ctx->callstack = port::SaveStack(&ctx->frames);
switch (op) {
case kRead:
{
if (!direct_io) {
ctx->type =
static_cast<ErrorType>(ctx->rand.Uniform(ErrorType::kErrorTypeMax));
} else {
// In Direct IO mode, the actual read will read extra data due to
// alignment restrictions. So don't inject corruption or
// truncated reads as we don't know if it will actually cause a
// detectable error
ctx->type = ErrorType::kErrorTypeStatus;
}
switch (ctx->type) {
// Inject IO error
case ErrorType::kErrorTypeStatus:
return IOStatus::IOError(); return IOStatus::IOError();
// Inject random corruption
case ErrorType::kErrorTypeCorruption:
{
if (result->data() == scratch) {
uint64_t offset = ctx->rand.Uniform((uint32_t)result->size());
uint64_t len =
std::min<uint64_t>(result->size() - offset, 64UL);
assert(offset < result->size());
assert(offset + len <= result->size());
std::string str;
// The randomly generated string could be identical to the
// original one, so retry
do {
str = ctx->rand.RandomString(static_cast<int>(len));
} while (str == std::string(scratch + offset, len));
memcpy(scratch + offset, str.data(), len);
break;
} else {
FALLTHROUGH_INTENDED;
}
}
// Truncate the result
case ErrorType::kErrorTypeTruncated:
{
assert(result->size() > 0);
uint64_t offset = ctx->rand.Uniform((uint32_t)result->size());
assert(offset < result->size());
*result = Slice(result->data(), offset);
break;
}
default:
assert(false);
}
break;
}
case kOpen:
return IOStatus::IOError();
default:
assert(false);
}
} }
return IOStatus::OK(); return IOStatus::OK();
} }