Set FD_CLOEXEC after each file open

Summary: as subject. This is causing problem in adsconv. Ideally, this flags should be set in open. But that is only supported in Linux kernel ≥2.6.23 and glibc ≥2.7.

Test Plan:
db_test

run db_test

Reviewers: dhruba, MarkCallaghan, haobo

Reviewed By: dhruba

CC: leveldb, chip

Differential Revision: https://reviews.facebook.net/D10089
This commit is contained in:
heyongqiang 2013-04-09 19:42:07 -07:00
parent f51b375062
commit e21ba94a69
5 changed files with 42 additions and 2 deletions

View File

@ -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.

View File

@ -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

View File

@ -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<SequentialFile>* 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();
}

View File

@ -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
//

View File

@ -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