From 90069ce67b50bdaf0d7f1ba1c53d23eba1cbc39e Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Fri, 17 Jun 2016 13:58:55 +0800 Subject: [PATCH] msg/simple: 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 --- src/msg/simple/Accepter.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/msg/simple/Accepter.cc b/src/msg/simple/Accepter.cc index 3d43e27e181435..bce854120b6e98 100644 --- a/src/msg/simple/Accepter.cc +++ b/src/msg/simple/Accepter.cc @@ -37,6 +37,18 @@ * 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::bind(const entity_addr_t &bind_addr, const set& avoid_ports) { const md_config_t *conf = msgr->cct->_conf; @@ -63,6 +75,11 @@ int Accepter::bind(const entity_addr_t &bind_addr, const set& avoid_ports) return -errno; } + if (set_close_on_exec(listen_sd)) { + lderr(msgr->cct) << "accepter.bind unable to set_close_exec(): " + << cpp_strerror(errno) << dendl; + } + // use whatever user specified (if anything) entity_addr_t listen_addr = bind_addr; listen_addr.set_family(family); @@ -244,6 +261,11 @@ void *Accepter::entry() socklen_t slen = sizeof(ss); int sd = ::accept(listen_sd, (sockaddr*)&ss, &slen); if (sd >= 0) { + int r = set_close_on_exec(sd); + if (r) { + ldout(msgr->cct,0) << "accepter set_close_on_exec() failed " + << cpp_strerror(r) << dendl; + } errors = 0; ldout(msgr->cct,10) << "accepted incoming on sd " << sd << dendl;