msg/async: set close on exec on server sockets

mds execv() when handling the "respawn" command, to avoid fd leakage,
and enormous CLOSE_WAIT connections after respawning, we need to set
FD_CLOEXEC flag for the socket fds.

Fixes: http://tracker.ceph.com/issues/16390
Signed-off-by: Kefu Chai <kchai@redhat.com>
This commit is contained in:
Kefu Chai 2016-06-17 01:17:05 +08:00
parent 7eef57c271
commit eaf68c7241
3 changed files with 19 additions and 1 deletions

View File

@ -104,7 +104,7 @@ int Processor::bind(const entity_addr_t &bind_addr, const set<int>& avoid_ports)
listen_sd = -1;
return r;
}
net.set_close_on_exec(listen_sd);
net.set_socket_options(listen_sd);
// use whatever user specified (if anything)
@ -258,6 +258,7 @@ void Processor::accept()
socklen_t slen = sizeof(ss);
int sd = ::accept(listen_sd, (sockaddr*)&ss, &slen);
if (sd >= 0) {
net.set_close_on_exec(sd);
ldout(msgr->cct, 10) << __func__ << " accepted incoming on sd " << sd << dendl;
msgr->add_accept(sd);

View File

@ -73,6 +73,22 @@ int NetHandler::set_nonblock(int sd)
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;
}
}
void NetHandler::set_socket_options(int sd)
{
// disable Nagle algorithm?

View File

@ -28,6 +28,7 @@ namespace ceph {
public:
explicit NetHandler(CephContext *c): cct(c) {}
int set_nonblock(int sd);
void set_close_on_exec(int sd);
void set_socket_options(int sd);
int connect(const entity_addr_t &addr);