Otherwise these descriptors may leak across execve() during e.g. MDS respawn.
Fixes: http://tracker.ceph.com/issues/35850
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
CHECK_FUNCTION_EXISTS(strerror_r HAVE_Strerror_R)
CHECK_FUNCTION_EXISTS(name_to_handle_at HAVE_NAME_TO_HANDLE_AT)
CHECK_FUNCTION_EXISTS(pipe2 HAVE_PIPE2)
+CHECK_FUNCTION_EXISTS(accept4 HAVE_ACCEPT4)
include(CMakePushCheckState)
cmake_push_check_state(RESET)
#include <sstream>
#include <limits>
+#include <fcntl.h>
+
#include "Crypto.h"
#ifdef USE_OPENSSL
# include <openssl/aes.h>
// open /dev/urandom once on construction and reuse the fd for all reads
CryptoRandom::CryptoRandom()
- : fd(TEMP_FAILURE_RETRY(::open("/dev/urandom", O_RDONLY)))
+ : fd(TEMP_FAILURE_RETRY(::open("/dev/urandom", O_CLOEXEC|O_RDONLY)))
{
if (fd < 0) {
throw std::system_error(errno, std::system_category());
{
char fn[PATH_MAX];
snprintf(fn, sizeof(fn), "%s/type", data_path.c_str());
- int fd = ::open(fn, O_RDONLY);
+ int fd = ::open(fn, O_RDONLY|O_CLOEXEC);
if (fd >= 0) {
bufferlist bl;
bl.read_fd(fd, 64);
if (cfuse->fino_snap(parent) == CEPH_SNAPDIR &&
fuse_multithreaded && fuse_syncfs_on_mksnap) {
int err = 0;
- int fd = ::open(cfuse->mountpoint, O_RDONLY | O_DIRECTORY);
+ int fd = ::open(cfuse->mountpoint, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
if (fd < 0) {
err = errno;
} else {
perf_counters.cc
perf_histogram.cc
pick_address.cc
- pipe.c
reverse.c
run_cmd.cc
scrub_types.cc
if (is_healthy()) {
string path = m_cct->_conf->heartbeat_file;
if (path.length()) {
- int fd = ::open(path.c_str(), O_WRONLY|O_CREAT, 0644);
+ int fd = ::open(path.c_str(), O_WRONLY|O_CREAT|O_CLOEXEC, 0644);
if (fd >= 0) {
::utimes(path.c_str(), NULL);
::close(fd);
#include "common/OutputDataSocket.h"
#include "common/errno.h"
-#include "common/pipe.h"
#include "common/safe_io.h"
#include "include/compat.h"
+#include "include/sock_compat.h"
#include <poll.h>
#include <sys/un.h>
std::string OutputDataSocket::create_shutdown_pipe(int *pipe_rd, int *pipe_wr)
{
int pipefd[2];
- int ret = pipe_cloexec(pipefd);
- if (ret < 0) {
+ if (pipe_cloexec(pipefd) < 0) {
+ int e = errno;
ostringstream oss;
- oss << "OutputDataSocket::create_shutdown_pipe error: " << cpp_strerror(ret);
+ oss << "OutputDataSocket::create_shutdown_pipe error: " << cpp_strerror(e);
return oss.str();
}
<< (sizeof(address.sun_path) - 1);
return oss.str();
}
- int sock_fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ int sock_fd = socket_cloexec(PF_UNIX, SOCK_STREAM, 0);
if (sock_fd < 0) {
int err = errno;
ostringstream oss;
<< "failed to create socket: " << cpp_strerror(err);
return oss.str();
}
- int r = fcntl(sock_fd, F_SETFD, FD_CLOEXEC);
- if (r < 0) {
- r = errno;
- VOID_TEMP_FAILURE_RETRY(::close(sock_fd));
- ostringstream oss;
- oss << "OutputDataSocket::bind_and_listen: failed to fcntl on socket: " << cpp_strerror(r);
- return oss.str();
- }
memset(&address, 0, sizeof(struct sockaddr_un));
address.sun_family = AF_UNIX;
snprintf(address.sun_path, sizeof(address.sun_path),
struct sockaddr_un address;
socklen_t address_length = sizeof(address);
ldout(m_cct, 30) << "OutputDataSocket: calling accept" << dendl;
- int connection_fd = accept(m_sock_fd, (struct sockaddr*) &address,
+ int connection_fd = accept_cloexec(m_sock_fd, (struct sockaddr*) &address,
&address_length);
- ldout(m_cct, 30) << "OutputDataSocket: finished accept" << dendl;
if (connection_fd < 0) {
int err = errno;
lderr(m_cct) << "OutputDataSocket: do_accept error: '"
<< cpp_strerror(err) << dendl;
return false;
}
+ ldout(m_cct, 30) << "OutputDataSocket: finished accept" << dendl;
handle_connection(connection_fd);
close_connection(connection_fd);
#include <unistd.h>
#include <sstream>
-#include "include/ceph_assert.h"
-#include "common/safe_io.h"
#include "common/errno.h"
+#include "common/safe_io.h"
+#include "include/ceph_assert.h"
+#include "include/compat.h"
+#include "include/sock_compat.h"
/**
* pre-fork fork/daemonize helper class
int prefork(std::string &err) {
ceph_assert(!forked);
- int r = ::socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
std::ostringstream oss;
+ int r = socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, fd);
if (r < 0) {
- oss << "[" << getpid() << "]: unable to create socketpair: " << cpp_strerror(errno);
+ int e = errno;
+ oss << "[" << getpid() << "]: unable to create socketpair: " << cpp_strerror(e);
err = oss.str();
- return r;
+ return (errno = e, -1);
}
forked = true;
childpid = fork();
if (childpid < 0) {
- r = -errno;
- oss << "[" << getpid() << "]: unable to fork: " << cpp_strerror(errno);
+ int e = errno;
+ oss << "[" << getpid() << "]: unable to fork: " << cpp_strerror(e);
err = oss.str();
- return r;
+ return (errno = e, -1);
}
if (is_child()) {
::close(fd[0]);
#include <signal.h>
#endif
#include <stdarg.h>
+#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include "common/errno.h"
#include "include/ceph_assert.h"
+#include "include/compat.h"
SubProcess::SubProcess(const char *cmd_, std_fd_op stdin_op_, std_fd_op stdout_op_, std_fd_op stderr_op_) :
cmd(cmd_),
int ret = 0;
- if ((stdin_op == PIPE && ::pipe(ipipe) == -1) ||
- (stdout_op == PIPE && ::pipe(opipe) == -1) ||
- (stderr_op == PIPE && ::pipe(epipe) == -1)) {
+ if ((stdin_op == PIPE && pipe_cloexec(ipipe) == -1) ||
+ (stdout_op == PIPE && pipe_cloexec(opipe) == -1) ||
+ (stderr_op == PIPE && pipe_cloexec(epipe) == -1)) {
ret = -errno;
errstr << "pipe failed: " << cpp_strerror(errno);
goto fail;
close(opipe[IN ]);
close(epipe[IN ]);
- if (ipipe[IN] != -1 && ipipe[IN] != STDIN_FILENO) {
- ::dup2(ipipe[IN], STDIN_FILENO);
- close(ipipe[IN]);
+ if (ipipe[IN] >= 0) {
+ if (ipipe[IN] == STDIN_FILENO) {
+ ::fcntl(STDIN_FILENO, F_SETFD, 0); /* clear FD_CLOEXEC */
+ } else {
+ ::dup2(ipipe[IN], STDIN_FILENO);
+ ::close(ipipe[IN]);
+ }
}
- if (opipe[OUT] != -1 && opipe[OUT] != STDOUT_FILENO) {
- ::dup2(opipe[OUT], STDOUT_FILENO);
- close(opipe[OUT]);
- static fd_buf buf(STDOUT_FILENO);
- std::cout.rdbuf(&buf);
+ if (opipe[OUT] >= 0) {
+ if (opipe[OUT] == STDOUT_FILENO) {
+ ::fcntl(STDOUT_FILENO, F_SETFD, 0); /* clear FD_CLOEXEC */
+ } else {
+ ::dup2(opipe[OUT], STDOUT_FILENO);
+ ::close(opipe[OUT]);
+ static fd_buf buf(STDOUT_FILENO);
+ std::cout.rdbuf(&buf);
+ }
}
- if (epipe[OUT] != -1 && epipe[OUT] != STDERR_FILENO) {
- ::dup2(epipe[OUT], STDERR_FILENO);
- close(epipe[OUT]);
- static fd_buf buf(STDERR_FILENO);
- std::cerr.rdbuf(&buf);
+ if (epipe[OUT] >= 0) {
+ if (epipe[OUT] == STDERR_FILENO) {
+ ::fcntl(STDERR_FILENO, F_SETFD, 0); /* clear FD_CLOEXEC */
+ } else {
+ ::dup2(epipe[OUT], STDERR_FILENO);
+ ::close(epipe[OUT]);
+ static fd_buf buf(STDERR_FILENO);
+ std::cerr.rdbuf(&buf);
+ }
}
int maxfd = sysconf(_SC_OPEN_MAX);
#include "common/admin_socket_client.h"
#include "common/dout.h"
#include "common/errno.h"
-#include "common/pipe.h"
#include "common/safe_io.h"
#include "common/Thread.h"
#include "common/version.h"
// re-include our assert to clobber the system one; fix dout:
#include "include/ceph_assert.h"
+#include "include/compat.h"
+#include "include/sock_compat.h"
#define dout_subsys ceph_subsys_asok
#undef dout_prefix
std::string AdminSocket::create_shutdown_pipe(int *pipe_rd, int *pipe_wr)
{
int pipefd[2];
- int ret = pipe_cloexec(pipefd);
- if (ret < 0) {
+ if (pipe_cloexec(pipefd) < 0) {
+ int e = errno;
ostringstream oss;
- oss << "AdminSocket::create_shutdown_pipe error: " << cpp_strerror(ret);
+ oss << "AdminSocket::create_shutdown_pipe error: " << cpp_strerror(e);
return oss.str();
}
<< (sizeof(address.sun_path) - 1);
return oss.str();
}
- int sock_fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ int sock_fd = socket_cloexec(PF_UNIX, SOCK_STREAM, 0);
if (sock_fd < 0) {
int err = errno;
ostringstream oss;
<< "failed to create socket: " << cpp_strerror(err);
return oss.str();
}
- int r = fcntl(sock_fd, F_SETFD, FD_CLOEXEC);
- if (r < 0) {
- r = errno;
- retry_sys_call(::close, sock_fd);
- ostringstream oss;
- oss << "AdminSocket::bind_and_listen: failed to fcntl on socket: " << cpp_strerror(r);
- return oss.str();
- }
memset(&address, 0, sizeof(struct sockaddr_un));
address.sun_family = AF_UNIX;
snprintf(address.sun_path, sizeof(address.sun_path),
struct sockaddr_un address;
socklen_t address_length = sizeof(address);
ldout(m_cct, 30) << "AdminSocket: calling accept" << dendl;
- int connection_fd = accept(m_sock_fd, (struct sockaddr*) &address,
+ int connection_fd = accept_cloexec(m_sock_fd, (struct sockaddr*) &address,
&address_length);
- ldout(m_cct, 30) << "AdminSocket: finished accept" << dendl;
if (connection_fd < 0) {
int err = errno;
lderr(m_cct) << "AdminSocket: do_accept error: '"
<< cpp_strerror(err) << dendl;
return false;
}
+ ldout(m_cct, 30) << "AdminSocket: finished accept" << dendl;
char cmd[1024];
unsigned pos = 0;
*/
#include <arpa/inet.h>
+#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "common/safe_io.h"
#include "common/admin_socket_client.h"
+#include "include/compat.h"
+#include "include/sock_compat.h"
+
using std::ostringstream;
const char* get_rand_socket_path()
static std::string asok_connect(const std::string &path, int *fd)
{
- int socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ int socket_fd = socket_cloexec(PF_UNIX, SOCK_STREAM, 0);
if(socket_fd < 0) {
int err = errno;
ostringstream oss;
target[r] = 0;
if (expect == target) {
snprintf(fn, sizeof(fn), "/sys/kvdo/%s/statistics", de->d_name);
- vdo_fd = ::open(fn, O_RDONLY); //DIRECTORY);
+ vdo_fd = ::open(fn, O_RDONLY|O_CLOEXEC); //DIRECTORY);
if (vdo_fd >= 0) {
*vdo_name = de->d_name;
break;
int64_t get_vdo_stat(int vdo_fd, const char *property)
{
int64_t ret = 0;
- int fd = ::openat(vdo_fd, property, O_RDONLY);
+ int fd = ::openat(vdo_fd, property, O_RDONLY|O_CLOEXEC);
if (fd < 0) {
return 0;
}
int buffer::list::read_file(const char *fn, std::string *error)
{
- int fd = TEMP_FAILURE_RETRY(::open(fn, O_RDONLY));
+ int fd = TEMP_FAILURE_RETRY(::open(fn, O_RDONLY|O_CLOEXEC));
if (fd < 0) {
int err = errno;
std::ostringstream oss;
int buffer::list::write_file(const char *fn, int mode)
{
- int fd = TEMP_FAILURE_RETRY(::open(fn, O_WRONLY|O_CREAT|O_TRUNC, mode));
+ int fd = TEMP_FAILURE_RETRY(::open(fn, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, mode));
if (fd < 0) {
int err = errno;
cerr << "bufferlist::write_file(" << fn << "): failed to open file: "
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
-#include <unistd.h>
#include <string.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/param.h>
#include <sys/mount.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
#if defined(__linux__)
#include <sys/vfs.h>
#endif
-#include "include/compat.h"
+#include "include/compat.h"
+#include "include/sock_compat.h"
#include "common/safe_io.h"
// The type-value for a ZFS FS in fstatfs.
#endif
}
+int pipe_cloexec(int pipefd[2])
+{
+#if defined(HAVE_PIPE2)
+ return pipe2(pipefd, O_CLOEXEC);
+#else
+ if (pipe(pipefd) == -1)
+ return -1;
+
+ /*
+ * The old-fashioned, race-condition prone way that we have to fall
+ * back on if pipe2 does not exist.
+ */
+ if (fcntl(pipefd[0], F_SETFD, FD_CLOEXEC) < 0) {
+ goto fail;
+ }
+
+ if (fcntl(pipefd[1], F_SETFD, FD_CLOEXEC) < 0) {
+ goto fail;
+ }
+
+ return 0;
+fail:
+ int save_errno = errno;
+ VOID_TEMP_FAILURE_RETRY(close(pipefd[0]));
+ VOID_TEMP_FAILURE_RETRY(close(pipefd[1]));
+ return (errno = save_errno, -1);
+#endif
+}
+
+
+int socket_cloexec(int domain, int type, int protocol)
+{
+#ifdef SOCK_CLOEXEC
+ return socket(domain, type|SOCK_CLOEXEC, protocol);
+#else
+ int fd = socket(domain, type, protocol);
+ if (fd == -1)
+ return -1;
+
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
+ goto fail;
+
+ return fd;
+fail:
+ int save_errno = errno;
+ VOID_TEMP_FAILURE_RETRY(close(fd));
+ return (errno = save_errno, -1);
+#endif
+}
+
+int socketpair_cloexec(int domain, int type, int protocol, int sv[2])
+{
+#ifdef SOCK_CLOEXEC
+ return socketpair(domain, type|SOCK_CLOEXEC, protocol, sv);
+#else
+ int rc = socketpair(domain, type, protocol, sv);
+ if (rc == -1)
+ return -1;
+
+ if (fcntl(sv[0], F_SETFD, FD_CLOEXEC) < 0)
+ goto fail;
+
+ if (fcntl(sv[1], F_SETFD, FD_CLOEXEC) < 0)
+ goto fail;
+
+ return 0;
+fail:
+ int save_errno = errno;
+ VOID_TEMP_FAILURE_RETRY(close(sv[0]));
+ VOID_TEMP_FAILURE_RETRY(close(sv[1]));
+ return (errno = save_errno, -1);
+#endif
+}
+
+int accept_cloexec(int sockfd, struct sockaddr* addr, socklen_t* addrlen)
+{
+#ifdef HAVE_ACCEPT4
+ return accept4(sockfd, addr, addrlen, SOCK_CLOEXEC);
+#else
+ int fd = accept(sockfd, addr, addrlen);
+ if (fd == -1)
+ return -1;
+
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
+ goto fail;
+
+ return fd;
+fail:
+ int save_errno = errno;
+ VOID_TEMP_FAILURE_RETRY(close(fd));
+ return (errno = save_errno, -1);
+#endif
+}
int ret = -ENOENT;
list<string>::iterator iter;
for (iter = ls.begin(); iter != ls.end(); ++iter) {
- int fd = ::open(iter->c_str(), O_RDONLY);
+ int fd = ::open(iter->c_str(), O_RDONLY|O_CLOEXEC);
if (fd < 0) {
ret = -errno;
continue;
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2011 New Dream Network
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-#include "include/compat.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-int pipe_cloexec(int pipefd[2])
-{
- int ret;
-
-#if defined(HAVE_PIPE2) && defined(O_CLOEXEC)
- ret = pipe2(pipefd, O_CLOEXEC);
- if (ret == -1)
- return -errno;
- return 0;
-#else
- ret = pipe(pipefd);
- if (ret == -1)
- return -errno;
-
- /*
- * The old-fashioned, race-condition prone way that we have to fall
- * back on if O_CLOEXEC does not exist.
- */
- ret = fcntl(pipefd[0], F_SETFD, FD_CLOEXEC);
- if (ret == -1) {
- ret = -errno;
- goto out;
- }
-
- ret = fcntl(pipefd[1], F_SETFD, FD_CLOEXEC);
- if (ret == -1) {
- ret = -errno;
- goto out;
- }
-
- return 0;
-
-out:
- VOID_TEMP_FAILURE_RETRY(close(pipefd[0]));
- VOID_TEMP_FAILURE_RETRY(close(pipefd[1]));
-
- return ret;
-#endif
-}
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2011 New Dream Network
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#ifndef CEPH_COMMON_PIPE_H
-#define CEPH_COMMON_PIPE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Create a pipe and set both ends to have F_CLOEXEC
- *
- * @param pipefd pipe array, just as in pipe(2)
- * @return 0 on success, errno otherwise
- */
-int pipe_cloexec(int pipefd[2]);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
${PROJECT_SOURCE_DIR}/src/common/ceph_strings.cc
${PROJECT_SOURCE_DIR}/src/common/cmdparse.cc
${PROJECT_SOURCE_DIR}/src/common/common_init.cc
+ ${PROJECT_SOURCE_DIR}/src/common/compat.cc
${PROJECT_SOURCE_DIR}/src/common/code_environment.cc
${PROJECT_SOURCE_DIR}/src/common/config.cc
${PROJECT_SOURCE_DIR}/src/common/config_values.cc
${PROJECT_SOURCE_DIR}/src/common/perf_counters.cc
${PROJECT_SOURCE_DIR}/src/common/perf_histogram.cc
${PROJECT_SOURCE_DIR}/src/common/page.cc
- ${PROJECT_SOURCE_DIR}/src/common/pipe.c
${PROJECT_SOURCE_DIR}/src/common/snap_types.cc
${PROJECT_SOURCE_DIR}/src/common/safe_io.c
${PROJECT_SOURCE_DIR}/src/common/signal.cc
int reopen_as_null(CephContext *cct, int fd)
{
- int newfd = open("/dev/null", O_RDONLY);
+ int newfd = open("/dev/null", O_RDONLY|O_CLOEXEC);
if (newfd < 0) {
int err = errno;
lderr(cct) << __func__ << " failed to open /dev/null: " << cpp_strerror(err)
}
// close newfd (we cloned it to target fd)
VOID_TEMP_FAILURE_RETRY(close(newfd));
+ // N.B. FD_CLOEXEC is cleared on fd (see dup2(2))
return 0;
}
return -ENAMETOOLONG;
int fd;
- fd = ::open(pf_path, O_CREAT|O_RDWR, 0644);
+ fd = ::open(pf_path, O_CREAT|O_RDWR|O_CLOEXEC, 0644);
if (fd < 0) {
int err = errno;
derr << __func__ << ": failed to open pid file '"
if (r >= 0) {
char fn[PATH_MAX*2];
snprintf(fn, sizeof(fn)-1, "%s/meta", base);
- int fd = ::open(fn, O_CREAT|O_WRONLY, 0600);
+ int fd = ::open(fn, O_CREAT|O_WRONLY|O_CLOEXEC, 0600);
if (fd >= 0) {
JSONFormatter jf(true);
jf.open_object_section("crash");
}
#if defined(__linux__)
// os-release
- int in = ::open("/etc/os-release", O_RDONLY);
+ int in = ::open("/etc/os-release", O_RDONLY|O_CLOEXEC);
if (in >= 0) {
char buf[4096];
r = safe_read(in, buf, sizeof(buf)-1);
: stop(false), lock("SignalHandler::lock")
{
// create signal pipe
- int r = pipe(pipefd);
+ int r = pipe_cloexec(pipefd);
ceph_assert(r == 0);
r = fcntl(pipefd[0], F_SETFL, O_NONBLOCK);
ceph_assert(r == 0);
safe_handler *h = new safe_handler;
- r = pipe(h->pipefd);
+ r = pipe_cloexec(h->pipefd);
ceph_assert(r == 0);
r = fcntl(h->pipefd[0], F_SETFL, O_NONBLOCK);
ceph_assert(r == 0);
int ceph_posix_fallocate(int fd, off_t offset, off_t len);
+int pipe_cloexec(int pipefd[2]);
+
#endif /* !CEPH_COMPAT_H */
snprintf(fn, sizeof(fn), \
ENCODE_STRINGIFY(ENCODE_DUMP_PATH) "/%s__%d.%x", #Type, \
getpid(), i++); \
- int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT, 0644); \
+ int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT|O_CLOEXEC, 0644); \
if (fd >= 0) { \
size_t len = p.get_pos() - __denc_dump_pre; \
int r = ::write(fd, __denc_dump_pre, len); \
break; \
char fn[PATH_MAX]; \
snprintf(fn, sizeof(fn), ENCODE_STRINGIFY(ENCODE_DUMP_PATH) "/%s__%d.%x", #cl, getpid(), i++); \
- int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT, 0644); \
+ int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT|O_CLOEXEC, 0644); \
if (fd >= 0) { \
::ceph::bufferlist sub; \
sub.substr_of(bl, pre_off, bl.length() - pre_off); \
template <typename MutexT, typename EngineT>
void randomize_rng(MutexT& m, EngineT& e)
{
- thread_local std::random_device rd;
+ std::random_device rd;
std::lock_guard<MutexT> lg(m);
e.seed(rd());
template <typename EngineT = std::default_random_engine>
void randomize_rng()
{
- thread_local std::random_device rd;
+ std::random_device rd;
detail::engine<EngineT>().seed(rd());
}
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ */
+
#ifndef CEPH_SOCK_COMPAT_H
#define CEPH_SOCK_COMPAT_H
#include "include/compat.h"
+#include <sys/socket.h>
/*
* This optimization may not be available on all platforms (e.g. OSX).
# endif
#endif
+int socket_cloexec(int domain, int type, int protocol);
+int socketpair_cloexec(int domain, int type, int protocol, int sv[2]);
+int accept_cloexec(int sockfd, struct sockaddr* addr, socklen_t* addrlen);
+
#endif
*/
#include "encoding.h"
+
#include <ostream>
+#include <random>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
-#include <boost/random/random_device.hpp>
struct uuid_d {
boost::uuids::uuid uuid;
}
void generate_random() {
- boost::random::random_device rng("/dev/urandom");
- boost::uuids::basic_random_generator<boost::random::random_device> gen(&rng);
+ std::random_device rng;
+ boost::uuids::basic_random_generator gen(rng);
uuid = gen();
}
dout(10) << __func__ << " Saving MemDB to file: "<< _get_data_fn().c_str() << dendl;
int mode = 0644;
int fd = TEMP_FAILURE_RETRY(::open(_get_data_fn().c_str(),
- O_WRONLY|O_CREAT|O_TRUNC, mode));
+ O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, mode));
if (fd < 0) {
int err = errno;
cerr << "write_file(" << _get_data_fn().c_str() << "): failed to open file: "
/*
* Open file and read it in single shot.
*/
- int fd = TEMP_FAILURE_RETRY(::open(_get_data_fn().c_str(), O_RDONLY));
+ int fd = TEMP_FAILURE_RETRY(::open(_get_data_fn().c_str(), O_RDONLY|O_CLOEXEC));
if (fd < 0) {
int err = errno;
cerr << "can't open " << _get_data_fn().c_str() << ": "
#include "SubsystemMap.h"
#include <errno.h>
+#include <fcntl.h>
#include <syslog.h>
#include <iostream>
if (m_fd >= 0)
VOID_TEMP_FAILURE_RETRY(::close(m_fd));
if (m_log_file.length()) {
- m_fd = ::open(m_log_file.c_str(), O_CREAT|O_WRONLY|O_APPEND, 0644);
+ m_fd = ::open(m_log_file.c_str(), O_CREAT|O_WRONLY|O_APPEND|O_CLOEXEC, 0644);
if (m_fd >= 0 && (m_uid || m_gid)) {
- int r = ::fchown(m_fd, m_uid, m_gid);
- if (r < 0) {
- r = -errno;
- std::cerr << "failed to chown " << m_log_file << ": " << cpp_strerror(r)
+ if (::fchown(m_fd, m_uid, m_gid) < 0) {
+ int e = errno;
+ std::cerr << "failed to chown " << m_log_file << ": " << cpp_strerror(e)
<< std::endl;
}
}
dout(1) << "dump_cache to " << path << dendl;
- fd = ::open(path, O_WRONLY|O_CREAT|O_EXCL, 0600);
+ fd = ::open(path, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0600);
if (fd < 0) {
derr << "failed to open " << path << ": " << cpp_strerror(errno) << dendl;
return errno;
<< "' logging " << p->second.length() << " bytes" << dendl;
string log_file = channels.get_log_file(p->first);
- int fd = ::open(log_file.c_str(), O_WRONLY|O_APPEND|O_CREAT, 0600);
+ int fd = ::open(log_file.c_str(), O_WRONLY|O_APPEND|O_CREAT|O_CLOEXEC, 0600);
if (fd < 0) {
int err = -errno;
dout(1) << "unable to write to '" << log_file << "' for channel '"
os << g_conf()->mon_data << "/keyring";
int err = 0;
- int fd = ::open(os.str().c_str(), O_WRONLY|O_CREAT, 0600);
+ int fd = ::open(os.str().c_str(), O_WRONLY|O_CREAT|O_CLOEXEC, 0600);
if (fd < 0) {
err = -errno;
dout(0) << __func__ << " failed to open " << os.str()
if (!g_conf()->mon_debug_dump_json) {
dump_fd_binary = ::open(
g_conf()->mon_debug_dump_location.c_str(),
- O_CREAT|O_APPEND|O_WRONLY, 0644);
+ O_CREAT|O_APPEND|O_WRONLY|O_CLOEXEC, 0644);
if (dump_fd_binary < 0) {
dump_fd_binary = -errno;
derr << "Could not open log file, got "
snprintf(fn, sizeof(fn), ENCODE_STRINGIFY(ENCODE_DUMP) "/%s__%d.%x",
abi::__cxa_demangle(typeid(*this).name(), 0, 0, &status),
getpid(), i++);
- int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT, 0644);
+ int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT|O_CLOEXEC, 0644);
if (fd >= 0) {
bl.write_fd(fd);
::close(fd);
*
*/
+#include "include/compat.h"
#include "common/errno.h"
#include "Event.h"
return 0;
int fds[2];
- if (pipe(fds) < 0) {
- lderr(cct) << __func__ << " can't create notify pipe" << dendl;
- return -errno;
+ if (pipe_cloexec(fds) < 0) {
+ int e = errno;
+ lderr(cct) << __func__ << " can't create notify pipe: " << cpp_strerror(e) << dendl;
+ return -e;
}
notify_receive_fd = fds[0];
*/
#include "common/errno.h"
+#include <fcntl.h>
#include "EventEpoll.h"
#define dout_subsys ceph_subsys_ms
<< cpp_strerror(errno) << dendl;
return -errno;
}
+ if (::fcntl(epfd, F_SETFD, FD_CLOEXEC) == -1) {
+ int e = errno;
+ ::close(epfd);
+ lderr(cct) << __func__ << " unable to set cloexec: "
+ << cpp_strerror(e) << dendl;
+
+ return -e;
+ }
size = nevent;
#include "common/strtol.h"
#include "common/dout.h"
#include "msg/Messenger.h"
+#include "include/compat.h"
#include "include/sock_compat.h"
#define dout_subsys ceph_subsys_ms
ceph_assert(sock);
sockaddr_storage ss;
socklen_t slen = sizeof(ss);
- int sd = ::accept(_fd, (sockaddr*)&ss, &slen);
+ int sd = accept_cloexec(_fd, (sockaddr*)&ss, &slen);
if (sd < 0) {
return -errno;
}
- handler.set_close_on_exec(sd);
int r = handler.set_nonblock(sd);
if (r < 0) {
::close(sd);
return -errno;
}
- net.set_close_on_exec(listen_sd);
r = net.set_socket_options(listen_sd, opt.nodelay, opt.rcbuf_size);
if (r < 0) {
::close(listen_sd);
#include <arpa/inet.h>
#include "net_handler.h"
-#include "common/errno.h"
#include "common/debug.h"
+#include "common/errno.h"
+#include "include/compat.h"
+#include "include/sock_compat.h"
#define dout_subsys ceph_subsys_ms
#undef dout_prefix
int s;
int r = 0;
- if ((s = ::socket(domain, SOCK_STREAM, 0)) == -1) {
+ if ((s = socket_cloexec(domain, SOCK_STREAM, 0)) == -1) {
r = errno;
lderr(cct) << __func__ << " couldn't create socket " << cpp_strerror(r) << dendl;
return -r;
return 0;
}
-void NetHandler::set_close_on_exec(int sd)
-{
- int flags = fcntl(sd, F_GETFD, 0);
- if (flags < 0) {
- int r = errno;
- lderr(cct) << __func__ << " fcntl(F_GETFD): "
- << cpp_strerror(r) << dendl;
- return;
- }
- if (fcntl(sd, F_SETFD, flags | FD_CLOEXEC)) {
- int r = errno;
- lderr(cct) << __func__ << " fcntl(F_SETFD): "
- << cpp_strerror(r) << dendl;
- }
-}
-
int NetHandler::set_socket_options(int sd, bool nodelay, int size)
{
int r = 0;
int create_socket(int domain, bool reuse_addr=false);
explicit NetHandler(CephContext *c): cct(c) {}
int set_nonblock(int sd);
- void set_close_on_exec(int sd);
int set_socket_options(int sd, bool nodelay, int size);
int connect(const entity_addr_t &addr, const entity_addr_t& bind_addr);
if (tcp_fd < 0) {
return -errno;
}
- net.set_close_on_exec(tcp_fd);
int r = net.set_socket_options(tcp_fd, opts.nodelay, opts.rcbuf_size);
if (r < 0) {
#include "msg/async/net_handler.h"
#include "RDMAStack.h"
+#include "include/compat.h"
+#include "include/sock_compat.h"
+
#define dout_subsys ceph_subsys_ms
#undef dout_prefix
#define dout_prefix *_dout << " RDMAServerSocketImpl "
if (rc < 0) {
goto err;
}
- net.set_close_on_exec(server_setup_socket);
rc = ::bind(server_setup_socket, sa.get_sockaddr(), sa.get_sockaddr_len());
if (rc < 0) {
sockaddr_storage ss;
socklen_t slen = sizeof(ss);
- int sd = ::accept(server_setup_socket, (sockaddr*)&ss, &slen);
+ int sd = accept_cloexec(server_setup_socket, (sockaddr*)&ss, &slen);
if (sd < 0) {
return -errno;
}
- net.set_close_on_exec(sd);
int r = net.set_nonblock(sd);
if (r < 0) {
::close(sd);
*/
#include "include/compat.h"
+#include "include/sock_compat.h"
#include <iterator>
#include <sys/socket.h>
#include <netinet/tcp.h>
* Accepter
*/
-static int set_close_on_exec(int fd)
-{
- int flags = fcntl(fd, F_GETFD, 0);
- if (flags < 0) {
- return errno;
- }
- if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC)) {
- return errno;
- }
- return 0;
-}
-
int Accepter::create_selfpipe(int *pipe_rd, int *pipe_wr) {
int selfpipe[2];
-#ifdef HAVE_PIPE2
- int ret = ::pipe2(selfpipe, (O_CLOEXEC|O_NONBLOCK));
-#else
- int ret = ::pipe(selfpipe);
- if (ret == 0) {
- for (size_t i = 0; i < std::size(selfpipe); i++) {
- int f = fcntl(selfpipe[i], F_GETFL);
- ceph_assert(f != -1);
- f = fcntl(selfpipe[i], F_SETFL, f | O_NONBLOCK);
- ceph_assert(f != -1);
- }
- }
-#endif
- if (ret < 0 ) {
+ if (pipe_cloexec(selfpipe) < 0) {
+ int e = errno;
lderr(msgr->cct) << __func__ << " unable to create the selfpipe: "
- << cpp_strerror(errno) << dendl;
- return -errno;
+ << cpp_strerror(e) << dendl;
+ return -e;
+ }
+ for (size_t i = 0; i < std::size(selfpipe); i++) {
+ int rc = fcntl(selfpipe[i], F_GETFL);
+ ceph_assert(rc != -1);
+ rc = fcntl(selfpipe[i], F_SETFL, rc | O_NONBLOCK);
+ ceph_assert(rc != -1);
}
*pipe_rd = selfpipe[0];
*pipe_wr = selfpipe[1];
}
/* socket creation */
- listen_sd = ::socket(family, SOCK_STREAM, 0);
- ldout(msgr->cct,10) << __func__ << " socket sd: " << listen_sd << dendl;
+ listen_sd = socket_cloexec(family, SOCK_STREAM, 0);
if (listen_sd < 0) {
+ int e = errno;
lderr(msgr->cct) << __func__ << " unable to create socket: "
- << cpp_strerror(errno) << dendl;
- return -errno;
- }
-
- if (set_close_on_exec(listen_sd)) {
- lderr(msgr->cct) << __func__ << " unable to set_close_exec(): "
- << cpp_strerror(errno) << dendl;
+ << cpp_strerror(e) << dendl;
+ return -e;
}
-
+ ldout(msgr->cct,10) << __func__ << " socket sd: " << listen_sd << dendl;
// use whatever user specified (if anything)
entity_addr_t listen_addr = bind_addr;
// accept
sockaddr_storage ss;
socklen_t slen = sizeof(ss);
- int sd = ::accept(listen_sd, (sockaddr*)&ss, &slen);
+ int sd = accept_cloexec(listen_sd, (sockaddr*)&ss, &slen);
if (sd >= 0) {
- int r = set_close_on_exec(sd);
- if (r) {
- ldout(msgr->cct,1) << __func__ << " set_close_on_exec() failed "
- << cpp_strerror(r) << dendl;
- }
errors = 0;
ldout(msgr->cct,10) << __func__ << " incoming on sd " << sd << dendl;
msgr->add_accept_pipe(sd);
} else {
+ int e = errno;
ldout(msgr->cct,0) << __func__ << " no incoming connection? sd = " << sd
- << " errno " << errno << " " << cpp_strerror(errno) << dendl;
+ << " errno " << e << " " << cpp_strerror(e) << dendl;
if (++errors > msgr->cct->_conf->ms_max_accept_failures) {
lderr(msgr->cct) << "accetper has encoutered enough errors, just do ceph_abort()." << dendl;
ceph_abort();
#include "auth/cephx/CephxProtocol.h"
#include "auth/AuthSessionHandler.h"
+#include "include/compat.h"
#include "include/sock_compat.h"
#include "include/random.h"
::close(sd);
// create socket?
- sd = ::socket(peer_addr.get_family(), SOCK_STREAM, 0);
+ sd = socket_cloexec(peer_addr.get_family(), SOCK_STREAM, 0);
if (sd < 0) {
- rc = -errno;
- lderr(msgr->cct) << "connect couldn't create socket " << cpp_strerror(rc) << dendl;
+ int e = errno;
+ lderr(msgr->cct) << "connect couldn't create socket " << cpp_strerror(e) << dendl;
+ rc = -e;
goto fail;
}
return -EINVAL;
}
ceph_assert(path_fd < 0);
- path_fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_DIRECTORY));
+ path_fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_DIRECTORY|O_CLOEXEC));
if (path_fd < 0) {
int r = -errno;
derr << __func__ << " unable to open " << path << ": " << cpp_strerror(r)
z.zero();
bl.append(std::move(z));
- int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_WRONLY));
+ int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_WRONLY|O_CLOEXEC));
if (fd < 0) {
fd = -errno;
derr << __func__ << " failed to open " << path << ": " << cpp_strerror(fd)
bluestore_bdev_label_t *label)
{
dout(10) << __func__ << dendl;
- int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_RDONLY));
+ int fd = TEMP_FAILURE_RETRY(::open(path.c_str(), O_RDONLY|O_CLOEXEC));
if (fd < 0) {
fd = -errno;
derr << __func__ << " failed to open " << path << ": " << cpp_strerror(fd)
int BlueStore::_open_fsid(bool create)
{
ceph_assert(fsid_fd < 0);
- int flags = O_RDWR;
+ int flags = O_RDWR|O_CLOEXEC;
if (create)
flags |= O_CREAT;
fsid_fd = ::openat(path_fd, "fsid", flags, 0644);
dout(20) << __func__ << " name " << name << " path " << epath
<< " size " << size << " create=" << (int)create << dendl;
int r = 0;
- int flags = O_RDWR;
+ int flags = O_RDWR|O_CLOEXEC;
if (create)
flags |= O_CREAT;
if (epath.length()) {
int r = 0;
dout(1) << __func__ << " path " << path << dendl;
- fd_direct = ::open(path.c_str(), O_RDWR | O_DIRECT);
+ fd_direct = ::open(path.c_str(), O_RDWR | O_DIRECT | O_CLOEXEC);
if (fd_direct < 0) {
r = -errno;
derr << __func__ << " open got: " << cpp_strerror(r) << dendl;
return r;
}
- fd_buffered = ::open(path.c_str(), O_RDWR);
+ fd_buffered = ::open(path.c_str(), O_RDWR | O_CLOEXEC);
if (fd_buffered < 0) {
r = -errno;
derr << __func__ << " open got: " << cpp_strerror(r) << dendl;
dout(1) << __func__ << " path " << p << dendl;
string serial_number;
- int fd = ::open(p.c_str(), O_RDONLY);
+ int fd = ::open(p.c_str(), O_RDONLY | O_CLOEXEC);
if (fd < 0) {
r = -errno;
derr << __func__ << " unable to open " << p << ": " << cpp_strerror(r)
int r = 0;
dout(1) << __func__ << " path " << path << dendl;
- fd = ::open(path.c_str(), O_RDWR);
+ fd = ::open(path.c_str(), O_RDWR | O_CLOEXEC);
if (fd < 0) {
r = -errno;
derr << __func__ << " open got: " << cpp_strerror(r) << dendl;
v += "]\nkey = " + i->second;
}
v += "\n";
- int fd = ::open(p.c_str(), O_CREAT|O_TRUNC|O_WRONLY, 0600);
+ int fd = ::open(p.c_str(), O_CREAT|O_TRUNC|O_WRONLY|O_CLOEXEC, 0600);
if (fd < 0) {
cerr << "error writing " << p << ": " << cpp_strerror(errno)
<< std::endl;
exit(EXIT_FAILURE);
}
string path = out_dir + "/" + dir + "/" + file;
- int fd = ::open(path.c_str(), O_CREAT|O_WRONLY|O_TRUNC, 0644);
+ int fd = ::open(path.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC, 0644);
if (fd < 0) {
r = -errno;
cerr << "open " << path << " failed: " << cpp_strerror(r) << std::endl;
// clone_range?
if (m_filestore_btrfs_clone_range) {
- int fd = ::openat(get_basedir_fd(), "clone_range_test", O_CREAT|O_WRONLY, 0600);
+ int fd = ::openat(get_basedir_fd(), "clone_range_test", O_CREAT|O_WRONLY|O_CLOEXEC, 0600);
if (fd >= 0) {
if (::unlinkat(get_basedir_fd(), "clone_range_test", 0) < 0) {
r = -errno;
r = -errno;
dout(0) << "detect_feature: failed to create simple subvolume " << vol_args.name << ": " << cpp_strerror(r) << dendl;
}
- int srcfd = ::openat(get_basedir_fd(), vol_args.name, O_RDONLY);
+ int srcfd = ::openat(get_basedir_fd(), vol_args.name, O_RDONLY|O_CLOEXEC);
if (srcfd < 0) {
r = -errno;
dout(0) << "detect_feature: failed to open " << vol_args.name << ": " << cpp_strerror(r) << dendl;
snprintf(s, sizeof(s), "%s/%s", get_basedir_path().c_str(), name.c_str());
// roll back
- vol_args.fd = ::open(s, O_RDONLY);
+ vol_args.fd = ::open(s, O_RDONLY|O_CLOEXEC);
if (vol_args.fd < 0) {
ret = -errno;
dout(0) << "rollback_to: error opening '" << s << "': " << cpp_strerror(ret) << dendl;
<< cpp_strerror(err) << dendl;
}
}
- fd = TEMP_FAILURE_RETRY(::open(fn.c_str(), flags, 0644));
+ fd = TEMP_FAILURE_RETRY(::open(fn.c_str(), flags|O_CLOEXEC, 0644));
if (fd < 0) {
int err = errno;
dout(2) << "FileJournal::_open unable to open journal "
goto fail;
}
- r = ::open((*path)->path(), flags, 0644);
+ r = ::open((*path)->path(), flags|O_CLOEXEC, 0644);
if (r < 0) {
r = -errno;
dout(10) << "error opening file " << (*path)->path() << " with flags="
uuid_d old_omap_fsid;
dout(1) << "mkfs in " << basedir << dendl;
- basedir_fd = ::open(basedir.c_str(), O_RDONLY);
+ basedir_fd = ::open(basedir.c_str(), O_RDONLY|O_CLOEXEC);
if (basedir_fd < 0) {
ret = -errno;
derr << __FUNC__ << ": failed to open base dir " << basedir << ": " << cpp_strerror(ret) << dendl;
// open+lock fsid
snprintf(fsid_fn, sizeof(fsid_fn), "%s/fsid", basedir.c_str());
- fsid_fd = ::open(fsid_fn, O_RDWR|O_CREAT, 0644);
+ fsid_fd = ::open(fsid_fn, O_RDWR|O_CREAT|O_CLOEXEC, 0644);
if (fsid_fd < 0) {
ret = -errno;
derr << __FUNC__ << ": failed to open " << fsid_fn << ": " << cpp_strerror(ret) << dendl;
if (backend->can_checkpoint()) {
// create snap_1 too
- current_fd = ::open(current_fn.c_str(), O_RDONLY);
+ current_fd = ::open(current_fn.c_str(), O_RDONLY|O_CLOEXEC);
ceph_assert(current_fd >= 0);
char s[NAME_MAX];
snprintf(s, sizeof(s), COMMIT_SNAP_ITEM, 1ull);
int omap_fsid_fd;
char omap_fsid_fn[PATH_MAX];
snprintf(omap_fsid_fn, sizeof(omap_fsid_fn), "%s/osd_uuid", omap_dir.c_str());
- omap_fsid_fd = ::open(omap_fsid_fn, O_RDWR|O_CREAT, 0644);
+ omap_fsid_fd = ::open(omap_fsid_fn, O_RDWR|O_CREAT|O_CLOEXEC, 0644);
if (omap_fsid_fd < 0) {
ret = -errno;
derr << __FUNC__ << ": failed to open " << omap_fsid_fn << ": " << cpp_strerror(ret) << dendl;
int ret;
char fn[PATH_MAX];
snprintf(fn, sizeof(fn), "%s/fsid", basedir.c_str());
- int fd = ::open(fn, O_RDONLY, 0644);
+ int fd = ::open(fn, O_RDONLY|O_CLOEXEC, 0644);
if (fd < 0) {
int err = errno;
derr << __FUNC__ << ": open error: " << cpp_strerror(err) << dendl;
// verify fs isn't in use
- fsid_fd = ::open(fn, O_RDWR, 0644);
+ fsid_fd = ::open(fn, O_RDWR|O_CLOEXEC, 0644);
if (fsid_fd < 0)
return 0; // no fsid, ok.
bool inuse = lock_fsid() < 0;
if (backend) {
rotational = backend->is_rotational();
} else {
- int fd = ::open(basedir.c_str(), O_RDONLY);
+ int fd = ::open(basedir.c_str(), O_RDONLY|O_CLOEXEC);
if (fd < 0)
return true;
struct statfs st;
if (backend) {
journal_rotational = backend->is_journal_rotational();
} else {
- int fd = ::open(journalpath.c_str(), O_RDONLY);
+ int fd = ::open(journalpath.c_str(), O_RDONLY|O_CLOEXEC);
if (fd < 0)
return true;
struct statfs st;
int x = rand();
int y = x+1;
snprintf(fn, sizeof(fn), "%s/xattr_test", basedir.c_str());
- int tmpfd = ::open(fn, O_CREAT|O_WRONLY|O_TRUNC, 0700);
+ int tmpfd = ::open(fn, O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC, 0700);
if (tmpfd < 0) {
int ret = -errno;
derr << __FUNC__ << ": unable to create " << fn << ": " << cpp_strerror(ret) << dendl;
int FileStore::read_op_seq(uint64_t *seq)
{
- int op_fd = ::open(current_op_seq_fn.c_str(), O_CREAT|O_RDWR, 0644);
+ int op_fd = ::open(current_op_seq_fn.c_str(), O_CREAT|O_RDWR|O_CLOEXEC, 0644);
if (op_fd < 0) {
int r = -errno;
ceph_assert(!m_filestore_fail_eio || r != -EIO);
// get fsid
snprintf(buf, sizeof(buf), "%s/fsid", basedir.c_str());
- fsid_fd = ::open(buf, O_RDWR, 0644);
+ fsid_fd = ::open(buf, O_RDWR|O_CLOEXEC, 0644);
if (fsid_fd < 0) {
ret = -errno;
derr << __FUNC__ << ": error opening '" << buf << "': "
}
// open some dir handles
- basedir_fd = ::open(basedir.c_str(), O_RDONLY);
+ basedir_fd = ::open(basedir.c_str(), O_RDONLY|O_CLOEXEC);
if (basedir_fd < 0) {
ret = -errno;
derr << __FUNC__ << ": failed to open " << basedir << ": "
}
initial_op_seq = 0;
- current_fd = ::open(current_fn.c_str(), O_RDONLY);
+ current_fd = ::open(current_fn.c_str(), O_RDONLY|O_CLOEXEC);
if (current_fd < 0) {
ret = -errno;
derr << __FUNC__ << ": error opening: " << current_fn << ": " << cpp_strerror(ret) << dendl;
} else {
int omap_fsid_fd;
// if osd_uuid exists, compares osd_uuid with fsid
- omap_fsid_fd = ::open(omap_fsid_buf, O_RDONLY, 0644);
+ omap_fsid_fd = ::open(omap_fsid_buf, O_RDONLY|O_CLOEXEC, 0644);
if (omap_fsid_fd < 0) {
ret = -errno;
derr << __FUNC__ << ": error opening '" << omap_fsid_buf << "': "
char fn[PATH_MAX];
get_cdir(cid, fn, sizeof(fn));
- int fd = ::open(fn, O_RDONLY);
+ int fd = ::open(fn, O_RDONLY|O_CLOEXEC);
if (fd < 0) {
int err = errno;
derr << __FUNC__ << ": " << cid << " error " << cpp_strerror(err) << dendl;
{
char fn[PATH_MAX];
get_cdir(cid, fn, sizeof(fn));
- int fd = ::open(fn, O_RDONLY);
+ int fd = ::open(fn, O_RDONLY|O_CLOEXEC);
if (fd < 0) {
dout(10) << __FUNC__ << ": " << cid << " dne" << dendl;
return 1; // if collection does not exist, there is no guard, and we can replay.
{
char fn[PATH_MAX];
get_cdir(cid, fn, sizeof(fn));
- int fd = ::open(fn, O_RDONLY);
+ int fd = ::open(fn, O_RDONLY|O_CLOEXEC);
if (fd < 0) {
int err = errno;
derr << __FUNC__ << ": " << cid << " error " << cpp_strerror(err) << dendl;
{
char fn[PATH_MAX];
get_cdir(cid, fn, sizeof(fn));
- int fd = ::open(fn, O_RDONLY);
+ int fd = ::open(fn, O_RDONLY|O_CLOEXEC);
if (fd < 0) {
int err = errno;
derr << __FUNC__ << ": " << cid << " error " << cpp_strerror(err) << dendl;
char fn[PATH_MAX];
get_cdir(cid, fn, sizeof(fn));
- int fd = ::open(fn, O_RDONLY);
+ int fd = ::open(fn, O_RDONLY|O_CLOEXEC);
if (fd < 0) {
dout(10) << __FUNC__ << ": " << cid << " dne" << dendl;
return 1; // if collection does not exist, there is no guard, and we can replay.
#ifdef CEPH_HAVE_SPLICE
if (backend->has_splice()) {
int pipefd[2];
- if (pipe(pipefd) < 0) {
- r = -errno;
- derr << " pipe " << " got " << cpp_strerror(r) << dendl;
- return r;
+ if (pipe_cloexec(pipefd) < 0) {
+ int e = errno;
+ derr << " pipe " << " got " << cpp_strerror(e) << dendl;
+ return -e;
}
loff_t dstpos = dstoff;
char n[PATH_MAX];
int r;
int32_t v = bits;
- int fd = ::open(fn, O_RDONLY);
+ int fd = ::open(fn, O_RDONLY|O_CLOEXEC);
if (fd < 0) {
r = -errno;
goto out;
int r;
char n[PATH_MAX];
int32_t bits;
- int fd = ::open(fn, O_RDONLY);
+ int fd = ::open(fn, O_RDONLY|O_CLOEXEC);
if (fd < 0) {
bits = r = -errno;
goto out;
{
// NOTE: the below won't work on btrfs; we'll assume rotational.
string fn = get_basedir_path();
- int fd = ::open(fn.c_str(), O_RDONLY);
+ int fd = ::open(fn.c_str(), O_RDONLY|O_CLOEXEC);
if (fd < 0) {
return;
}
{
// NOTE: the below won't work on btrfs; we'll assume rotational.
string fn = get_journal_path();
- int fd = ::open(fn.c_str(), O_RDONLY);
+ int fd = ::open(fn.c_str(), O_RDONLY|O_CLOEXEC);
if (fd < 0) {
return;
}
char fn[PATH_MAX];
snprintf(fn, sizeof(fn), "%s/fiemap_test", get_basedir_path().c_str());
- int fd = ::open(fn, O_CREAT|O_RDWR|O_TRUNC, 0644);
+ int fd = ::open(fn, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0644);
if (fd < 0) {
fd = -errno;
derr << "detect_features: unable to create " << fn << ": " << cpp_strerror(fd) << dendl;
int pipefd[2];
loff_t off_in = 0;
int r;
- if ((r = pipe(pipefd)) < 0)
- dout(0) << "detect_features: splice pipe met error " << cpp_strerror(errno) << dendl;
- else {
+ if (pipe_cloexec(pipefd) < 0) {
+ int e = errno;
+ dout(0) << "detect_features: splice pipe met error " << cpp_strerror(e) << dendl;
+ } else {
lseek(fd, 0, SEEK_SET);
r = splice(fd, &off_in, pipefd[1], NULL, 10, 0);
if (!(r < 0 && errno == EINVAL)) {
int LFNIndex::fsync_dir(const vector<string> &path)
{
maybe_inject_failure();
- int fd = ::open(get_full_path_subdir(path).c_str(), O_RDONLY);
+ int fd = ::open(get_full_path_subdir(path).c_str(), O_RDONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
FDCloser f(fd);
}
}
string full_path = get_full_path(path, mangled_name);
- int fd = ::open(full_path.c_str(), O_RDONLY);
+ int fd = ::open(full_path.c_str(), O_RDONLY|O_CLOEXEC);
if (fd < 0)
return -errno;
FDCloser f(fd);
int KStore::_open_path()
{
ceph_assert(path_fd < 0);
- path_fd = ::open(path.c_str(), O_DIRECTORY);
+ path_fd = ::open(path.c_str(), O_DIRECTORY|O_CLOEXEC);
if (path_fd < 0) {
int r = -errno;
derr << __func__ << " unable to open " << path << ": " << cpp_strerror(r)
// vim: ts=8 sw=2 smarttab
#include "include/compat.h"
+#include "common/errno.h"
#include <boost/utility/string_ref.hpp>
int RGWHTTPManager::start()
{
- int r = pipe(thread_pipe);
- if (r < 0) {
- r = -errno;
- ldout(cct, 0) << "ERROR: pipe() returned errno=" << r << dendl;
- return r;
+ if (pipe_cloexec(thread_pipe) < 0) {
+ int e = errno;
+ ldout(cct, 0) << "ERROR: pipe(): " << cpp_strerror(e) << dendl;
+ return -e;
}
// enable non-blocking reads
- r = ::fcntl(thread_pipe[0], F_SETFL, O_NONBLOCK);
- if (r < 0) {
- r = -errno;
- ldout(cct, 0) << "ERROR: fcntl() returned errno=" << r << dendl;
+ if (::fcntl(thread_pipe[0], F_SETFL, O_NONBLOCK) < 0) {
+ int e = errno;
+ ldout(cct, 0) << "ERROR: fcntl(): " << cpp_strerror(e) << dendl;
TEMP_FAILURE_RETRY(::close(thread_pipe[0]));
TEMP_FAILURE_RETRY(::close(thread_pipe[1]));
- return r;
+ return -e;
}
#ifdef HAVE_CURL_MULTI_WAIT
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
+#include <random>
#include <thread>
#include "global/global_init.h"
#include "common/ceph_argparse.h"
std::unique_ptr<char[]> gen_buffer(uint64_t size)
{
std::unique_ptr<char[]> buffer = std::make_unique<char[]>(size);
- boost::random::random_device rand;
- rand.generate(buffer.get(), buffer.get() + size);
+ std::independent_bits_engine<std::default_random_engine, CHAR_BIT, unsigned char> e;
+ std::generate(buffer.get(), buffer.get()+size, std::ref(e));
return buffer;
}