| Author |
Message |
< Erlang patches mailing list ~ [PATCH] Exit if an error occurs with the listening socket |
| Guest |
Posted: Sun Mar 21, 2010 1:30 am |
|
|
|
Guest
|
On erlang-questions, there was a thread about epmd consuming 100% CPU
under some conditions:
http://www.erlang.org/cgi-bin/ezmlm-cgi?4:mss:50068:ikpcjohfehcpniapmcfm
Looking through the code for epmd_srv.c, when either select() or accept()
returns an error, errno is not checked. In the case of an error with
the socket, this will cause select/accept to return immediately and loop.
The easiest way of reproducing this situation is by using too many
file descriptors:
http://gist.github.com/338996
In one shell:
$ ulimit -n 16
$ epmd -d -port 1234
In another shell:
$ erl
$ emfile:start(1234,32).
epmd will log many errors and consume CPU:
epmd: Sat Mar 20 20:09:45 2010: error in accept: Too many open files
Since my github fork is "temporarily unavailable", the patch will be
sent separately in git patch format. If the patch needs to be re-worked,
please let me know, and I will do so when my fork is back up.
________________________________________________________________
erlang-patches (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-patches-unsubscribe@erlang.org
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Sun Mar 21, 2010 1:30 am |
|
|
|
Guest
|
On erlang-questions, there was a thread about epmd consuming 100% CPU
under some conditions:
http://www.erlang.org/cgi-bin/ezmlm-cgi?4:mss:50068:ikpcjohfehcpniapmcfm
Looking through the code for epmd_srv.c, when either select() or accept()
returns an error, errno is not checked. In the case of an error with
the socket, this will cause select/accept to return immediately and loop.
The easiest way of reproducing this situation is by using too many
file descriptors:
http://gist.github.com/338996
In one shell:
$ ulimit -n 16
$ epmd -d -port 1234
In another shell:
$ erl
$ emfile:start(1234,32).
epmd will log many errors and consume CPU:
epmd: Sat Mar 20 20:09:45 2010: error in accept: Too many open files
Since my github fork is "temporarily unavailable", the patch will be
sent separately in git patch format. If the patch needs to be re-worked,
please let me know, and I will do so when my fork is back up.
________________________________________________________________
erlang-patches (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-patches-unsubscribe@erlang.org
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Sun Mar 21, 2010 1:31 am |
|
|
|
Guest
|
Check errno if either select() or accept() returns an error and exit.
This prevents epmd from looping and taking up 100% CPU.
---
erts/epmd/src/epmd_srv.c | 19 +++++++++++++++++--
1 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index a033fab..7e4a661 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -227,8 +227,16 @@ void run(EpmdVars *g)
timeout.tv_sec = (g->packet_timeout < IDLE_TIMEOUT) ? 1 : IDLE_TIMEOUT;
timeout.tv_usec = 0;
- if ((ret = select(g->max_conn,&read_mask,(fd_set *)0,(fd_set *)0,&timeout)) < 0)
+ if ((ret = select(g->max_conn,&read_mask,(fd_set *)0,(fd_set *)0,&timeout)) < 0) {
dbg_perror(g,"error in select ");
+ switch (errno) {
+ case EAGAIN:
+ case EINTR:
+ break;
+ default:
+ epmd_cleanup_exit(g,1);
+ }
+ }
else {
time_t now;
if (ret == 0) {
@@ -401,7 +409,14 @@ static int do_accept(EpmdVars *g,int listensock)
if (msgsock < 0) {
dbg_perror(g,"error in accept");
- return EPMD_FALSE;
+ switch (errno) {
+ case EAGAIN:
+ case ECONNABORTED:
+ case EINTR:
+ return EPMD_FALSE;
+ default:
+ epmd_cleanup_exit(g,1);
+ }
}
return conn_open(g,msgsock);
--
1.5.4.3
________________________________________________________________
erlang-patches (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-patches-unsubscribe@erlang.org
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Sun Mar 21, 2010 1:31 am |
|
|
|
Guest
|
Check errno if either select() or accept() returns an error and exit.
This prevents epmd from looping and taking up 100% CPU.
---
erts/epmd/src/epmd_srv.c | 19 +++++++++++++++++--
1 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index a033fab..7e4a661 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -227,8 +227,16 @@ void run(EpmdVars *g)
timeout.tv_sec = (g->packet_timeout < IDLE_TIMEOUT) ? 1 : IDLE_TIMEOUT;
timeout.tv_usec = 0;
- if ((ret = select(g->max_conn,&read_mask,(fd_set *)0,(fd_set *)0,&timeout)) < 0)
+ if ((ret = select(g->max_conn,&read_mask,(fd_set *)0,(fd_set *)0,&timeout)) < 0) {
dbg_perror(g,"error in select ");
+ switch (errno) {
+ case EAGAIN:
+ case EINTR:
+ break;
+ default:
+ epmd_cleanup_exit(g,1);
+ }
+ }
else {
time_t now;
if (ret == 0) {
@@ -401,7 +409,14 @@ static int do_accept(EpmdVars *g,int listensock)
if (msgsock < 0) {
dbg_perror(g,"error in accept");
- return EPMD_FALSE;
+ switch (errno) {
+ case EAGAIN:
+ case ECONNABORTED:
+ case EINTR:
+ return EPMD_FALSE;
+ default:
+ epmd_cleanup_exit(g,1);
+ }
}
return conn_open(g,msgsock);
--
1.5.4.3
________________________________________________________________
erlang-patches (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-patches-unsubscribe@erlang.org
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Tue Mar 30, 2010 1:32 pm |
|
|
|
Guest
|
On Tue, Mar 30, 2010 at 11:58:48AM +0200, Bj??rn Gustavsson wrote:
> 2010/3/22 Bj??rn Gustavsson <bgustavsson@gmail.com>:
> > On Sun, Mar 21, 2010 at 2:30 AM, Michael Santos
> > <michael.santos@gmail.com> wrote:
> >> Check errno if either select() or accept() returns an error and exit.
> >> This prevents epmd from looping and taking up 100% CPU.
> >
> > Thanks! Will include in 'pu'.
>
> I did not build on Windows. I have added an additional
> commit that fixes that. I intend to squash that commit into
> your commit if/when the branch is graduated.
>
> Are there other platforms that don't have ECONNABORTED
> defined?
Yay, I broke the Windows build! Thanks for fixing the patch.
Looking through erts/emulator/drivers/common/inet_drv.c, the only platform
for which ECONNABORTED is explicitly handled is Windows:
#ifdef __WIN32__
#define ECONNABORTED WSAECONNABORTED
#endif /* __WIN32__ */
> diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
> index 7e4a661..83ebdaa 100644
> --- a/erts/epmd/src/epmd_srv.c
> +++ b/erts/epmd/src/epmd_srv.c
> @@ -411,7 +411,9 @@ static int do_accept(EpmdVars *g,int listensock)
> dbg_perror(g,"error in accept");
> switch (errno) {
> case EAGAIN:
> +#ifndef __WIN32__
> case ECONNABORTED:
> +#endif
> case EINTR:
> return EPMD_FALSE;
> default:
________________________________________________________________
erlang-patches (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-patches-unsubscribe@erlang.org
Post received from mailinglist |
|
|
| Back to top |
|
| Guest |
Posted: Tue Mar 30, 2010 1:32 pm |
|
|
|
Guest
|
On Tue, Mar 30, 2010 at 11:58:48AM +0200, Bj??rn Gustavsson wrote:
> 2010/3/22 Bj??rn Gustavsson <bgustavsson@gmail.com>:
> > On Sun, Mar 21, 2010 at 2:30 AM, Michael Santos
> > <michael.santos@gmail.com> wrote:
> >> Check errno if either select() or accept() returns an error and exit.
> >> This prevents epmd from looping and taking up 100% CPU.
> >
> > Thanks! Will include in 'pu'.
>
> I did not build on Windows. I have added an additional
> commit that fixes that. I intend to squash that commit into
> your commit if/when the branch is graduated.
>
> Are there other platforms that don't have ECONNABORTED
> defined?
Yay, I broke the Windows build! Thanks for fixing the patch.
Looking through erts/emulator/drivers/common/inet_drv.c, the only platform
for which ECONNABORTED is explicitly handled is Windows:
#ifdef __WIN32__
#define ECONNABORTED WSAECONNABORTED
#endif /* __WIN32__ */
> diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
> index 7e4a661..83ebdaa 100644
> --- a/erts/epmd/src/epmd_srv.c
> +++ b/erts/epmd/src/epmd_srv.c
> @@ -411,7 +411,9 @@ static int do_accept(EpmdVars *g,int listensock)
> dbg_perror(g,"error in accept");
> switch (errno) {
> case EAGAIN:
> +#ifndef __WIN32__
> case ECONNABORTED:
> +#endif
> case EINTR:
> return EPMD_FALSE;
> default:
________________________________________________________________
erlang-patches (at) erlang.org mailing list.
See http://www.erlang.org/faq.html
To unsubscribe; mailto:erlang-patches-unsubscribe@erlang.org
Post received from mailinglist |
|
|
| Back to top |
|
|
|
All times are GMT
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|
|