diff --git a/include/leveldb/env.h b/include/leveldb/env.h index 8a27bbede..6e163726c 100644 --- a/include/leveldb/env.h +++ b/include/leveldb/env.h @@ -385,6 +385,9 @@ class EnvOptions { // If true, then use mmap to write data virtual bool UseMmapWrites() const = 0; + + // If true, set the FD_CLOEXEC on open fd. + virtual bool IsFDCloseOnExec() const = 0; }; // Log the specified data to *info_log if info_log is non-nullptr. diff --git a/include/leveldb/options.h b/include/leveldb/options.h index 219f05f48..863cf919a 100644 --- a/include/leveldb/options.h +++ b/include/leveldb/options.h @@ -415,6 +415,9 @@ struct Options { // Allow the OS to mmap file for writing. Default: true bool allow_mmap_writes; + + // Disable child process inherit open files. Default: true + bool is_fd_close_on_exec; }; // Options that control read operations diff --git a/util/env_posix.cc b/util/env_posix.cc index 88373bccd..7cdf66cec 100644 --- a/util/env_posix.cc +++ b/util/env_posix.cc @@ -605,6 +605,12 @@ class PosixEnv : public Env { exit(1); } + void SetFD_CLOEXEC(int fd, const EnvOptions* options) { + if ((options == nullptr || options->IsFDCloseOnExec()) && fd > 0) { + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); + } + } + virtual Status NewSequentialFile(const std::string& fname, unique_ptr* result, const EnvOptions& options) { @@ -614,6 +620,8 @@ class PosixEnv : public Env { *result = nullptr; return IOError(fname, errno); } else { + int fd = fileno(f); + SetFD_CLOEXEC(fd, &options); result->reset(new PosixSequentialFile(fname, f, options)); return Status::OK(); } @@ -625,6 +633,7 @@ class PosixEnv : public Env { result->reset(); Status s; int fd = open(fname.c_str(), O_RDONLY); + SetFD_CLOEXEC(fd, &options); if (fd < 0) { s = IOError(fname, errno); } else if (options.UseMmapReads() && sizeof(void*) >= 8) { @@ -657,6 +666,7 @@ class PosixEnv : public Env { if (fd < 0) { s = IOError(fname, errno); } else { + SetFD_CLOEXEC(fd, &options); if (options.UseMmapWrites()) { if (!checkedDiskForMmap_) { // this will be executed once in the program's lifetime. @@ -772,6 +782,7 @@ class PosixEnv : public Env { result = IOError("lock " + fname, errno); close(fd); } else { + SetFD_CLOEXEC(fd, nullptr); PosixFileLock* my_lock = new PosixFileLock; my_lock->fd_ = fd; my_lock->filename = fname; @@ -823,6 +834,8 @@ class PosixEnv : public Env { result->reset(); return IOError(fname, errno); } else { + int fd = fileno(f); + SetFD_CLOEXEC(fd, nullptr); result->reset(new PosixLogger(f, &PosixEnv::gettid)); return Status::OK(); } diff --git a/util/options.cc b/util/options.cc index f467ed19a..1d4836479 100644 --- a/util/options.cc +++ b/util/options.cc @@ -64,7 +64,8 @@ Options::Options() allow_readahead(true), allow_readahead_compactions(true), allow_mmap_reads(false), - allow_mmap_writes(true) { + allow_mmap_writes(true), + is_fd_close_on_exec(true) { } void @@ -168,6 +169,20 @@ Options::Dump(Logger* log) const WAL_ttl_seconds); Log(log," Options.manifest_preallocation_size: %ld", manifest_preallocation_size); + Log(log," Options.purge_redundant_kvs_while_flush: %d", + purge_redundant_kvs_while_flush); + Log(log," Options.allow_os_buffer: %d", + allow_os_buffer); + Log(log," Options.allow_readahead: %d", + allow_readahead); + Log(log," Options.allow_readahead_compactions: %d", + allow_readahead_compactions); + Log(log," Options.allow_mmap_reads: %d", + allow_mmap_reads); + Log(log," Options.allow_mmap_writes: %d", + allow_mmap_writes); + Log(log," Options.is_fd_close_on_exec: %d", + is_fd_close_on_exec); } // Options::Dump // diff --git a/util/storage_options.h b/util/storage_options.h index 54dfb23dc..1d2c850e4 100644 --- a/util/storage_options.h +++ b/util/storage_options.h @@ -20,7 +20,9 @@ class StorageOptions : public EnvOptions { fs_readahead_(opt.allow_readahead), readahead_compactions_(opt.allow_readahead_compactions), use_mmap_reads_(opt.allow_mmap_reads), - use_mmap_writes_(opt.allow_mmap_writes) { + use_mmap_writes_(opt.allow_mmap_writes), + set_fd_cloexec_(opt.is_fd_close_on_exec) + { } // copy constructor with readaheads set to readahead_compactions_ @@ -30,6 +32,7 @@ class StorageOptions : public EnvOptions { readahead_compactions_ = opt.UseReadaheadCompactions(); use_mmap_reads_ = opt.UseMmapReads(); use_mmap_writes_ = opt.UseMmapWrites(); + set_fd_cloexec_ = opt.IsFDCloseOnExec(); } // constructor with default options @@ -40,6 +43,7 @@ class StorageOptions : public EnvOptions { readahead_compactions_ = fs_readahead_; use_mmap_reads_ = opt.allow_mmap_reads; use_mmap_writes_ = opt.allow_mmap_writes; + set_fd_cloexec_ = opt.is_fd_close_on_exec; } virtual ~StorageOptions() {} @@ -49,6 +53,7 @@ class StorageOptions : public EnvOptions { bool UseMmapReads() const { return use_mmap_reads_; } bool UseMmapWrites() const { return use_mmap_writes_; } bool UseReadaheadCompactions() const { return readahead_compactions_;} + bool IsFDCloseOnExec() const { return set_fd_cloexec_;} void DisableMmapWrites() { use_mmap_writes_ = false; @@ -60,6 +65,7 @@ class StorageOptions : public EnvOptions { bool readahead_compactions_; bool use_mmap_reads_; bool use_mmap_writes_; + bool set_fd_cloexec_; }; } // namespace leveldb