]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
msg/simple: set close on exec on server sockets 9772/head
authorKefu Chai <kchai@redhat.com>
Fri, 17 Jun 2016 05:58:55 +0000 (13:58 +0800)
committerKefu Chai <kchai@redhat.com>
Sat, 2 Jul 2016 04:50:56 +0000 (12:50 +0800)
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>
src/msg/simple/Accepter.cc

index 3d43e27e18143512d52d150f103a7c8bf3b7c385..bce854120b6e98a537c43dde9341974903c3788f 100644 (file)
  * 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<int>& 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<int>& 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;