Use Env::GetChildren() instead of readdir (#6139)

Summary:
For more portability, switch from readdir to Env::GetChildren() in ldb's
manifest_dump subcommand.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/6139

Test Plan:
```
$make check
```
Manually check ldb command.

Differential Revision: D18898197

Pulled By: riversand963

fbshipit-source-id: 92afca379e9fbe78ab70b2eb40d127daad8df5e2
This commit is contained in:
Yanqin Jin 2019-12-10 11:47:20 -08:00 committed by Facebook Github Bot
parent 14c38baca0
commit 2b060c1498

View file

@ -1016,8 +1016,8 @@ void DumpManifestFile(Options options, std::string file, bool verbose, bool hex,
/*block_cache_tracer=*/nullptr);
Status s = versions.DumpManifest(options, file, verbose, hex, json);
if (!s.ok()) {
printf("Error in processing file %s %s\n", file.c_str(),
s.ToString().c_str());
fprintf(stderr, "Error in processing file %s %s\n", file.c_str(),
s.ToString().c_str());
}
}
@ -1066,45 +1066,72 @@ void ManifestDumpCommand::DoCommand() {
if (!path_.empty()) {
manifestfile = path_;
} else {
bool found = false;
// We need to find the manifest file by searching the directory
// containing the db for files of the form MANIFEST_[0-9]+
auto CloseDir = [](DIR* p) { closedir(p); };
std::unique_ptr<DIR, decltype(CloseDir)> d(opendir(db_path_.c_str()),
CloseDir);
if (d == nullptr) {
exec_state_ =
LDBCommandExecuteResult::Failed(db_path_ + " is not a directory");
std::vector<std::string> files;
Status s = options_.env->GetChildren(db_path_, &files);
if (!s.ok()) {
std::string err_msg = s.ToString();
err_msg.append(": Failed to list the content of ");
err_msg.append(db_path_);
exec_state_ = LDBCommandExecuteResult::Failed(err_msg);
return;
}
struct dirent* entry;
while ((entry = readdir(d.get())) != nullptr) {
unsigned int match;
uint64_t num;
if (sscanf(entry->d_name, "MANIFEST-%" PRIu64 "%n", &num, &match) &&
match == strlen(entry->d_name)) {
if (!found) {
manifestfile = db_path_ + "/" + std::string(entry->d_name);
found = true;
} else {
const std::string kManifestNamePrefix = "MANIFEST-";
std::string matched_file;
#ifdef OS_WIN
const char kPathDelim = '\\';
#else
const char kPathDelim = '/';
#endif
for (const auto& file_path : files) {
// Some Env::GetChildren() return absolute paths. Some directories' path
// end with path delim, e.g. '/' or '\\'.
size_t pos = file_path.find_last_of(kPathDelim);
if (pos == file_path.size() - 1) {
continue;
}
std::string fname;
if (pos != std::string::npos) {
// Absolute path.
fname.assign(file_path, pos + 1, file_path.size() - pos - 1);
} else {
fname = file_path;
}
uint64_t file_num = 0;
FileType file_type = kLogFile; // Just for initialization
if (ParseFileName(fname, &file_num, &file_type) &&
file_type == kDescriptorFile) {
if (!matched_file.empty()) {
exec_state_ = LDBCommandExecuteResult::Failed(
"Multiple MANIFEST files found; use --path to select one");
return;
} else {
matched_file.swap(fname);
}
}
}
if (matched_file.empty()) {
std::string err_msg("No MANIFEST found in ");
err_msg.append(db_path_);
exec_state_ = LDBCommandExecuteResult::Failed(err_msg);
return;
}
if (db_path_[db_path_.length() - 1] != '/') {
db_path_.append("/");
}
manifestfile = db_path_ + matched_file;
}
if (verbose_) {
printf("Processing Manifest file %s\n", manifestfile.c_str());
fprintf(stdout, "Processing Manifest file %s\n", manifestfile.c_str());
}
DumpManifestFile(options_, manifestfile, verbose_, is_key_hex_, json_);
if (verbose_) {
printf("Processing Manifest file %s done\n", manifestfile.c_str());
fprintf(stdout, "Processing Manifest file %s done\n", manifestfile.c_str());
}
}
@ -1126,19 +1153,19 @@ void ListColumnFamiliesCommand::DoCommand() {
std::vector<std::string> column_families;
Status s = DB::ListColumnFamilies(options_, db_path_, &column_families);
if (!s.ok()) {
printf("Error in processing db %s %s\n", db_path_.c_str(),
s.ToString().c_str());
fprintf(stderr, "Error in processing db %s %s\n", db_path_.c_str(),
s.ToString().c_str());
} else {
printf("Column families in %s: \n{", db_path_.c_str());
fprintf(stdout, "Column families in %s: \n{", db_path_.c_str());
bool first = true;
for (auto cf : column_families) {
if (!first) {
printf(", ");
fprintf(stdout, ", ");
}
first = false;
printf("%s", cf.c_str());
fprintf(stdout, "%s", cf.c_str());
}
printf("}\n");
fprintf(stdout, "}\n");
}
}
@ -2761,7 +2788,7 @@ void CheckPointCommand::DoCommand() {
Status status = Checkpoint::Create(db_, &checkpoint);
status = checkpoint->CreateCheckpoint(checkpoint_dir_);
if (status.ok()) {
printf("OK\n");
fprintf(stdout, "OK\n");
} else {
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString());
}
@ -2785,7 +2812,7 @@ void RepairCommand::DoCommand() {
options.info_log.reset(new StderrLogger(InfoLogLevel::WARN_LEVEL));
Status status = RepairDB(db_path_, options);
if (status.ok()) {
printf("OK\n");
fprintf(stdout, "OK\n");
} else {
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString());
}
@ -2865,7 +2892,7 @@ void BackupCommand::DoCommand() {
assert(GetExecuteState().IsFailed());
return;
}
printf("open db OK\n");
fprintf(stdout, "open db OK\n");
Env* custom_env = nullptr;
Env::LoadEnv(backup_env_uri_, &custom_env, &backup_env_guard_);
assert(custom_env != nullptr);
@ -2876,14 +2903,14 @@ void BackupCommand::DoCommand() {
backup_options.max_background_operations = num_threads_;
status = BackupEngine::Open(custom_env, backup_options, &backup_engine);
if (status.ok()) {
printf("open backup engine OK\n");
fprintf(stdout, "open backup engine OK\n");
} else {
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString());
return;
}
status = backup_engine->CreateNewBackup(db_);
if (status.ok()) {
printf("create new backup OK\n");
fprintf(stdout, "create new backup OK\n");
} else {
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString());
return;
@ -2921,11 +2948,11 @@ void RestoreCommand::DoCommand() {
}
}
if (status.ok()) {
printf("open restore engine OK\n");
fprintf(stdout, "open restore engine OK\n");
status = restore_engine->RestoreDBFromLatestBackup(db_path_, db_path_);
}
if (status.ok()) {
printf("restore from backup OK\n");
fprintf(stdout, "restore from backup OK\n");
} else {
exec_state_ = LDBCommandExecuteResult::Failed(status.ToString());
}