Make FileSystem a Customizable Class (#8649)
Summary: Pull Request resolved: https://github.com/facebook/rocksdb/pull/8649 Reviewed By: zhichao-cao Differential Revision: D32036059 Pulled By: mrambacher fbshipit-source-id: 4f1e7557ecac52eb849b83ae02b8d7d232112295
This commit is contained in:
parent
cfc57f55b5
commit
f72c834eab
@ -15,6 +15,9 @@
|
|||||||
### Public Interface Change
|
### Public Interface Change
|
||||||
* When options.ttl is used with leveled compaction with compactinon priority kMinOverlappingRatio, files exceeding half of TTL value will be prioritized more, so that by the time TTL is reached, fewer extra compactions will be scheduled to clear them up. At the same time, when compacting files with data older than half of TTL, output files may be cut off based on those files' boundaries, in order for the early TTL compaction to work properly.
|
* When options.ttl is used with leveled compaction with compactinon priority kMinOverlappingRatio, files exceeding half of TTL value will be prioritized more, so that by the time TTL is reached, fewer extra compactions will be scheduled to clear them up. At the same time, when compacting files with data older than half of TTL, output files may be cut off based on those files' boundaries, in order for the early TTL compaction to work properly.
|
||||||
|
|
||||||
|
### Public API change
|
||||||
|
* Made FileSystem extend the Customizable class and added a CreateFromString method. Implementations need to be registered with the ObjectRegistry and to implement a Name() method in order to be created via this method.
|
||||||
|
|
||||||
## 6.26.0 (2021-10-20)
|
## 6.26.0 (2021-10-20)
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
* Fixes a bug in directed IO mode when calling MultiGet() for blobs in the same blob file. The bug is caused by not sorting the blob read requests by file offsets.
|
* Fixes a bug in directed IO mode when calling MultiGet() for blobs in the same blob file. The bug is caused by not sorting the blob read requests by file offsets.
|
||||||
|
@ -3296,6 +3296,9 @@ class DeadlineFS : public FileSystemWrapper {
|
|||||||
ignore_deadline_(false),
|
ignore_deadline_(false),
|
||||||
error_on_delay_(error_on_delay) {}
|
error_on_delay_(error_on_delay) {}
|
||||||
|
|
||||||
|
static const char* kClassName() { return "DeadlineFileSystem"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
|
||||||
IOStatus NewRandomAccessFile(const std::string& fname,
|
IOStatus NewRandomAccessFile(const std::string& fname,
|
||||||
const FileOptions& opts,
|
const FileOptions& opts,
|
||||||
std::unique_ptr<FSRandomAccessFile>* result,
|
std::unique_ptr<FSRandomAccessFile>* result,
|
||||||
|
3
env/env.cc
vendored
3
env/env.cc
vendored
@ -324,7 +324,8 @@ class LegacyFileSystemWrapper : public FileSystem {
|
|||||||
explicit LegacyFileSystemWrapper(Env* t) : target_(t) {}
|
explicit LegacyFileSystemWrapper(Env* t) : target_(t) {}
|
||||||
~LegacyFileSystemWrapper() override {}
|
~LegacyFileSystemWrapper() override {}
|
||||||
|
|
||||||
const char* Name() const override { return "Legacy File System"; }
|
static const char* kClassName() { return "LegacyFileSystem"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
|
||||||
// Return the target to which this Env forwards all calls
|
// Return the target to which this Env forwards all calls
|
||||||
Env* target() const { return target_; }
|
Env* target() const { return target_; }
|
||||||
|
127
env/env_chroot.cc
vendored
127
env/env_chroot.cc
vendored
@ -13,20 +13,35 @@
|
|||||||
|
|
||||||
#include "env/composite_env_wrapper.h"
|
#include "env/composite_env_wrapper.h"
|
||||||
#include "env/fs_remap.h"
|
#include "env/fs_remap.h"
|
||||||
|
#include "rocksdb/utilities/options_type.h"
|
||||||
#include "util/string_util.h" // errnoStr
|
#include "util/string_util.h" // errnoStr
|
||||||
|
|
||||||
namespace ROCKSDB_NAMESPACE {
|
namespace ROCKSDB_NAMESPACE {
|
||||||
namespace {
|
namespace {
|
||||||
class ChrootFileSystem : public RemapFileSystem {
|
static std::unordered_map<std::string, OptionTypeInfo> chroot_fs_type_info = {
|
||||||
public:
|
{"chroot_dir", {0, OptionType::kString}}};
|
||||||
ChrootFileSystem(const std::shared_ptr<FileSystem>& base,
|
} // namespace
|
||||||
const std::string& chroot_dir)
|
ChrootFileSystem::ChrootFileSystem(const std::shared_ptr<FileSystem>& base,
|
||||||
: RemapFileSystem(base) {
|
const std::string& chroot_dir)
|
||||||
|
: RemapFileSystem(base), chroot_dir_(chroot_dir) {
|
||||||
|
RegisterOptions("chroot_dir", &chroot_dir_, &chroot_fs_type_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status ChrootFileSystem::PrepareOptions(const ConfigOptions& options) {
|
||||||
|
Status s = FileSystemWrapper::PrepareOptions(options);
|
||||||
|
if (!s.ok()) {
|
||||||
|
return s;
|
||||||
|
} else if (chroot_dir_.empty()) {
|
||||||
|
s = Status::InvalidArgument("ChRootFileSystem requires a chroot dir");
|
||||||
|
} else {
|
||||||
|
s = target_->FileExists(chroot_dir_, IOOptions(), nullptr);
|
||||||
|
}
|
||||||
|
if (s.ok()) {
|
||||||
#if defined(OS_AIX)
|
#if defined(OS_AIX)
|
||||||
char resolvedName[PATH_MAX];
|
char resolvedName[PATH_MAX];
|
||||||
char* real_chroot_dir = realpath(chroot_dir.c_str(), resolvedName);
|
char* real_chroot_dir = realpath(chroot_dir_.c_str(), resolvedName);
|
||||||
#else
|
#else
|
||||||
char* real_chroot_dir = realpath(chroot_dir.c_str(), nullptr);
|
char* real_chroot_dir = realpath(chroot_dir_.c_str(), nullptr);
|
||||||
#endif
|
#endif
|
||||||
// chroot_dir must exist so realpath() returns non-nullptr.
|
// chroot_dir must exist so realpath() returns non-nullptr.
|
||||||
assert(real_chroot_dir != nullptr);
|
assert(real_chroot_dir != nullptr);
|
||||||
@ -35,32 +50,32 @@ class ChrootFileSystem : public RemapFileSystem {
|
|||||||
free(real_chroot_dir);
|
free(real_chroot_dir);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
const char* Name() const override { return "ChrootFS"; }
|
IOStatus ChrootFileSystem::GetTestDirectory(const IOOptions& options,
|
||||||
|
std::string* path,
|
||||||
|
IODebugContext* dbg) {
|
||||||
|
// Adapted from PosixEnv's implementation since it doesn't provide a way to
|
||||||
|
// create directory in the chroot.
|
||||||
|
char buf[256];
|
||||||
|
snprintf(buf, sizeof(buf), "/rocksdbtest-%d", static_cast<int>(geteuid()));
|
||||||
|
*path = buf;
|
||||||
|
|
||||||
IOStatus GetTestDirectory(const IOOptions& options, std::string* path,
|
// Directory may already exist, so ignore return
|
||||||
IODebugContext* dbg) override {
|
return CreateDirIfMissing(*path, options, dbg);
|
||||||
// Adapted from PosixEnv's implementation since it doesn't provide a way to
|
}
|
||||||
// create directory in the chroot.
|
|
||||||
char buf[256];
|
|
||||||
snprintf(buf, sizeof(buf), "/rocksdbtest-%d", static_cast<int>(geteuid()));
|
|
||||||
*path = buf;
|
|
||||||
|
|
||||||
// Directory may already exist, so ignore return
|
|
||||||
return CreateDirIfMissing(*path, options, dbg);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Returns status and expanded absolute path including the chroot directory.
|
// Returns status and expanded absolute path including the chroot directory.
|
||||||
// Checks whether the provided path breaks out of the chroot. If it returns
|
// Checks whether the provided path breaks out of the chroot. If it returns
|
||||||
// non-OK status, the returned path should not be used.
|
// non-OK status, the returned path should not be used.
|
||||||
std::pair<IOStatus, std::string> EncodePath(
|
std::pair<IOStatus, std::string> ChrootFileSystem::EncodePath(
|
||||||
const std::string& path) override {
|
const std::string& path) {
|
||||||
if (path.empty() || path[0] != '/') {
|
if (path.empty() || path[0] != '/') {
|
||||||
return {IOStatus::InvalidArgument(path, "Not an absolute path"), ""};
|
return {IOStatus::InvalidArgument(path, "Not an absolute path"), ""};
|
||||||
}
|
}
|
||||||
std::pair<IOStatus, std::string> res;
|
std::pair<IOStatus, std::string> res;
|
||||||
res.second = chroot_dir_ + path;
|
res.second = chroot_dir_ + path;
|
||||||
#if defined(OS_AIX)
|
#if defined(OS_AIX)
|
||||||
char resolvedName[PATH_MAX];
|
char resolvedName[PATH_MAX];
|
||||||
char* normalized_path = realpath(res.second.c_str(), resolvedName);
|
char* normalized_path = realpath(res.second.c_str(), resolvedName);
|
||||||
@ -81,47 +96,51 @@ class ChrootFileSystem : public RemapFileSystem {
|
|||||||
free(normalized_path);
|
free(normalized_path);
|
||||||
#endif
|
#endif
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similar to EncodePath() except assumes the basename in the path hasn't been
|
// Similar to EncodePath() except assumes the basename in the path hasn't been
|
||||||
// created yet.
|
// created yet.
|
||||||
std::pair<IOStatus, std::string> EncodePathWithNewBasename(
|
std::pair<IOStatus, std::string> ChrootFileSystem::EncodePathWithNewBasename(
|
||||||
const std::string& path) override {
|
const std::string& path) {
|
||||||
if (path.empty() || path[0] != '/') {
|
if (path.empty() || path[0] != '/') {
|
||||||
return {IOStatus::InvalidArgument(path, "Not an absolute path"), ""};
|
return {IOStatus::InvalidArgument(path, "Not an absolute path"), ""};
|
||||||
}
|
}
|
||||||
// Basename may be followed by trailing slashes
|
// Basename may be followed by trailing slashes
|
||||||
size_t final_idx = path.find_last_not_of('/');
|
size_t final_idx = path.find_last_not_of('/');
|
||||||
if (final_idx == std::string::npos) {
|
if (final_idx == std::string::npos) {
|
||||||
// It's only slashes so no basename to extract
|
// It's only slashes so no basename to extract
|
||||||
return EncodePath(path);
|
return EncodePath(path);
|
||||||
}
|
|
||||||
|
|
||||||
// Pull off the basename temporarily since realname(3) (used by
|
|
||||||
// EncodePath()) requires a path that exists
|
|
||||||
size_t base_sep = path.rfind('/', final_idx);
|
|
||||||
auto status_and_enc_path = EncodePath(path.substr(0, base_sep + 1));
|
|
||||||
status_and_enc_path.second.append(path.substr(base_sep + 1));
|
|
||||||
return status_and_enc_path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
// Pull off the basename temporarily since realname(3) (used by
|
||||||
std::string chroot_dir_;
|
// EncodePath()) requires a path that exists
|
||||||
};
|
size_t base_sep = path.rfind('/', final_idx);
|
||||||
} // namespace
|
auto status_and_enc_path = EncodePath(path.substr(0, base_sep + 1));
|
||||||
|
status_and_enc_path.second.append(path.substr(base_sep + 1));
|
||||||
|
return status_and_enc_path;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<FileSystem> NewChrootFileSystem(
|
std::shared_ptr<FileSystem> NewChrootFileSystem(
|
||||||
const std::shared_ptr<FileSystem>& base, const std::string& chroot_dir) {
|
const std::shared_ptr<FileSystem>& base, const std::string& chroot_dir) {
|
||||||
return std::make_shared<ChrootFileSystem>(base, chroot_dir);
|
auto chroot_fs = std::make_shared<ChrootFileSystem>(base, chroot_dir);
|
||||||
|
Status s = chroot_fs->PrepareOptions(ConfigOptions());
|
||||||
|
if (s.ok()) {
|
||||||
|
return chroot_fs;
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Env* NewChrootEnv(Env* base_env, const std::string& chroot_dir) {
|
Env* NewChrootEnv(Env* base_env, const std::string& chroot_dir) {
|
||||||
if (!base_env->FileExists(chroot_dir).ok()) {
|
if (!base_env->FileExists(chroot_dir).ok()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
std::shared_ptr<FileSystem> chroot_fs =
|
auto chroot_fs = NewChrootFileSystem(base_env->GetFileSystem(), chroot_dir);
|
||||||
NewChrootFileSystem(base_env->GetFileSystem(), chroot_dir);
|
if (chroot_fs != nullptr) {
|
||||||
return new CompositeEnvWrapper(base_env, chroot_fs);
|
return new CompositeEnvWrapper(base_env, chroot_fs);
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ROCKSDB_NAMESPACE
|
} // namespace ROCKSDB_NAMESPACE
|
||||||
|
32
env/env_chroot.h
vendored
32
env/env_chroot.h
vendored
@ -9,9 +9,37 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "rocksdb/env.h"
|
#include "env/fs_remap.h"
|
||||||
|
#include "rocksdb/file_system.h"
|
||||||
|
|
||||||
namespace ROCKSDB_NAMESPACE {
|
namespace ROCKSDB_NAMESPACE {
|
||||||
|
class ChrootFileSystem : public RemapFileSystem {
|
||||||
|
public:
|
||||||
|
ChrootFileSystem(const std::shared_ptr<FileSystem>& base,
|
||||||
|
const std::string& chroot_dir);
|
||||||
|
|
||||||
|
static const char* kClassName() { return "ChrootFS"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
|
||||||
|
IOStatus GetTestDirectory(const IOOptions& options, std::string* path,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
Status PrepareOptions(const ConfigOptions& options) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Returns status and expanded absolute path including the chroot directory.
|
||||||
|
// Checks whether the provided path breaks out of the chroot. If it returns
|
||||||
|
// non-OK status, the returned path should not be used.
|
||||||
|
std::pair<IOStatus, std::string> EncodePath(const std::string& path) override;
|
||||||
|
|
||||||
|
// Similar to EncodePath() except assumes the basename in the path hasn't been
|
||||||
|
// created yet.
|
||||||
|
std::pair<IOStatus, std::string> EncodePathWithNewBasename(
|
||||||
|
const std::string& path) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string chroot_dir_;
|
||||||
|
};
|
||||||
|
|
||||||
// Returns an Env that translates paths such that the root directory appears to
|
// Returns an Env that translates paths such that the root directory appears to
|
||||||
// be chroot_dir. chroot_dir should refer to an existing directory.
|
// be chroot_dir. chroot_dir should refer to an existing directory.
|
||||||
@ -19,6 +47,8 @@ namespace ROCKSDB_NAMESPACE {
|
|||||||
// This class has not been fully analyzed for providing strong security
|
// This class has not been fully analyzed for providing strong security
|
||||||
// guarantees.
|
// guarantees.
|
||||||
Env* NewChrootEnv(Env* base_env, const std::string& chroot_dir);
|
Env* NewChrootEnv(Env* base_env, const std::string& chroot_dir);
|
||||||
|
std::shared_ptr<FileSystem> NewChrootFileSystem(
|
||||||
|
const std::shared_ptr<FileSystem>& base, const std::string& chroot_dir);
|
||||||
|
|
||||||
} // namespace ROCKSDB_NAMESPACE
|
} // namespace ROCKSDB_NAMESPACE
|
||||||
|
|
||||||
|
32
env/env_encryption.cc
vendored
32
env/env_encryption.cc
vendored
@ -438,11 +438,20 @@ IOStatus EncryptedRandomRWFile::Close(const IOOptions& options,
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
static std::unordered_map<std::string, OptionTypeInfo> encrypted_fs_type_info =
|
||||||
|
{
|
||||||
|
{"provider",
|
||||||
|
OptionTypeInfo::AsCustomSharedPtr<EncryptionProvider>(
|
||||||
|
0 /* No offset, whole struct*/, OptionVerificationType::kByName,
|
||||||
|
OptionTypeFlags::kNone)},
|
||||||
|
};
|
||||||
// EncryptedFileSystemImpl implements an FileSystemWrapper that adds encryption
|
// EncryptedFileSystemImpl implements an FileSystemWrapper that adds encryption
|
||||||
// to files stored on disk.
|
// to files stored on disk.
|
||||||
class EncryptedFileSystemImpl : public EncryptedFileSystem {
|
class EncryptedFileSystemImpl : public EncryptedFileSystem {
|
||||||
public:
|
public:
|
||||||
const char* Name() const override { return "EncryptedFS"; }
|
const char* Name() const override {
|
||||||
|
return EncryptedFileSystem::kClassName();
|
||||||
|
}
|
||||||
// Returns the raw encryption provider that should be used to write the input
|
// Returns the raw encryption provider that should be used to write the input
|
||||||
// encrypted file. If there is no such provider, NotFound is returned.
|
// encrypted file. If there is no such provider, NotFound is returned.
|
||||||
IOStatus GetWritableProvider(const std::string& /*fname*/,
|
IOStatus GetWritableProvider(const std::string& /*fname*/,
|
||||||
@ -664,6 +673,7 @@ class EncryptedFileSystemImpl : public EncryptedFileSystem {
|
|||||||
const std::shared_ptr<EncryptionProvider>& provider)
|
const std::shared_ptr<EncryptionProvider>& provider)
|
||||||
: EncryptedFileSystem(base) {
|
: EncryptedFileSystem(base) {
|
||||||
provider_ = provider;
|
provider_ = provider;
|
||||||
|
RegisterOptions("EncryptionProvider", &provider_, &encrypted_fs_type_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status AddCipher(const std::string& descriptor, const char* cipher,
|
Status AddCipher(const std::string& descriptor, const char* cipher,
|
||||||
@ -910,10 +920,28 @@ class EncryptedFileSystemImpl : public EncryptedFileSystem {
|
|||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
Status NewEncryptedFileSystemImpl(
|
||||||
|
const std::shared_ptr<FileSystem>& base,
|
||||||
|
const std::shared_ptr<EncryptionProvider>& provider,
|
||||||
|
std::unique_ptr<FileSystem>* result) {
|
||||||
|
result->reset(new EncryptedFileSystemImpl(base, provider));
|
||||||
|
return Status::OK();
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<FileSystem> NewEncryptedFS(
|
std::shared_ptr<FileSystem> NewEncryptedFS(
|
||||||
const std::shared_ptr<FileSystem>& base,
|
const std::shared_ptr<FileSystem>& base,
|
||||||
const std::shared_ptr<EncryptionProvider>& provider) {
|
const std::shared_ptr<EncryptionProvider>& provider) {
|
||||||
return std::make_shared<EncryptedFileSystemImpl>(base, provider);
|
std::unique_ptr<FileSystem> efs;
|
||||||
|
Status s = NewEncryptedFileSystemImpl(base, provider, &efs);
|
||||||
|
if (s.ok()) {
|
||||||
|
s = efs->PrepareOptions(ConfigOptions());
|
||||||
|
}
|
||||||
|
if (s.ok()) {
|
||||||
|
std::shared_ptr<FileSystem> result(efs.release());
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Returns an Env that encrypts data when stored on disk and decrypts data when
|
// Returns an Env that encrypts data when stored on disk and decrypts data when
|
||||||
// read from disk.
|
// read from disk.
|
||||||
|
6
env/env_encryption_ctr.h
vendored
6
env/env_encryption_ctr.h
vendored
@ -105,6 +105,12 @@ class CTREncryptionProvider : public EncryptionProvider {
|
|||||||
uint64_t initialCounter, const Slice& iv, const Slice& prefix,
|
uint64_t initialCounter, const Slice& iv, const Slice& prefix,
|
||||||
std::unique_ptr<BlockAccessCipherStream>* result);
|
std::unique_ptr<BlockAccessCipherStream>* result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Status NewEncryptedFileSystemImpl(
|
||||||
|
const std::shared_ptr<FileSystem>& base_fs,
|
||||||
|
const std::shared_ptr<EncryptionProvider>& provider,
|
||||||
|
std::unique_ptr<FileSystem>* fs);
|
||||||
|
|
||||||
} // namespace ROCKSDB_NAMESPACE
|
} // namespace ROCKSDB_NAMESPACE
|
||||||
|
|
||||||
#endif // !defined(ROCKSDB_LITE)
|
#endif // !defined(ROCKSDB_LITE)
|
||||||
|
171
env/env_test.cc
vendored
171
env/env_test.cc
vendored
@ -39,6 +39,7 @@
|
|||||||
#include "env/emulated_clock.h"
|
#include "env/emulated_clock.h"
|
||||||
#include "env/env_chroot.h"
|
#include "env/env_chroot.h"
|
||||||
#include "env/env_encryption_ctr.h"
|
#include "env/env_encryption_ctr.h"
|
||||||
|
#include "env/fs_readonly.h"
|
||||||
#include "env/unique_id_gen.h"
|
#include "env/unique_id_gen.h"
|
||||||
#include "logging/log_buffer.h"
|
#include "logging/log_buffer.h"
|
||||||
#include "logging/logging.h"
|
#include "logging/logging.h"
|
||||||
@ -59,6 +60,7 @@
|
|||||||
#include "util/mutexlock.h"
|
#include "util/mutexlock.h"
|
||||||
#include "util/random.h"
|
#include "util/random.h"
|
||||||
#include "util/string_util.h"
|
#include "util/string_util.h"
|
||||||
|
#include "utilities/env_timed.h"
|
||||||
#include "utilities/fault_injection_env.h"
|
#include "utilities/fault_injection_env.h"
|
||||||
#include "utilities/fault_injection_fs.h"
|
#include "utilities/fault_injection_fs.h"
|
||||||
|
|
||||||
@ -2233,14 +2235,17 @@ INSTANTIATE_TEST_CASE_P(DefaultEnvWithDirectIO, EnvPosixTestWithParam,
|
|||||||
#endif // !defined(ROCKSDB_LITE)
|
#endif // !defined(ROCKSDB_LITE)
|
||||||
|
|
||||||
#if !defined(ROCKSDB_LITE) && !defined(OS_WIN)
|
#if !defined(ROCKSDB_LITE) && !defined(OS_WIN)
|
||||||
static std::unique_ptr<Env> chroot_env(
|
static Env* GetChrootEnv() {
|
||||||
NewChrootEnv(Env::Default(), test::TmpDir(Env::Default())));
|
static std::unique_ptr<Env> chroot_env(
|
||||||
INSTANTIATE_TEST_CASE_P(
|
NewChrootEnv(Env::Default(), test::TmpDir(Env::Default())));
|
||||||
ChrootEnvWithoutDirectIO, EnvPosixTestWithParam,
|
return chroot_env.get();
|
||||||
::testing::Values(std::pair<Env*, bool>(chroot_env.get(), false)));
|
}
|
||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(ChrootEnvWithoutDirectIO, EnvPosixTestWithParam,
|
||||||
ChrootEnvWithDirectIO, EnvPosixTestWithParam,
|
::testing::Values(std::pair<Env*, bool>(GetChrootEnv(),
|
||||||
::testing::Values(std::pair<Env*, bool>(chroot_env.get(), true)));
|
false)));
|
||||||
|
INSTANTIATE_TEST_CASE_P(ChrootEnvWithDirectIO, EnvPosixTestWithParam,
|
||||||
|
::testing::Values(std::pair<Env*, bool>(GetChrootEnv(),
|
||||||
|
true)));
|
||||||
#endif // !defined(ROCKSDB_LITE) && !defined(OS_WIN)
|
#endif // !defined(ROCKSDB_LITE) && !defined(OS_WIN)
|
||||||
|
|
||||||
class EnvFSTestWithParam
|
class EnvFSTestWithParam
|
||||||
@ -2492,7 +2497,6 @@ TEST_F(CreateEnvTest, CreateMockSystemClock) {
|
|||||||
guard->reset(new MockSystemClock(nullptr));
|
guard->reset(new MockSystemClock(nullptr));
|
||||||
return guard->get();
|
return guard->get();
|
||||||
});
|
});
|
||||||
|
|
||||||
ASSERT_OK(SystemClock::CreateFromString(
|
ASSERT_OK(SystemClock::CreateFromString(
|
||||||
config_options_, EmulatedSystemClock::kClassName(), &mock));
|
config_options_, EmulatedSystemClock::kClassName(), &mock));
|
||||||
ASSERT_NE(mock, nullptr);
|
ASSERT_NE(mock, nullptr);
|
||||||
@ -2518,6 +2522,154 @@ TEST_F(CreateEnvTest, CreateMockSystemClock) {
|
|||||||
ASSERT_OK(SystemClock::CreateFromString(
|
ASSERT_OK(SystemClock::CreateFromString(
|
||||||
config_options_, EmulatedSystemClock::kClassName(), &mock));
|
config_options_, EmulatedSystemClock::kClassName(), &mock));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CreateEnvTest, CreateReadOnlyFileSystem) {
|
||||||
|
std::shared_ptr<FileSystem> fs, copy;
|
||||||
|
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(
|
||||||
|
config_options_, ReadOnlyFileSystem::kClassName(), &fs));
|
||||||
|
ASSERT_NE(fs, nullptr);
|
||||||
|
ASSERT_STREQ(fs->Name(), ReadOnlyFileSystem::kClassName());
|
||||||
|
ASSERT_EQ(fs->Inner(), FileSystem::Default().get());
|
||||||
|
|
||||||
|
std::string opts_str = fs->ToString(config_options_);
|
||||||
|
std::string mismatch;
|
||||||
|
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_, opts_str, ©));
|
||||||
|
ASSERT_TRUE(fs->AreEquivalent(config_options_, copy.get(), &mismatch));
|
||||||
|
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(
|
||||||
|
config_options_,
|
||||||
|
std::string("id=") + ReadOnlyFileSystem::kClassName() +
|
||||||
|
"; target=" + TimedFileSystem::kClassName(),
|
||||||
|
&fs));
|
||||||
|
ASSERT_NE(fs, nullptr);
|
||||||
|
opts_str = fs->ToString(config_options_);
|
||||||
|
ASSERT_STREQ(fs->Name(), ReadOnlyFileSystem::kClassName());
|
||||||
|
ASSERT_NE(fs->Inner(), nullptr);
|
||||||
|
ASSERT_STREQ(fs->Inner()->Name(), TimedFileSystem::kClassName());
|
||||||
|
ASSERT_EQ(fs->Inner()->Inner(), FileSystem::Default().get());
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_, opts_str, ©));
|
||||||
|
ASSERT_TRUE(fs->AreEquivalent(config_options_, copy.get(), &mismatch));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CreateEnvTest, CreateTimedFileSystem) {
|
||||||
|
std::shared_ptr<FileSystem> fs, copy;
|
||||||
|
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_,
|
||||||
|
TimedFileSystem::kClassName(), &fs));
|
||||||
|
ASSERT_NE(fs, nullptr);
|
||||||
|
ASSERT_STREQ(fs->Name(), TimedFileSystem::kClassName());
|
||||||
|
ASSERT_EQ(fs->Inner(), FileSystem::Default().get());
|
||||||
|
|
||||||
|
std::string opts_str = fs->ToString(config_options_);
|
||||||
|
std::string mismatch;
|
||||||
|
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_, opts_str, ©));
|
||||||
|
ASSERT_TRUE(fs->AreEquivalent(config_options_, copy.get(), &mismatch));
|
||||||
|
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(
|
||||||
|
config_options_,
|
||||||
|
std::string("id=") + TimedFileSystem::kClassName() +
|
||||||
|
"; target=" + ReadOnlyFileSystem::kClassName(),
|
||||||
|
&fs));
|
||||||
|
ASSERT_NE(fs, nullptr);
|
||||||
|
opts_str = fs->ToString(config_options_);
|
||||||
|
ASSERT_STREQ(fs->Name(), TimedFileSystem::kClassName());
|
||||||
|
ASSERT_NE(fs->Inner(), nullptr);
|
||||||
|
ASSERT_STREQ(fs->Inner()->Name(), ReadOnlyFileSystem::kClassName());
|
||||||
|
ASSERT_EQ(fs->Inner()->Inner(), FileSystem::Default().get());
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_, opts_str, ©));
|
||||||
|
ASSERT_TRUE(fs->AreEquivalent(config_options_, copy.get(), &mismatch));
|
||||||
|
}
|
||||||
|
#ifndef OS_WIN
|
||||||
|
TEST_F(CreateEnvTest, CreateChrootFileSystem) {
|
||||||
|
std::shared_ptr<FileSystem> fs, copy;
|
||||||
|
auto tmp_dir = test::TmpDir(Env::Default());
|
||||||
|
// The Chroot FileSystem has a required "chroot_dir" option.
|
||||||
|
ASSERT_NOK(FileSystem::CreateFromString(config_options_,
|
||||||
|
ChrootFileSystem::kClassName(), &fs));
|
||||||
|
|
||||||
|
// ChrootFileSystem fails with an invalid directory
|
||||||
|
ASSERT_NOK(FileSystem::CreateFromString(
|
||||||
|
config_options_,
|
||||||
|
std::string("chroot_dir=/No/Such/Directory; id=") +
|
||||||
|
ChrootFileSystem::kClassName(),
|
||||||
|
&fs));
|
||||||
|
std::string chroot_opts = std::string("chroot_dir=") + tmp_dir +
|
||||||
|
std::string("; id=") +
|
||||||
|
ChrootFileSystem::kClassName();
|
||||||
|
|
||||||
|
// Create a valid ChrootFileSystem with an inner Default
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_, chroot_opts, &fs));
|
||||||
|
ASSERT_NE(fs, nullptr);
|
||||||
|
ASSERT_STREQ(fs->Name(), ChrootFileSystem::kClassName());
|
||||||
|
ASSERT_EQ(fs->Inner(), FileSystem::Default().get());
|
||||||
|
std::string opts_str = fs->ToString(config_options_);
|
||||||
|
std::string mismatch;
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_, opts_str, ©));
|
||||||
|
ASSERT_TRUE(fs->AreEquivalent(config_options_, copy.get(), &mismatch));
|
||||||
|
|
||||||
|
// Create a valid ChrootFileSystem with an inner TimedFileSystem
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(
|
||||||
|
config_options_,
|
||||||
|
chroot_opts + "; target=" + TimedFileSystem::kClassName(), &fs));
|
||||||
|
ASSERT_NE(fs, nullptr);
|
||||||
|
ASSERT_STREQ(fs->Name(), ChrootFileSystem::kClassName());
|
||||||
|
ASSERT_NE(fs->Inner(), nullptr);
|
||||||
|
ASSERT_STREQ(fs->Inner()->Name(), TimedFileSystem::kClassName());
|
||||||
|
ASSERT_EQ(fs->Inner()->Inner(), FileSystem::Default().get());
|
||||||
|
opts_str = fs->ToString(config_options_);
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_, opts_str, ©));
|
||||||
|
ASSERT_TRUE(fs->AreEquivalent(config_options_, copy.get(), &mismatch));
|
||||||
|
|
||||||
|
// Create a TimedFileSystem with an inner ChrootFileSystem
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(
|
||||||
|
config_options_,
|
||||||
|
"target={" + chroot_opts + "}; id=" + TimedFileSystem::kClassName(),
|
||||||
|
&fs));
|
||||||
|
ASSERT_NE(fs, nullptr);
|
||||||
|
ASSERT_STREQ(fs->Name(), TimedFileSystem::kClassName());
|
||||||
|
ASSERT_NE(fs->Inner(), nullptr);
|
||||||
|
ASSERT_STREQ(fs->Inner()->Name(), ChrootFileSystem::kClassName());
|
||||||
|
ASSERT_EQ(fs->Inner()->Inner(), FileSystem::Default().get());
|
||||||
|
opts_str = fs->ToString(config_options_);
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_, opts_str, ©));
|
||||||
|
ASSERT_TRUE(fs->AreEquivalent(config_options_, copy.get(), &mismatch));
|
||||||
|
}
|
||||||
|
#endif // OS_WIN
|
||||||
|
|
||||||
|
TEST_F(CreateEnvTest, CreateEncryptedFileSystem) {
|
||||||
|
std::shared_ptr<FileSystem> fs, copy;
|
||||||
|
|
||||||
|
std::string base_opts =
|
||||||
|
std::string("provider=1://test; id=") + EncryptedFileSystem::kClassName();
|
||||||
|
// The EncryptedFileSystem requires a "provider" option.
|
||||||
|
ASSERT_NOK(FileSystem::CreateFromString(
|
||||||
|
config_options_, EncryptedFileSystem::kClassName(), &fs));
|
||||||
|
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_, base_opts, &fs));
|
||||||
|
|
||||||
|
ASSERT_NE(fs, nullptr);
|
||||||
|
ASSERT_STREQ(fs->Name(), EncryptedFileSystem::kClassName());
|
||||||
|
ASSERT_EQ(fs->Inner(), FileSystem::Default().get());
|
||||||
|
std::string opts_str = fs->ToString(config_options_);
|
||||||
|
std::string mismatch;
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_, opts_str, ©));
|
||||||
|
ASSERT_TRUE(fs->AreEquivalent(config_options_, copy.get(), &mismatch));
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(
|
||||||
|
config_options_, base_opts + "; target=" + TimedFileSystem::kClassName(),
|
||||||
|
&fs));
|
||||||
|
ASSERT_NE(fs, nullptr);
|
||||||
|
ASSERT_STREQ(fs->Name(), EncryptedFileSystem::kClassName());
|
||||||
|
ASSERT_NE(fs->Inner(), nullptr);
|
||||||
|
ASSERT_STREQ(fs->Inner()->Name(), TimedFileSystem::kClassName());
|
||||||
|
ASSERT_EQ(fs->Inner()->Inner(), FileSystem::Default().get());
|
||||||
|
opts_str = fs->ToString(config_options_);
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_, opts_str, ©));
|
||||||
|
ASSERT_TRUE(fs->AreEquivalent(config_options_, copy.get(), &mismatch));
|
||||||
|
}
|
||||||
|
|
||||||
#endif // ROCKSDB_LITE
|
#endif // ROCKSDB_LITE
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -2742,7 +2894,6 @@ TEST_F(EnvTest, FailureToCreateLockFile) {
|
|||||||
// Clean up
|
// Clean up
|
||||||
ASSERT_OK(DestroyDir(env, dir));
|
ASSERT_OK(DestroyDir(env, dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ROCKSDB_NAMESPACE
|
} // namespace ROCKSDB_NAMESPACE
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
112
env/file_system.cc
vendored
112
env/file_system.cc
vendored
@ -6,9 +6,17 @@
|
|||||||
#include "rocksdb/file_system.h"
|
#include "rocksdb/file_system.h"
|
||||||
|
|
||||||
#include "env/composite_env_wrapper.h"
|
#include "env/composite_env_wrapper.h"
|
||||||
|
#include "env/env_chroot.h"
|
||||||
|
#include "env/env_encryption_ctr.h"
|
||||||
|
#include "env/fs_readonly.h"
|
||||||
|
#include "env/mock_env.h"
|
||||||
#include "options/db_options.h"
|
#include "options/db_options.h"
|
||||||
#include "rocksdb/convenience.h"
|
#include "rocksdb/convenience.h"
|
||||||
|
#include "rocksdb/utilities/customizable_util.h"
|
||||||
#include "rocksdb/utilities/object_registry.h"
|
#include "rocksdb/utilities/object_registry.h"
|
||||||
|
#include "rocksdb/utilities/options_type.h"
|
||||||
|
#include "util/string_util.h"
|
||||||
|
#include "utilities/env_timed.h"
|
||||||
|
|
||||||
namespace ROCKSDB_NAMESPACE {
|
namespace ROCKSDB_NAMESPACE {
|
||||||
|
|
||||||
@ -21,19 +29,63 @@ Status FileSystem::Load(const std::string& value,
|
|||||||
return CreateFromString(ConfigOptions(), value, result);
|
return CreateFromString(ConfigOptions(), value, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ROCKSDB_LITE
|
||||||
|
static int RegisterBuiltinFileSystems(ObjectLibrary& library,
|
||||||
|
const std::string& /*arg*/) {
|
||||||
|
library.Register<FileSystem>(
|
||||||
|
TimedFileSystem::kClassName(),
|
||||||
|
[](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
|
||||||
|
std::string* /* errmsg */) {
|
||||||
|
guard->reset(new TimedFileSystem(nullptr));
|
||||||
|
return guard->get();
|
||||||
|
});
|
||||||
|
library.Register<FileSystem>(
|
||||||
|
ReadOnlyFileSystem::kClassName(),
|
||||||
|
[](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
|
||||||
|
std::string* /* errmsg */) {
|
||||||
|
guard->reset(new ReadOnlyFileSystem(nullptr));
|
||||||
|
return guard->get();
|
||||||
|
});
|
||||||
|
library.Register<FileSystem>(
|
||||||
|
EncryptedFileSystem::kClassName(),
|
||||||
|
[](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
|
||||||
|
std::string* errmsg) {
|
||||||
|
Status s = NewEncryptedFileSystemImpl(nullptr, nullptr, guard);
|
||||||
|
if (!s.ok()) {
|
||||||
|
*errmsg = s.ToString();
|
||||||
|
}
|
||||||
|
return guard->get();
|
||||||
|
});
|
||||||
|
#ifndef OS_WIN
|
||||||
|
library.Register<FileSystem>(
|
||||||
|
ChrootFileSystem::kClassName(),
|
||||||
|
[](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
|
||||||
|
std::string* /* errmsg */) {
|
||||||
|
guard->reset(new ChrootFileSystem(nullptr, ""));
|
||||||
|
return guard->get();
|
||||||
|
});
|
||||||
|
#endif // OS_WIN
|
||||||
|
size_t num_types;
|
||||||
|
return static_cast<int>(library.GetFactoryCount(&num_types));
|
||||||
|
}
|
||||||
|
#endif // ROCKSDB_LITE
|
||||||
|
|
||||||
Status FileSystem::CreateFromString(const ConfigOptions& config_options,
|
Status FileSystem::CreateFromString(const ConfigOptions& config_options,
|
||||||
const std::string& value,
|
const std::string& value,
|
||||||
std::shared_ptr<FileSystem>* result) {
|
std::shared_ptr<FileSystem>* result) {
|
||||||
Status s;
|
auto default_fs = FileSystem::Default();
|
||||||
|
if (default_fs->IsInstanceOf(value)) {
|
||||||
|
*result = default_fs;
|
||||||
|
return Status::OK();
|
||||||
|
} else {
|
||||||
#ifndef ROCKSDB_LITE
|
#ifndef ROCKSDB_LITE
|
||||||
(void)config_options;
|
static std::once_flag once;
|
||||||
s = ObjectRegistry::NewInstance()->NewSharedObject<FileSystem>(value, result);
|
std::call_once(once, [&]() {
|
||||||
#else
|
RegisterBuiltinFileSystems(*(ObjectLibrary::Default().get()), "");
|
||||||
(void)config_options;
|
});
|
||||||
(void)result;
|
#endif // ROCKSDB_LITE
|
||||||
s = Status::NotSupported("Cannot load FileSystem in LITE mode", value);
|
return LoadSharedObject<FileSystem>(config_options, value, nullptr, result);
|
||||||
#endif
|
}
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IOStatus FileSystem::ReuseWritableFile(const std::string& fname,
|
IOStatus FileSystem::ReuseWritableFile(const std::string& fname,
|
||||||
@ -147,4 +199,46 @@ IOStatus ReadFileToString(FileSystem* fs, const std::string& fname,
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
static std::unordered_map<std::string, OptionTypeInfo> fs_wrapper_type_info = {
|
||||||
|
#ifndef ROCKSDB_LITE
|
||||||
|
{"target",
|
||||||
|
OptionTypeInfo::AsCustomSharedPtr<FileSystem>(
|
||||||
|
0, OptionVerificationType::kByName, OptionTypeFlags::kDontSerialize)},
|
||||||
|
#endif // ROCKSDB_LITE
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
FileSystemWrapper::FileSystemWrapper(const std::shared_ptr<FileSystem>& t)
|
||||||
|
: target_(t) {
|
||||||
|
RegisterOptions("", &target_, &fs_wrapper_type_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status FileSystemWrapper::PrepareOptions(const ConfigOptions& options) {
|
||||||
|
if (target_ == nullptr) {
|
||||||
|
target_ = FileSystem::Default();
|
||||||
|
}
|
||||||
|
return FileSystem::PrepareOptions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef ROCKSDB_LITE
|
||||||
|
std::string FileSystemWrapper::SerializeOptions(
|
||||||
|
const ConfigOptions& config_options, const std::string& header) const {
|
||||||
|
auto parent = FileSystem::SerializeOptions(config_options, "");
|
||||||
|
if (config_options.IsShallow() || target_ == nullptr ||
|
||||||
|
target_->IsInstanceOf(FileSystem::kDefaultName())) {
|
||||||
|
return parent;
|
||||||
|
} else {
|
||||||
|
std::string result = header;
|
||||||
|
if (!StartsWith(parent, OptionTypeInfo::kIdPropName())) {
|
||||||
|
result.append(OptionTypeInfo::kIdPropName()).append("=");
|
||||||
|
}
|
||||||
|
result.append(parent);
|
||||||
|
if (!EndsWith(result, config_options.delimiter)) {
|
||||||
|
result.append(config_options.delimiter);
|
||||||
|
}
|
||||||
|
result.append("target=").append(target_->ToString(config_options));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // ROCKSDB_LITE
|
||||||
} // namespace ROCKSDB_NAMESPACE
|
} // namespace ROCKSDB_NAMESPACE
|
||||||
|
3
env/file_system_tracer.h
vendored
3
env/file_system_tracer.h
vendored
@ -27,6 +27,9 @@ class FileSystemTracingWrapper : public FileSystemWrapper {
|
|||||||
|
|
||||||
~FileSystemTracingWrapper() override {}
|
~FileSystemTracingWrapper() override {}
|
||||||
|
|
||||||
|
static const char* kClassName() { return "FileSystemTracing"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
|
||||||
IOStatus NewSequentialFile(const std::string& fname,
|
IOStatus NewSequentialFile(const std::string& fname,
|
||||||
const FileOptions& file_opts,
|
const FileOptions& file_opts,
|
||||||
std::unique_ptr<FSSequentialFile>* result,
|
std::unique_ptr<FSSequentialFile>* result,
|
||||||
|
18
env/fs_posix.cc
vendored
18
env/fs_posix.cc
vendored
@ -141,7 +141,9 @@ class PosixFileSystem : public FileSystem {
|
|||||||
public:
|
public:
|
||||||
PosixFileSystem();
|
PosixFileSystem();
|
||||||
|
|
||||||
const char* Name() const override { return "Posix File System"; }
|
static const char* kClassName() { return "PosixFileSystem"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
const char* NickName() const override { return kDefaultName(); }
|
||||||
|
|
||||||
~PosixFileSystem() override {}
|
~PosixFileSystem() override {}
|
||||||
|
|
||||||
@ -618,7 +620,8 @@ class PosixFileSystem : public FileSystem {
|
|||||||
return IOStatus::NotFound();
|
return IOStatus::NotFound();
|
||||||
default:
|
default:
|
||||||
assert(err == EIO || err == ENOMEM);
|
assert(err == EIO || err == ENOMEM);
|
||||||
return IOStatus::IOError("Unexpected error(" + ToString(err) +
|
return IOStatus::IOError("Unexpected error(" +
|
||||||
|
ROCKSDB_NAMESPACE::ToString(err) +
|
||||||
") accessing file `" + fname + "' ");
|
") accessing file `" + fname + "' ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -819,11 +822,12 @@ class PosixFileSystem : public FileSystem {
|
|||||||
errno = ENOLCK;
|
errno = ENOLCK;
|
||||||
// Note that the thread ID printed is the same one as the one in
|
// Note that the thread ID printed is the same one as the one in
|
||||||
// posix logger, but posix logger prints it hex format.
|
// posix logger, but posix logger prints it hex format.
|
||||||
return IOError("lock hold by current process, acquire time " +
|
return IOError(
|
||||||
ToString(prev_info.acquire_time) +
|
"lock hold by current process, acquire time " +
|
||||||
" acquiring thread " +
|
ROCKSDB_NAMESPACE::ToString(prev_info.acquire_time) +
|
||||||
ToString(prev_info.acquiring_thread),
|
" acquiring thread " +
|
||||||
fname, errno);
|
ROCKSDB_NAMESPACE::ToString(prev_info.acquiring_thread),
|
||||||
|
fname, errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
IOStatus result = IOStatus::OK();
|
IOStatus result = IOStatus::OK();
|
||||||
|
3
env/fs_readonly.h
vendored
3
env/fs_readonly.h
vendored
@ -26,6 +26,9 @@ class ReadOnlyFileSystem : public FileSystemWrapper {
|
|||||||
explicit ReadOnlyFileSystem(const std::shared_ptr<FileSystem>& base)
|
explicit ReadOnlyFileSystem(const std::shared_ptr<FileSystem>& base)
|
||||||
: FileSystemWrapper(base) {}
|
: FileSystemWrapper(base) {}
|
||||||
|
|
||||||
|
static const char* kClassName() { return "ReadOnlyFileSystem"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
|
||||||
IOStatus NewWritableFile(const std::string& /*fname*/,
|
IOStatus NewWritableFile(const std::string& /*fname*/,
|
||||||
const FileOptions& /*options*/,
|
const FileOptions& /*options*/,
|
||||||
std::unique_ptr<FSWritableFile>* /*result*/,
|
std::unique_ptr<FSWritableFile>* /*result*/,
|
||||||
|
8
env/fs_remap.h
vendored
8
env/fs_remap.h
vendored
@ -39,6 +39,14 @@ class RemapFileSystem : public FileSystemWrapper {
|
|||||||
public:
|
public:
|
||||||
// Left abstract:
|
// Left abstract:
|
||||||
// const char* Name() const override { ... }
|
// const char* Name() const override { ... }
|
||||||
|
static const char* kClassName() { return "RemapFileSystem"; }
|
||||||
|
bool IsInstanceOf(const std::string& id) const override {
|
||||||
|
if (id == kClassName()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return FileSystemWrapper::IsInstanceOf(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Status RegisterDbPaths(const std::vector<std::string>& paths) override;
|
Status RegisterDbPaths(const std::vector<std::string>& paths) override;
|
||||||
|
|
||||||
|
147
env/mock_env.cc
vendored
147
env/mock_env.cc
vendored
@ -565,132 +565,39 @@ class TestMemLogger : public Logger {
|
|||||||
}
|
}
|
||||||
size_t GetLogFileSize() const override { return log_size_; }
|
size_t GetLogFileSize() const override { return log_size_; }
|
||||||
};
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
class MockFileSystem : public FileSystem {
|
MockFileSystem::MockFileSystem(const std::shared_ptr<SystemClock>& clock,
|
||||||
public:
|
bool supports_direct_io)
|
||||||
explicit MockFileSystem(const std::shared_ptr<SystemClock>& clock,
|
: system_clock_(clock), supports_direct_io_(supports_direct_io) {
|
||||||
bool supports_direct_io = true)
|
clock_ = system_clock_.get();
|
||||||
: system_clock_(clock), supports_direct_io_(supports_direct_io) {
|
}
|
||||||
clock_ = system_clock_.get();
|
|
||||||
|
MockFileSystem::~MockFileSystem() {
|
||||||
|
for (auto i = file_map_.begin(); i != file_map_.end(); ++i) {
|
||||||
|
i->second->Unref();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
~MockFileSystem() override {
|
IOStatus MockFileSystem::GetAbsolutePath(const std::string& db_path,
|
||||||
for (auto i = file_map_.begin(); i != file_map_.end(); ++i) {
|
const IOOptions& /*options*/,
|
||||||
i->second->Unref();
|
std::string* output_path,
|
||||||
}
|
IODebugContext* /*dbg*/) {
|
||||||
|
*output_path = NormalizeMockPath(db_path);
|
||||||
|
if (output_path->at(0) != '/') {
|
||||||
|
return IOStatus::NotSupported("GetAbsolutePath");
|
||||||
|
} else {
|
||||||
|
return IOStatus::OK();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char* Name() const override { return "Memory"; }
|
std::string MockFileSystem::NormalizeMockPath(const std::string& path) {
|
||||||
IOStatus NewSequentialFile(const std::string& f, const FileOptions& file_opts,
|
std::string p = NormalizePath(path);
|
||||||
std::unique_ptr<FSSequentialFile>* r,
|
if (p.back() == kFilePathSeparator && p.size() > 1) {
|
||||||
IODebugContext* dbg) override;
|
p.pop_back();
|
||||||
IOStatus NewRandomAccessFile(const std::string& f,
|
|
||||||
const FileOptions& file_opts,
|
|
||||||
std::unique_ptr<FSRandomAccessFile>* r,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
|
|
||||||
IOStatus NewRandomRWFile(const std::string& fname,
|
|
||||||
const FileOptions& file_opts,
|
|
||||||
std::unique_ptr<FSRandomRWFile>* result,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
IOStatus ReuseWritableFile(const std::string& fname,
|
|
||||||
const std::string& old_fname,
|
|
||||||
const FileOptions& file_opts,
|
|
||||||
std::unique_ptr<FSWritableFile>* result,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
IOStatus NewWritableFile(const std::string& fname,
|
|
||||||
const FileOptions& file_opts,
|
|
||||||
std::unique_ptr<FSWritableFile>* result,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
IOStatus ReopenWritableFile(const std::string& fname,
|
|
||||||
const FileOptions& options,
|
|
||||||
std::unique_ptr<FSWritableFile>* result,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
IOStatus NewDirectory(const std::string& /*name*/, const IOOptions& io_opts,
|
|
||||||
std::unique_ptr<FSDirectory>* result,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
IOStatus FileExists(const std::string& fname, const IOOptions& /*io_opts*/,
|
|
||||||
IODebugContext* /*dbg*/) override;
|
|
||||||
IOStatus GetChildren(const std::string& dir, const IOOptions& options,
|
|
||||||
std::vector<std::string>* result,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
IOStatus DeleteFile(const std::string& fname, const IOOptions& options,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
IOStatus Truncate(const std::string& fname, size_t size,
|
|
||||||
const IOOptions& options, IODebugContext* dbg) override;
|
|
||||||
IOStatus CreateDir(const std::string& dirname, const IOOptions& options,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
IOStatus CreateDirIfMissing(const std::string& dirname,
|
|
||||||
const IOOptions& options,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
IOStatus DeleteDir(const std::string& dirname, const IOOptions& options,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
|
|
||||||
IOStatus GetFileSize(const std::string& fname, const IOOptions& options,
|
|
||||||
uint64_t* file_size, IODebugContext* dbg) override;
|
|
||||||
|
|
||||||
IOStatus GetFileModificationTime(const std::string& fname,
|
|
||||||
const IOOptions& options,
|
|
||||||
uint64_t* file_mtime,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
IOStatus RenameFile(const std::string& src, const std::string& target,
|
|
||||||
const IOOptions& options, IODebugContext* dbg) override;
|
|
||||||
IOStatus LinkFile(const std::string& /*src*/, const std::string& /*target*/,
|
|
||||||
const IOOptions& /*options*/,
|
|
||||||
IODebugContext* /*dbg*/) override;
|
|
||||||
IOStatus LockFile(const std::string& fname, const IOOptions& options,
|
|
||||||
FileLock** lock, IODebugContext* dbg) override;
|
|
||||||
IOStatus UnlockFile(FileLock* lock, const IOOptions& options,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
IOStatus GetTestDirectory(const IOOptions& options, std::string* path,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
IOStatus NewLogger(const std::string& fname, const IOOptions& io_opts,
|
|
||||||
std::shared_ptr<Logger>* result,
|
|
||||||
IODebugContext* dbg) override;
|
|
||||||
// Get full directory name for this db.
|
|
||||||
IOStatus GetAbsolutePath(const std::string& db_path,
|
|
||||||
const IOOptions& /*options*/,
|
|
||||||
std::string* output_path,
|
|
||||||
IODebugContext* /*dbg*/) override {
|
|
||||||
*output_path = NormalizeMockPath(db_path);
|
|
||||||
if (output_path->at(0) != '/') {
|
|
||||||
return IOStatus::NotSupported("GetAbsolutePath");
|
|
||||||
} else {
|
|
||||||
return IOStatus::OK();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IOStatus IsDirectory(const std::string& /*path*/,
|
|
||||||
const IOOptions& /*options*/, bool* /*is_dir*/,
|
|
||||||
IODebugContext* /*dgb*/) override {
|
|
||||||
return IOStatus::NotSupported("IsDirectory");
|
|
||||||
}
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
Status CorruptBuffer(const std::string& fname);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool RenameFileInternal(const std::string& src, const std::string& dest);
|
|
||||||
void DeleteFileInternal(const std::string& fname);
|
|
||||||
bool GetChildrenInternal(const std::string& fname,
|
|
||||||
std::vector<std::string>* results);
|
|
||||||
|
|
||||||
std::string NormalizeMockPath(const std::string& path) {
|
|
||||||
std::string p = NormalizePath(path);
|
|
||||||
if (p.back() == kFilePathSeparator && p.size() > 1) {
|
|
||||||
p.pop_back();
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Map from filenames to MemFile objects, representing a simple file system.
|
|
||||||
port::Mutex mutex_;
|
|
||||||
std::map<std::string, MemFile*> file_map_; // Protected by mutex_.
|
|
||||||
std::shared_ptr<SystemClock> system_clock_;
|
|
||||||
SystemClock* clock_;
|
|
||||||
bool supports_direct_io_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // Anonymous namespace
|
|
||||||
// Partial implementation of the FileSystem interface.
|
// Partial implementation of the FileSystem interface.
|
||||||
IOStatus MockFileSystem::NewSequentialFile(
|
IOStatus MockFileSystem::NewSequentialFile(
|
||||||
const std::string& fname, const FileOptions& file_opts,
|
const std::string& fname, const FileOptions& file_opts,
|
||||||
|
106
env/mock_env.h
vendored
106
env/mock_env.h
vendored
@ -14,11 +14,117 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "env/composite_env_wrapper.h"
|
#include "env/composite_env_wrapper.h"
|
||||||
|
#include "port/port.h"
|
||||||
#include "rocksdb/env.h"
|
#include "rocksdb/env.h"
|
||||||
#include "rocksdb/status.h"
|
#include "rocksdb/status.h"
|
||||||
#include "rocksdb/system_clock.h"
|
#include "rocksdb/system_clock.h"
|
||||||
|
|
||||||
namespace ROCKSDB_NAMESPACE {
|
namespace ROCKSDB_NAMESPACE {
|
||||||
|
class MemFile;
|
||||||
|
class MockFileSystem : public FileSystem {
|
||||||
|
public:
|
||||||
|
explicit MockFileSystem(const std::shared_ptr<SystemClock>& clock,
|
||||||
|
bool supports_direct_io = true);
|
||||||
|
~MockFileSystem() override;
|
||||||
|
|
||||||
|
static const char* kClassName() { return "MemoryFileSystem"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
IOStatus NewSequentialFile(const std::string& f, const FileOptions& file_opts,
|
||||||
|
std::unique_ptr<FSSequentialFile>* r,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus NewRandomAccessFile(const std::string& f,
|
||||||
|
const FileOptions& file_opts,
|
||||||
|
std::unique_ptr<FSRandomAccessFile>* r,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus NewRandomRWFile(const std::string& fname,
|
||||||
|
const FileOptions& file_opts,
|
||||||
|
std::unique_ptr<FSRandomRWFile>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus ReuseWritableFile(const std::string& fname,
|
||||||
|
const std::string& old_fname,
|
||||||
|
const FileOptions& file_opts,
|
||||||
|
std::unique_ptr<FSWritableFile>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus NewWritableFile(const std::string& fname,
|
||||||
|
const FileOptions& file_opts,
|
||||||
|
std::unique_ptr<FSWritableFile>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus ReopenWritableFile(const std::string& fname,
|
||||||
|
const FileOptions& options,
|
||||||
|
std::unique_ptr<FSWritableFile>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus NewDirectory(const std::string& /*name*/, const IOOptions& io_opts,
|
||||||
|
std::unique_ptr<FSDirectory>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus FileExists(const std::string& fname, const IOOptions& /*io_opts*/,
|
||||||
|
IODebugContext* /*dbg*/) override;
|
||||||
|
IOStatus GetChildren(const std::string& dir, const IOOptions& options,
|
||||||
|
std::vector<std::string>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus DeleteFile(const std::string& fname, const IOOptions& options,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus Truncate(const std::string& fname, size_t size,
|
||||||
|
const IOOptions& options, IODebugContext* dbg) override;
|
||||||
|
IOStatus CreateDir(const std::string& dirname, const IOOptions& options,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus CreateDirIfMissing(const std::string& dirname,
|
||||||
|
const IOOptions& options,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus DeleteDir(const std::string& dirname, const IOOptions& options,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus GetFileSize(const std::string& fname, const IOOptions& options,
|
||||||
|
uint64_t* file_size, IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus GetFileModificationTime(const std::string& fname,
|
||||||
|
const IOOptions& options,
|
||||||
|
uint64_t* file_mtime,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus RenameFile(const std::string& src, const std::string& target,
|
||||||
|
const IOOptions& options, IODebugContext* dbg) override;
|
||||||
|
IOStatus LinkFile(const std::string& /*src*/, const std::string& /*target*/,
|
||||||
|
const IOOptions& /*options*/,
|
||||||
|
IODebugContext* /*dbg*/) override;
|
||||||
|
IOStatus LockFile(const std::string& fname, const IOOptions& options,
|
||||||
|
FileLock** lock, IODebugContext* dbg) override;
|
||||||
|
IOStatus UnlockFile(FileLock* lock, const IOOptions& options,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus GetTestDirectory(const IOOptions& options, std::string* path,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
IOStatus NewLogger(const std::string& fname, const IOOptions& io_opts,
|
||||||
|
std::shared_ptr<Logger>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
// Get full directory name for this db.
|
||||||
|
IOStatus GetAbsolutePath(const std::string& db_path,
|
||||||
|
const IOOptions& /*options*/,
|
||||||
|
std::string* output_path,
|
||||||
|
IODebugContext* /*dbg*/) override;
|
||||||
|
IOStatus IsDirectory(const std::string& /*path*/,
|
||||||
|
const IOOptions& /*options*/, bool* /*is_dir*/,
|
||||||
|
IODebugContext* /*dgb*/) override {
|
||||||
|
return IOStatus::NotSupported("IsDirectory");
|
||||||
|
}
|
||||||
|
|
||||||
|
Status CorruptBuffer(const std::string& fname);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool RenameFileInternal(const std::string& src, const std::string& dest);
|
||||||
|
void DeleteFileInternal(const std::string& fname);
|
||||||
|
bool GetChildrenInternal(const std::string& fname,
|
||||||
|
std::vector<std::string>* results);
|
||||||
|
|
||||||
|
std::string NormalizeMockPath(const std::string& path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Map from filenames to MemFile objects, representing a simple file system.
|
||||||
|
port::Mutex mutex_;
|
||||||
|
std::map<std::string, MemFile*> file_map_; // Protected by mutex_.
|
||||||
|
std::shared_ptr<SystemClock> system_clock_;
|
||||||
|
SystemClock* clock_;
|
||||||
|
bool supports_direct_io_;
|
||||||
|
};
|
||||||
|
|
||||||
class MockEnv : public CompositeEnvWrapper {
|
class MockEnv : public CompositeEnvWrapper {
|
||||||
public:
|
public:
|
||||||
static MockEnv* Create(Env* base);
|
static MockEnv* Create(Env* base);
|
||||||
|
@ -39,6 +39,9 @@ class MockFS : public FileSystemWrapper {
|
|||||||
bool support_prefetch)
|
bool support_prefetch)
|
||||||
: FileSystemWrapper(wrapped), support_prefetch_(support_prefetch) {}
|
: FileSystemWrapper(wrapped), support_prefetch_(support_prefetch) {}
|
||||||
|
|
||||||
|
static const char* kClassName() { return "MockFS"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
|
||||||
IOStatus NewRandomAccessFile(const std::string& fname,
|
IOStatus NewRandomAccessFile(const std::string& fname,
|
||||||
const FileOptions& opts,
|
const FileOptions& opts,
|
||||||
std::unique_ptr<FSRandomAccessFile>* result,
|
std::unique_ptr<FSRandomAccessFile>* result,
|
||||||
|
@ -24,6 +24,9 @@ struct ConfigOptions;
|
|||||||
// read from disk.
|
// read from disk.
|
||||||
Env* NewEncryptedEnv(Env* base_env,
|
Env* NewEncryptedEnv(Env* base_env,
|
||||||
const std::shared_ptr<EncryptionProvider>& provider);
|
const std::shared_ptr<EncryptionProvider>& provider);
|
||||||
|
std::shared_ptr<FileSystem> NewEncryptedFS(
|
||||||
|
const std::shared_ptr<FileSystem>& base_fs,
|
||||||
|
const std::shared_ptr<EncryptionProvider>& provider);
|
||||||
|
|
||||||
// BlockAccessCipherStream is the base class for any cipher stream that
|
// BlockAccessCipherStream is the base class for any cipher stream that
|
||||||
// supports random access at block level (without requiring data from other
|
// supports random access at block level (without requiring data from other
|
||||||
@ -440,6 +443,14 @@ class EncryptedFileSystem : public FileSystemWrapper {
|
|||||||
// otherwise
|
// otherwise
|
||||||
virtual Status AddCipher(const std::string& descriptor, const char* cipher,
|
virtual Status AddCipher(const std::string& descriptor, const char* cipher,
|
||||||
size_t len, bool for_write) = 0;
|
size_t len, bool for_write) = 0;
|
||||||
|
static const char* kClassName() { return "EncryptedFileSystem"; }
|
||||||
|
bool IsInstanceOf(const std::string& name) const override {
|
||||||
|
if (name == kClassName()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return FileSystemWrapper::IsInstanceOf(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // namespace ROCKSDB_NAMESPACE
|
} // namespace ROCKSDB_NAMESPACE
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "rocksdb/customizable.h"
|
||||||
#include "rocksdb/env.h"
|
#include "rocksdb/env.h"
|
||||||
#include "rocksdb/io_status.h"
|
#include "rocksdb/io_status.h"
|
||||||
#include "rocksdb/options.h"
|
#include "rocksdb/options.h"
|
||||||
@ -207,7 +208,8 @@ struct IODebugContext {
|
|||||||
// retryable.
|
// retryable.
|
||||||
// NewCompositeEnv can be used to create an Env with a custom FileSystem for
|
// NewCompositeEnv can be used to create an Env with a custom FileSystem for
|
||||||
// DBOptions::env.
|
// DBOptions::env.
|
||||||
class FileSystem {
|
|
||||||
|
class FileSystem : public Customizable {
|
||||||
public:
|
public:
|
||||||
FileSystem();
|
FileSystem();
|
||||||
|
|
||||||
@ -216,9 +218,8 @@ class FileSystem {
|
|||||||
|
|
||||||
virtual ~FileSystem();
|
virtual ~FileSystem();
|
||||||
|
|
||||||
virtual const char* Name() const = 0;
|
|
||||||
|
|
||||||
static const char* Type() { return "FileSystem"; }
|
static const char* Type() { return "FileSystem"; }
|
||||||
|
static const char* kDefaultName() { return "DefaultFileSystem"; }
|
||||||
|
|
||||||
// Loads the FileSystem specified by the input value into the result
|
// Loads the FileSystem specified by the input value into the result
|
||||||
// The CreateFromString alternative should be used; this method may be
|
// The CreateFromString alternative should be used; this method may be
|
||||||
@ -1147,12 +1148,9 @@ class FSDirectory {
|
|||||||
class FileSystemWrapper : public FileSystem {
|
class FileSystemWrapper : public FileSystem {
|
||||||
public:
|
public:
|
||||||
// Initialize an EnvWrapper that delegates all calls to *t
|
// Initialize an EnvWrapper that delegates all calls to *t
|
||||||
explicit FileSystemWrapper(const std::shared_ptr<FileSystem>& t)
|
explicit FileSystemWrapper(const std::shared_ptr<FileSystem>& t);
|
||||||
: target_(t) {}
|
|
||||||
~FileSystemWrapper() override {}
|
~FileSystemWrapper() override {}
|
||||||
|
|
||||||
const char* Name() const override { return target_->Name(); }
|
|
||||||
|
|
||||||
// Return the target to which this Env forwards all calls
|
// Return the target to which this Env forwards all calls
|
||||||
FileSystem* target() const { return target_.get(); }
|
FileSystem* target() const { return target_.get(); }
|
||||||
|
|
||||||
@ -1343,7 +1341,13 @@ class FileSystemWrapper : public FileSystem {
|
|||||||
return target_->IsDirectory(path, options, is_dir, dbg);
|
return target_->IsDirectory(path, options, is_dir, dbg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
const Customizable* Inner() const override { return target_.get(); }
|
||||||
|
Status PrepareOptions(const ConfigOptions& options) override;
|
||||||
|
#ifndef ROCKSDB_LITE
|
||||||
|
std::string SerializeOptions(const ConfigOptions& config_options,
|
||||||
|
const std::string& header) const override;
|
||||||
|
#endif // ROCKSDB_LITE
|
||||||
|
protected:
|
||||||
std::shared_ptr<FileSystem> target_;
|
std::shared_ptr<FileSystem> target_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1299,6 +1299,17 @@ class MockCipher : public BlockCipher {
|
|||||||
Status Encrypt(char* /*data*/) override { return Status::NotSupported(); }
|
Status Encrypt(char* /*data*/) override { return Status::NotSupported(); }
|
||||||
Status Decrypt(char* data) override { return Encrypt(data); }
|
Status Decrypt(char* data) override { return Encrypt(data); }
|
||||||
};
|
};
|
||||||
|
#endif // ROCKSDB_LITE
|
||||||
|
|
||||||
|
class DummyFileSystem : public FileSystemWrapper {
|
||||||
|
public:
|
||||||
|
explicit DummyFileSystem(const std::shared_ptr<FileSystem>& t)
|
||||||
|
: FileSystemWrapper(t) {}
|
||||||
|
static const char* kClassName() { return "DummyFileSystem"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef ROCKSDB_LITE
|
||||||
|
|
||||||
#endif // ROCKSDB_LITE
|
#endif // ROCKSDB_LITE
|
||||||
|
|
||||||
@ -1406,6 +1417,14 @@ static int RegisterLocalObjects(ObjectLibrary& library,
|
|||||||
return guard->get();
|
return guard->get();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
library.Register<FileSystem>(
|
||||||
|
DummyFileSystem::kClassName(),
|
||||||
|
[](const std::string& /*uri*/, std::unique_ptr<FileSystem>* guard,
|
||||||
|
std::string* /* errmsg */) {
|
||||||
|
guard->reset(new DummyFileSystem(nullptr));
|
||||||
|
return guard->get();
|
||||||
|
});
|
||||||
|
|
||||||
library.Register<SstPartitionerFactory>(
|
library.Register<SstPartitionerFactory>(
|
||||||
MockSstPartitionerFactory::kClassName(),
|
MockSstPartitionerFactory::kClassName(),
|
||||||
[](const std::string& /*uri*/,
|
[](const std::string& /*uri*/,
|
||||||
@ -1495,6 +1514,24 @@ TEST_F(LoadCustomizableTest, LoadTableFactoryTest) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(LoadCustomizableTest, LoadFileSystemTest) {
|
||||||
|
ColumnFamilyOptions cf_opts;
|
||||||
|
std::shared_ptr<FileSystem> result;
|
||||||
|
ASSERT_NOK(FileSystem::CreateFromString(
|
||||||
|
config_options_, DummyFileSystem::kClassName(), &result));
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(config_options_,
|
||||||
|
FileSystem::kDefaultName(), &result));
|
||||||
|
ASSERT_NE(result, nullptr);
|
||||||
|
ASSERT_TRUE(result->IsInstanceOf(FileSystem::kDefaultName()));
|
||||||
|
if (RegisterTests("Test")) {
|
||||||
|
ASSERT_OK(FileSystem::CreateFromString(
|
||||||
|
config_options_, DummyFileSystem::kClassName(), &result));
|
||||||
|
ASSERT_NE(result, nullptr);
|
||||||
|
ASSERT_STREQ(result->Name(), DummyFileSystem::kClassName());
|
||||||
|
ASSERT_FALSE(result->IsInstanceOf(FileSystem::kDefaultName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(LoadCustomizableTest, LoadSecondaryCacheTest) {
|
TEST_F(LoadCustomizableTest, LoadSecondaryCacheTest) {
|
||||||
std::shared_ptr<SecondaryCache> result;
|
std::shared_ptr<SecondaryCache> result;
|
||||||
ASSERT_NOK(SecondaryCache::CreateFromString(
|
ASSERT_NOK(SecondaryCache::CreateFromString(
|
||||||
|
@ -110,7 +110,10 @@ class WinFileSystem : public FileSystem {
|
|||||||
static const std::shared_ptr<WinFileSystem>& Default();
|
static const std::shared_ptr<WinFileSystem>& Default();
|
||||||
WinFileSystem(const std::shared_ptr<SystemClock>& clock);
|
WinFileSystem(const std::shared_ptr<SystemClock>& clock);
|
||||||
~WinFileSystem() {}
|
~WinFileSystem() {}
|
||||||
const char* Name() const { return "WinFS"; }
|
static const char* kClassName() { return "WinFS"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
const char* NickName() const { return kDefaultName(); }
|
||||||
|
|
||||||
static size_t GetSectorSize(const std::string& fname);
|
static size_t GetSectorSize(const std::string& fname);
|
||||||
size_t GetPageSize() const { return page_size_; }
|
size_t GetPageSize() const { return page_size_; }
|
||||||
size_t GetAllocationGranularity() const { return allocation_granularity_; }
|
size_t GetAllocationGranularity() const { return allocation_granularity_; }
|
||||||
|
@ -555,6 +555,9 @@ class StringFS : public FileSystemWrapper {
|
|||||||
: FileSystemWrapper(t) {}
|
: FileSystemWrapper(t) {}
|
||||||
~StringFS() override {}
|
~StringFS() override {}
|
||||||
|
|
||||||
|
static const char* kClassName() { return "StringFS"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
|
||||||
const std::string& GetContent(const std::string& f) { return files_[f]; }
|
const std::string& GetContent(const std::string& f) { return files_[f]; }
|
||||||
|
|
||||||
const IOStatus WriteToNewFile(const std::string& file_name,
|
const IOStatus WriteToNewFile(const std::string& file_name,
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// This source code is licensed under both the GPLv2 (found in the
|
// This source code is licensed under both the GPLv2 (found in the
|
||||||
// COPYING file in the root directory) and Apache 2.0 License
|
// COPYING file in the root directory) and Apache 2.0 License
|
||||||
// (found in the LICENSE.Apache file in the root directory).
|
// (found in the LICENSE.Apache file in the root directory).
|
||||||
|
#include "utilities/env_timed.h"
|
||||||
|
|
||||||
#include "env/composite_env_wrapper.h"
|
#include "env/composite_env_wrapper.h"
|
||||||
#include "monitoring/perf_context_imp.h"
|
#include "monitoring/perf_context_imp.h"
|
||||||
@ -12,154 +13,157 @@
|
|||||||
namespace ROCKSDB_NAMESPACE {
|
namespace ROCKSDB_NAMESPACE {
|
||||||
|
|
||||||
#ifndef ROCKSDB_LITE
|
#ifndef ROCKSDB_LITE
|
||||||
namespace {
|
TimedFileSystem::TimedFileSystem(const std::shared_ptr<FileSystem>& base)
|
||||||
class TimedFileSystem : public FileSystemWrapper {
|
: FileSystemWrapper(base) {}
|
||||||
public:
|
IOStatus TimedFileSystem::NewSequentialFile(
|
||||||
explicit TimedFileSystem(const std::shared_ptr<FileSystem>& base)
|
const std::string& fname, const FileOptions& options,
|
||||||
: FileSystemWrapper(base) {}
|
std::unique_ptr<FSSequentialFile>* result, IODebugContext* dbg) {
|
||||||
|
PERF_TIMER_GUARD(env_new_sequential_file_nanos);
|
||||||
|
return FileSystemWrapper::NewSequentialFile(fname, options, result, dbg);
|
||||||
|
}
|
||||||
|
|
||||||
const char* Name() const override { return "TimedFS"; }
|
IOStatus TimedFileSystem::NewRandomAccessFile(
|
||||||
IOStatus NewSequentialFile(const std::string& fname,
|
const std::string& fname, const FileOptions& options,
|
||||||
const FileOptions& options,
|
std::unique_ptr<FSRandomAccessFile>* result, IODebugContext* dbg) {
|
||||||
std::unique_ptr<FSSequentialFile>* result,
|
PERF_TIMER_GUARD(env_new_random_access_file_nanos);
|
||||||
IODebugContext* dbg) override {
|
return FileSystemWrapper::NewRandomAccessFile(fname, options, result, dbg);
|
||||||
PERF_TIMER_GUARD(env_new_sequential_file_nanos);
|
}
|
||||||
return FileSystemWrapper::NewSequentialFile(fname, options, result, dbg);
|
|
||||||
}
|
|
||||||
|
|
||||||
IOStatus NewRandomAccessFile(const std::string& fname,
|
IOStatus TimedFileSystem::NewWritableFile(
|
||||||
const FileOptions& options,
|
const std::string& fname, const FileOptions& options,
|
||||||
std::unique_ptr<FSRandomAccessFile>* result,
|
std::unique_ptr<FSWritableFile>* result, IODebugContext* dbg) {
|
||||||
IODebugContext* dbg) override {
|
PERF_TIMER_GUARD(env_new_writable_file_nanos);
|
||||||
PERF_TIMER_GUARD(env_new_random_access_file_nanos);
|
return FileSystemWrapper::NewWritableFile(fname, options, result, dbg);
|
||||||
return FileSystemWrapper::NewRandomAccessFile(fname, options, result, dbg);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
IOStatus NewWritableFile(const std::string& fname, const FileOptions& options,
|
IOStatus TimedFileSystem::ReuseWritableFile(
|
||||||
std::unique_ptr<FSWritableFile>* result,
|
const std::string& fname, const std::string& old_fname,
|
||||||
IODebugContext* dbg) override {
|
const FileOptions& options, std::unique_ptr<FSWritableFile>* result,
|
||||||
PERF_TIMER_GUARD(env_new_writable_file_nanos);
|
IODebugContext* dbg) {
|
||||||
return FileSystemWrapper::NewWritableFile(fname, options, result, dbg);
|
PERF_TIMER_GUARD(env_reuse_writable_file_nanos);
|
||||||
}
|
return FileSystemWrapper::ReuseWritableFile(fname, old_fname, options, result,
|
||||||
|
dbg);
|
||||||
|
}
|
||||||
|
|
||||||
IOStatus ReuseWritableFile(const std::string& fname,
|
IOStatus TimedFileSystem::NewRandomRWFile(
|
||||||
const std::string& old_fname,
|
const std::string& fname, const FileOptions& options,
|
||||||
const FileOptions& options,
|
std::unique_ptr<FSRandomRWFile>* result, IODebugContext* dbg) {
|
||||||
std::unique_ptr<FSWritableFile>* result,
|
PERF_TIMER_GUARD(env_new_random_rw_file_nanos);
|
||||||
IODebugContext* dbg) override {
|
return FileSystemWrapper::NewRandomRWFile(fname, options, result, dbg);
|
||||||
PERF_TIMER_GUARD(env_reuse_writable_file_nanos);
|
}
|
||||||
return FileSystemWrapper::ReuseWritableFile(fname, old_fname, options,
|
|
||||||
result, dbg);
|
|
||||||
}
|
|
||||||
|
|
||||||
IOStatus NewRandomRWFile(const std::string& fname, const FileOptions& options,
|
IOStatus TimedFileSystem::NewDirectory(const std::string& name,
|
||||||
std::unique_ptr<FSRandomRWFile>* result,
|
const IOOptions& options,
|
||||||
IODebugContext* dbg) override {
|
std::unique_ptr<FSDirectory>* result,
|
||||||
PERF_TIMER_GUARD(env_new_random_rw_file_nanos);
|
IODebugContext* dbg) {
|
||||||
return FileSystemWrapper::NewRandomRWFile(fname, options, result, dbg);
|
PERF_TIMER_GUARD(env_new_directory_nanos);
|
||||||
}
|
return FileSystemWrapper::NewDirectory(name, options, result, dbg);
|
||||||
|
}
|
||||||
|
|
||||||
IOStatus NewDirectory(const std::string& name, const IOOptions& options,
|
IOStatus TimedFileSystem::FileExists(const std::string& fname,
|
||||||
std::unique_ptr<FSDirectory>* result,
|
|
||||||
IODebugContext* dbg) override {
|
|
||||||
PERF_TIMER_GUARD(env_new_directory_nanos);
|
|
||||||
return FileSystemWrapper::NewDirectory(name, options, result, dbg);
|
|
||||||
}
|
|
||||||
|
|
||||||
IOStatus FileExists(const std::string& fname, const IOOptions& options,
|
|
||||||
IODebugContext* dbg) override {
|
|
||||||
PERF_TIMER_GUARD(env_file_exists_nanos);
|
|
||||||
return FileSystemWrapper::FileExists(fname, options, dbg);
|
|
||||||
}
|
|
||||||
|
|
||||||
IOStatus GetChildren(const std::string& dir, const IOOptions& options,
|
|
||||||
std::vector<std::string>* result,
|
|
||||||
IODebugContext* dbg) override {
|
|
||||||
PERF_TIMER_GUARD(env_get_children_nanos);
|
|
||||||
return FileSystemWrapper::GetChildren(dir, options, result, dbg);
|
|
||||||
}
|
|
||||||
|
|
||||||
IOStatus GetChildrenFileAttributes(const std::string& dir,
|
|
||||||
const IOOptions& options,
|
const IOOptions& options,
|
||||||
std::vector<FileAttributes>* result,
|
IODebugContext* dbg) {
|
||||||
IODebugContext* dbg) override {
|
PERF_TIMER_GUARD(env_file_exists_nanos);
|
||||||
PERF_TIMER_GUARD(env_get_children_file_attributes_nanos);
|
return FileSystemWrapper::FileExists(fname, options, dbg);
|
||||||
return FileSystemWrapper::GetChildrenFileAttributes(dir, options, result,
|
}
|
||||||
dbg);
|
|
||||||
}
|
|
||||||
|
|
||||||
IOStatus DeleteFile(const std::string& fname, const IOOptions& options,
|
IOStatus TimedFileSystem::GetChildren(const std::string& dir,
|
||||||
IODebugContext* dbg) override {
|
const IOOptions& options,
|
||||||
PERF_TIMER_GUARD(env_delete_file_nanos);
|
std::vector<std::string>* result,
|
||||||
return FileSystemWrapper::DeleteFile(fname, options, dbg);
|
IODebugContext* dbg) {
|
||||||
}
|
PERF_TIMER_GUARD(env_get_children_nanos);
|
||||||
|
return FileSystemWrapper::GetChildren(dir, options, result, dbg);
|
||||||
|
}
|
||||||
|
|
||||||
IOStatus CreateDir(const std::string& dirname, const IOOptions& options,
|
IOStatus TimedFileSystem::GetChildrenFileAttributes(
|
||||||
IODebugContext* dbg) override {
|
const std::string& dir, const IOOptions& options,
|
||||||
PERF_TIMER_GUARD(env_create_dir_nanos);
|
std::vector<FileAttributes>* result, IODebugContext* dbg) {
|
||||||
return FileSystemWrapper::CreateDir(dirname, options, dbg);
|
PERF_TIMER_GUARD(env_get_children_file_attributes_nanos);
|
||||||
}
|
return FileSystemWrapper::GetChildrenFileAttributes(dir, options, result,
|
||||||
|
dbg);
|
||||||
|
}
|
||||||
|
|
||||||
IOStatus CreateDirIfMissing(const std::string& dirname,
|
IOStatus TimedFileSystem::DeleteFile(const std::string& fname,
|
||||||
const IOOptions& options,
|
const IOOptions& options,
|
||||||
IODebugContext* dbg) override {
|
IODebugContext* dbg) {
|
||||||
PERF_TIMER_GUARD(env_create_dir_if_missing_nanos);
|
PERF_TIMER_GUARD(env_delete_file_nanos);
|
||||||
return FileSystemWrapper::CreateDirIfMissing(dirname, options, dbg);
|
return FileSystemWrapper::DeleteFile(fname, options, dbg);
|
||||||
}
|
}
|
||||||
|
|
||||||
IOStatus DeleteDir(const std::string& dirname, const IOOptions& options,
|
IOStatus TimedFileSystem::CreateDir(const std::string& dirname,
|
||||||
IODebugContext* dbg) override {
|
const IOOptions& options,
|
||||||
PERF_TIMER_GUARD(env_delete_dir_nanos);
|
IODebugContext* dbg) {
|
||||||
return FileSystemWrapper::DeleteDir(dirname, options, dbg);
|
PERF_TIMER_GUARD(env_create_dir_nanos);
|
||||||
}
|
return FileSystemWrapper::CreateDir(dirname, options, dbg);
|
||||||
|
}
|
||||||
|
|
||||||
IOStatus GetFileSize(const std::string& fname, const IOOptions& options,
|
IOStatus TimedFileSystem::CreateDirIfMissing(const std::string& dirname,
|
||||||
uint64_t* file_size, IODebugContext* dbg) override {
|
const IOOptions& options,
|
||||||
PERF_TIMER_GUARD(env_get_file_size_nanos);
|
IODebugContext* dbg) {
|
||||||
return FileSystemWrapper::GetFileSize(fname, options, file_size, dbg);
|
PERF_TIMER_GUARD(env_create_dir_if_missing_nanos);
|
||||||
}
|
return FileSystemWrapper::CreateDirIfMissing(dirname, options, dbg);
|
||||||
|
}
|
||||||
|
|
||||||
IOStatus GetFileModificationTime(const std::string& fname,
|
IOStatus TimedFileSystem::DeleteDir(const std::string& dirname,
|
||||||
|
const IOOptions& options,
|
||||||
|
IODebugContext* dbg) {
|
||||||
|
PERF_TIMER_GUARD(env_delete_dir_nanos);
|
||||||
|
return FileSystemWrapper::DeleteDir(dirname, options, dbg);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOStatus TimedFileSystem::GetFileSize(const std::string& fname,
|
||||||
|
const IOOptions& options,
|
||||||
|
uint64_t* file_size,
|
||||||
|
IODebugContext* dbg) {
|
||||||
|
PERF_TIMER_GUARD(env_get_file_size_nanos);
|
||||||
|
return FileSystemWrapper::GetFileSize(fname, options, file_size, dbg);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOStatus TimedFileSystem::GetFileModificationTime(const std::string& fname,
|
||||||
|
const IOOptions& options,
|
||||||
|
uint64_t* file_mtime,
|
||||||
|
IODebugContext* dbg) {
|
||||||
|
PERF_TIMER_GUARD(env_get_file_modification_time_nanos);
|
||||||
|
return FileSystemWrapper::GetFileModificationTime(fname, options, file_mtime,
|
||||||
|
dbg);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOStatus TimedFileSystem::RenameFile(const std::string& src,
|
||||||
|
const std::string& dst,
|
||||||
|
const IOOptions& options,
|
||||||
|
IODebugContext* dbg) {
|
||||||
|
PERF_TIMER_GUARD(env_rename_file_nanos);
|
||||||
|
return FileSystemWrapper::RenameFile(src, dst, options, dbg);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOStatus TimedFileSystem::LinkFile(const std::string& src,
|
||||||
|
const std::string& dst,
|
||||||
const IOOptions& options,
|
const IOOptions& options,
|
||||||
uint64_t* file_mtime,
|
IODebugContext* dbg) {
|
||||||
IODebugContext* dbg) override {
|
PERF_TIMER_GUARD(env_link_file_nanos);
|
||||||
PERF_TIMER_GUARD(env_get_file_modification_time_nanos);
|
return FileSystemWrapper::LinkFile(src, dst, options, dbg);
|
||||||
return FileSystemWrapper::GetFileModificationTime(fname, options,
|
}
|
||||||
file_mtime, dbg);
|
|
||||||
}
|
|
||||||
|
|
||||||
IOStatus RenameFile(const std::string& src, const std::string& dst,
|
IOStatus TimedFileSystem::LockFile(const std::string& fname,
|
||||||
const IOOptions& options, IODebugContext* dbg) override {
|
const IOOptions& options, FileLock** lock,
|
||||||
PERF_TIMER_GUARD(env_rename_file_nanos);
|
IODebugContext* dbg) {
|
||||||
return FileSystemWrapper::RenameFile(src, dst, options, dbg);
|
PERF_TIMER_GUARD(env_lock_file_nanos);
|
||||||
}
|
return FileSystemWrapper::LockFile(fname, options, lock, dbg);
|
||||||
|
}
|
||||||
|
|
||||||
IOStatus LinkFile(const std::string& src, const std::string& dst,
|
IOStatus TimedFileSystem::UnlockFile(FileLock* lock, const IOOptions& options,
|
||||||
const IOOptions& options, IODebugContext* dbg) override {
|
IODebugContext* dbg) {
|
||||||
PERF_TIMER_GUARD(env_link_file_nanos);
|
PERF_TIMER_GUARD(env_unlock_file_nanos);
|
||||||
return FileSystemWrapper::LinkFile(src, dst, options, dbg);
|
return FileSystemWrapper::UnlockFile(lock, options, dbg);
|
||||||
}
|
}
|
||||||
|
|
||||||
IOStatus LockFile(const std::string& fname, const IOOptions& options,
|
IOStatus TimedFileSystem::NewLogger(const std::string& fname,
|
||||||
FileLock** lock, IODebugContext* dbg) override {
|
const IOOptions& options,
|
||||||
PERF_TIMER_GUARD(env_lock_file_nanos);
|
std::shared_ptr<Logger>* result,
|
||||||
return FileSystemWrapper::LockFile(fname, options, lock, dbg);
|
IODebugContext* dbg) {
|
||||||
}
|
PERF_TIMER_GUARD(env_new_logger_nanos);
|
||||||
|
return FileSystemWrapper::NewLogger(fname, options, result, dbg);
|
||||||
IOStatus UnlockFile(FileLock* lock, const IOOptions& options,
|
}
|
||||||
IODebugContext* dbg) override {
|
|
||||||
PERF_TIMER_GUARD(env_unlock_file_nanos);
|
|
||||||
return FileSystemWrapper::UnlockFile(lock, options, dbg);
|
|
||||||
}
|
|
||||||
|
|
||||||
IOStatus NewLogger(const std::string& fname, const IOOptions& options,
|
|
||||||
std::shared_ptr<Logger>* result,
|
|
||||||
IODebugContext* dbg) override {
|
|
||||||
PERF_TIMER_GUARD(env_new_logger_nanos);
|
|
||||||
return FileSystemWrapper::NewLogger(fname, options, result, dbg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
std::shared_ptr<FileSystem> NewTimedFileSystem(
|
std::shared_ptr<FileSystem> NewTimedFileSystem(
|
||||||
const std::shared_ptr<FileSystem>& base) {
|
const std::shared_ptr<FileSystem>& base) {
|
||||||
|
97
utilities/env_timed.h
Normal file
97
utilities/env_timed.h
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
// Copyright (c) 2019-present, Facebook, Inc. All rights reserved.
|
||||||
|
// This source code is licensed under both the GPLv2 (found in the
|
||||||
|
// COPYING file in the root directory) and Apache 2.0 License
|
||||||
|
// (found in the LICENSE.Apache file in the root directory).
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "rocksdb/file_system.h"
|
||||||
|
namespace ROCKSDB_NAMESPACE {
|
||||||
|
#ifndef ROCKSDB_LITE
|
||||||
|
class TimedFileSystem : public FileSystemWrapper {
|
||||||
|
public:
|
||||||
|
explicit TimedFileSystem(const std::shared_ptr<FileSystem>& base);
|
||||||
|
|
||||||
|
static const char* kClassName() { return "TimedFS"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
|
||||||
|
IOStatus NewSequentialFile(const std::string& fname,
|
||||||
|
const FileOptions& options,
|
||||||
|
std::unique_ptr<FSSequentialFile>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus NewRandomAccessFile(const std::string& fname,
|
||||||
|
const FileOptions& options,
|
||||||
|
std::unique_ptr<FSRandomAccessFile>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus NewWritableFile(const std::string& fname, const FileOptions& options,
|
||||||
|
std::unique_ptr<FSWritableFile>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus ReuseWritableFile(const std::string& fname,
|
||||||
|
const std::string& old_fname,
|
||||||
|
const FileOptions& options,
|
||||||
|
std::unique_ptr<FSWritableFile>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus NewRandomRWFile(const std::string& fname, const FileOptions& options,
|
||||||
|
std::unique_ptr<FSRandomRWFile>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus NewDirectory(const std::string& name, const IOOptions& options,
|
||||||
|
std::unique_ptr<FSDirectory>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus FileExists(const std::string& fname, const IOOptions& options,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus GetChildren(const std::string& dir, const IOOptions& options,
|
||||||
|
std::vector<std::string>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus GetChildrenFileAttributes(const std::string& dir,
|
||||||
|
const IOOptions& options,
|
||||||
|
std::vector<FileAttributes>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus DeleteFile(const std::string& fname, const IOOptions& options,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus CreateDir(const std::string& dirname, const IOOptions& options,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus CreateDirIfMissing(const std::string& dirname,
|
||||||
|
const IOOptions& options,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus DeleteDir(const std::string& dirname, const IOOptions& options,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus GetFileSize(const std::string& fname, const IOOptions& options,
|
||||||
|
uint64_t* file_size, IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus GetFileModificationTime(const std::string& fname,
|
||||||
|
const IOOptions& options,
|
||||||
|
uint64_t* file_mtime,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus RenameFile(const std::string& src, const std::string& dst,
|
||||||
|
const IOOptions& options, IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus LinkFile(const std::string& src, const std::string& dst,
|
||||||
|
const IOOptions& options, IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus LockFile(const std::string& fname, const IOOptions& options,
|
||||||
|
FileLock** lock, IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus UnlockFile(FileLock* lock, const IOOptions& options,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
|
||||||
|
IOStatus NewLogger(const std::string& fname, const IOOptions& options,
|
||||||
|
std::shared_ptr<Logger>* result,
|
||||||
|
IODebugContext* dbg) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ROCKSDB_LITE
|
||||||
|
} // namespace ROCKSDB_NAMESPACE
|
@ -200,7 +200,8 @@ class FaultInjectionTestFS : public FileSystemWrapper {
|
|||||||
fail_get_file_unique_id_(false) {}
|
fail_get_file_unique_id_(false) {}
|
||||||
virtual ~FaultInjectionTestFS() { error_.PermitUncheckedError(); }
|
virtual ~FaultInjectionTestFS() { error_.PermitUncheckedError(); }
|
||||||
|
|
||||||
const char* Name() const override { return "FaultInjectionTestFS"; }
|
static const char* kClassName() { return "FaultInjectionTestFS"; }
|
||||||
|
const char* Name() const override { return kClassName(); }
|
||||||
|
|
||||||
IOStatus NewDirectory(const std::string& name, const IOOptions& options,
|
IOStatus NewDirectory(const std::string& name, const IOOptions& options,
|
||||||
std::unique_ptr<FSDirectory>* result,
|
std::unique_ptr<FSDirectory>* result,
|
||||||
|
Loading…
Reference in New Issue
Block a user