Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: added the socket_cloexec patch to ensure most of the nginx c…
…onnections could be closed before child process terminates. Signed-off-by: Yichun Zhang (agentzh) <agentzh@gmail.com>
- Loading branch information
1 parent
8d3ce00
commit a4f399b
Showing
2 changed files
with
161 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
diff --git a/auto/unix b/auto/unix | ||
index 10835f6c..b5b33bb3 100644 | ||
--- a/auto/unix | ||
+++ b/auto/unix | ||
@@ -990,3 +990,27 @@ ngx_feature_test='struct addrinfo *res; | ||
if (getaddrinfo("localhost", NULL, NULL, &res) != 0) return 1; | ||
freeaddrinfo(res)' | ||
. auto/feature | ||
+ | ||
+ngx_feature="SOCK_CLOEXEC support" | ||
+ngx_feature_name="NGX_HAVE_SOCKET_CLOEXEC" | ||
+ngx_feature_run=no | ||
+ngx_feature_incs="#include <sys/types.h> | ||
+ #include <sys/socket.h>" | ||
+ngx_feature_path= | ||
+ngx_feature_libs= | ||
+ngx_feature_test="int fd; | ||
+ fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);" | ||
+. auto/feature | ||
+ | ||
+ngx_feature="FD_CLOEXEC support" | ||
+ngx_feature_name="NGX_HAVE_FD_CLOEXEC" | ||
+ngx_feature_run=no | ||
+ngx_feature_incs="#include <sys/types.h> | ||
+ #include <sys/socket.h> | ||
+ #include <fcntl.h>" | ||
+ngx_feature_path= | ||
+ngx_feature_libs= | ||
+ngx_feature_test="int fd; | ||
+ fd = socket(AF_INET, SOCK_STREAM, 0); | ||
+ fcntl(fd, F_SETFD, FD_CLOEXEC);" | ||
+. auto/feature | ||
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c | ||
index cd55520c..438e0806 100644 | ||
--- a/src/core/ngx_resolver.c | ||
+++ b/src/core/ngx_resolver.c | ||
@@ -4466,8 +4466,14 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec) | ||
ngx_event_t *rev, *wev; | ||
ngx_connection_t *c; | ||
|
||
+#if (NGX_HAVE_SOCKET_CLOEXEC) | ||
+ s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0); | ||
+ | ||
+#else | ||
s = ngx_socket(rec->sockaddr->sa_family, SOCK_STREAM, 0); | ||
|
||
+#endif | ||
+ | ||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &rec->log, 0, "TCP socket %d", s); | ||
|
||
if (s == (ngx_socket_t) -1) { | ||
@@ -4494,6 +4500,15 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec) | ||
goto failed; | ||
} | ||
|
||
+#if (NGX_HAVE_FD_CLOEXEC) | ||
+ if (ngx_cloexec(s) == -1) { | ||
+ ngx_log_error(NGX_LOG_ALERT, &rec->log, ngx_socket_errno, | ||
+ ngx_cloexec_n " failed"); | ||
+ | ||
+ goto failed; | ||
+ } | ||
+#endif | ||
+ | ||
rev = c->read; | ||
wev = c->write; | ||
|
||
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c | ||
index 77563709..5827b9d0 100644 | ||
--- a/src/event/ngx_event_accept.c | ||
+++ b/src/event/ngx_event_accept.c | ||
@@ -62,7 +62,9 @@ ngx_event_accept(ngx_event_t *ev) | ||
|
||
#if (NGX_HAVE_ACCEPT4) | ||
if (use_accept4) { | ||
- s = accept4(lc->fd, &sa.sockaddr, &socklen, SOCK_NONBLOCK); | ||
+ s = accept4(lc->fd, &sa.sockaddr, &socklen, | ||
+ SOCK_NONBLOCK | SOCK_CLOEXEC); | ||
+ | ||
} else { | ||
s = accept(lc->fd, &sa.sockaddr, &socklen); | ||
} | ||
@@ -202,6 +204,16 @@ ngx_event_accept(ngx_event_t *ev) | ||
ngx_close_accepted_connection(c); | ||
return; | ||
} | ||
+ | ||
+#if (NGX_HAVE_FD_CLOEXEC) | ||
+ if (ngx_cloexec(s) == -1) { | ||
+ ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, | ||
+ ngx_cloexec_n " failed"); | ||
+ ngx_close_accepted_connection(c); | ||
+ return; | ||
+ } | ||
+#endif | ||
+ | ||
} | ||
} | ||
|
||
diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c | ||
index c5bb8068..cf33b1d2 100644 | ||
--- a/src/event/ngx_event_connect.c | ||
+++ b/src/event/ngx_event_connect.c | ||
@@ -38,8 +38,15 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) | ||
|
||
type = (pc->type ? pc->type : SOCK_STREAM); | ||
|
||
+#if (NGX_HAVE_SOCKET_CLOEXEC) | ||
+ s = ngx_socket(pc->sockaddr->sa_family, type | SOCK_CLOEXEC, 0); | ||
+ | ||
+#else | ||
s = ngx_socket(pc->sockaddr->sa_family, type, 0); | ||
|
||
+#endif | ||
+ | ||
+ | ||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pc->log, 0, "%s socket %d", | ||
(type == SOCK_STREAM) ? "stream" : "dgram", s); | ||
|
||
@@ -80,6 +87,15 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc) | ||
goto failed; | ||
} | ||
|
||
+#if (NGX_HAVE_FD_CLOEXEC) | ||
+ if (ngx_cloexec(s) == -1) { | ||
+ ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, | ||
+ ngx_cloexec_n " failed"); | ||
+ | ||
+ goto failed; | ||
+ } | ||
+#endif | ||
+ | ||
if (pc->local) { | ||
|
||
#if (NGX_HAVE_TRANSPARENT_PROXY) | ||
diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h | ||
index fcc51533..d1eebf47 100644 | ||
--- a/src/os/unix/ngx_socket.h | ||
+++ b/src/os/unix/ngx_socket.h | ||
@@ -38,6 +38,17 @@ int ngx_blocking(ngx_socket_t s); | ||
|
||
#endif | ||
|
||
+#if (NGX_HAVE_FD_CLOEXEC) | ||
+ | ||
+#define ngx_cloexec(s) fcntl(s, F_SETFD, FD_CLOEXEC) | ||
+#define ngx_cloexec_n "fcntl(FD_CLOEXEC)" | ||
+ | ||
+/* at least FD_CLOEXEC is required to ensure connection fd is closed | ||
+ * after execve */ | ||
+#define HAVE_SOCKET_CLOEXEC_PATCH 1 | ||
+ | ||
+#endif | ||
+ | ||
int ngx_tcp_nopush(ngx_socket_t s); | ||
int ngx_tcp_push(ngx_socket_t s); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters