Skip to content

Commit b938e60

Browse files
anand76facebook-github-bot
anand76
authored andcommitted
Fix a couple of bugs in FaultInjectionTestFS (facebook#6777)
Summary: Fix the following cases that can cause false alarms in db_stress when read fault injection is enabled - 1. Turn off corruption/truncation when direct IO is enabled. Since the actual IO size is larger than block size due to alignment requirements, the corruption may not result in a detectable error. 2. Handle the case when the randomly generated string to overwrite the original block is identical to the original. Tests: Run db_stress w/ and wo/ direct IO and fault injection turned on Pull Request resolved: facebook#6777 Reviewed By: zhichao-cao Differential Revision: D21316734 Pulled By: anand1976 fbshipit-source-id: bf0e6468043063ca81ff877d4bf71d3f296c77aa
1 parent 28fe8e4 commit b938e60

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

test_util/fault_injection_test_fs.cc

+20-6
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ IOStatus TestFSRandomAccessFile::Read(uint64_t offset, size_t n,
213213
IOStatus s = target_->Read(offset, n, options, result, scratch, dbg);
214214
if (s.ok()) {
215215
s = fs_->InjectError(FaultInjectionTestFS::ErrorOperation::kRead, result,
216-
scratch);
216+
use_direct_io(), scratch);
217217
}
218218
return s;
219219
}
@@ -311,7 +311,7 @@ IOStatus FaultInjectionTestFS::NewRandomAccessFile(
311311
if (!IsFilesystemActive()) {
312312
return GetError();
313313
}
314-
IOStatus io_s = InjectError(ErrorOperation::kOpen, nullptr, nullptr);
314+
IOStatus io_s = InjectError(ErrorOperation::kOpen, nullptr, false, nullptr);
315315
if (io_s.ok()) {
316316
io_s = target()->NewRandomAccessFile(fname, file_opts, result, dbg);
317317
}
@@ -457,6 +457,7 @@ void FaultInjectionTestFS::UntrackFile(const std::string& f) {
457457

458458
IOStatus FaultInjectionTestFS::InjectError(ErrorOperation op,
459459
Slice* result,
460+
bool direct_io,
460461
char* scratch) {
461462
ErrorContext* ctx =
462463
static_cast<ErrorContext*>(thread_local_error_->Get());
@@ -473,9 +474,17 @@ IOStatus FaultInjectionTestFS::InjectError(ErrorOperation op,
473474
switch (op) {
474475
case kRead:
475476
{
476-
ErrorType type =
477-
static_cast<ErrorType>(ctx->rand.Uniform(ErrorType::kErrorTypeMax));
478-
switch (type) {
477+
if (!direct_io) {
478+
ctx->type =
479+
static_cast<ErrorType>(ctx->rand.Uniform(ErrorType::kErrorTypeMax));
480+
} else {
481+
// In Direct IO mode, the actual read will read extra data due to
482+
// alignment restrictions. So don't inject corruption or
483+
// truncated reads as we don't know if it will actually cause a
484+
// detectable error
485+
ctx->type = ErrorType::kErrorTypeStatus;
486+
}
487+
switch (ctx->type) {
479488
// Inject IO error
480489
case ErrorType::kErrorTypeStatus:
481490
return IOStatus::IOError();
@@ -488,8 +497,13 @@ IOStatus FaultInjectionTestFS::InjectError(ErrorOperation op,
488497
std::min<uint64_t>(result->size() - offset, 64UL);
489498
assert(offset < result->size());
490499
assert(offset + len <= result->size());
491-
std::string str = DBTestBase::RandomString(&ctx->rand,
500+
std::string str;
501+
// The randomly generated string could be identical to the
502+
// original one, so retry
503+
do {
504+
str = DBTestBase::RandomString(&ctx->rand,
492505
static_cast<int>(len));
506+
} while (str == std::string(scratch + offset, len));
493507
memcpy(scratch + offset, str.data(), len);
494508
break;
495509
} else {

test_util/fault_injection_test_fs.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,8 @@ class FaultInjectionTestFS : public FileSystemWrapper {
309309
// corruption in the contents of scratch, or truncation of slice
310310
// are the types of error with equal probability. For OPEN,
311311
// its always an IOError.
312-
IOStatus InjectError(ErrorOperation op, Slice* slice, char* scratch);
312+
IOStatus InjectError(ErrorOperation op, Slice* slice,
313+
bool direct_io, char* scratch);
313314

314315
// Get the count of how many times we injected since the previous call
315316
int GetAndResetErrorCount() {

0 commit comments

Comments
 (0)