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>
listen_sd = -1;
return r;
}
-
+ net.set_close_on_exec(listen_sd);
net.set_socket_options(listen_sd);
// use whatever user specified (if anything)
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);
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?
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);