View Issue Details

IDProjectCategoryView StatusLast Update
0005511GNUnetutil librarypublic2019-02-28 11:17
ReporteramatusAssigned ToChristian Grothoff 
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Platformamd64OSdebianOS Version9
Product VersionSVN HEAD 
Target Version0.11.0Fixed in Version0.11.0 
Summary0005511: A service will busy-wait if it runs out of file descriptors and an incoming connection is made
DescriptionWhen a service's listening socket becomes readable accept_client() is called, it will call GNUNET_NETWORK_socket_accept() which will return NULL if accept() returns -1 (and errno is set to EMFILE) if the service has too many open files. The call to accept_client() will then be rescheduled and called again because the connection is still in the accept queue and the listening socket is still readable.

We could:
1. close and re-open the listening socket to clear out the accept queue, or
2. delay rescheduling accept_client().
Steps To ReproduceRun `gnunet-peerinfo -in` over and over again until gnunet-service-transport locks up.
TagsNo tags attached.

Activities

Christian Grothoff

2019-01-26 06:09

manager   ~0013469

I dislike closing the listen() socket, that seems like a terrible idea (we might not even get it back).

Pausing accept() seems fine, modulo knowing when it is OK to try again. I guess we could limit ourselves to resuming the accept()-ing when a client connection is close()d, and then trigger the re-adding of the accept() in the client-close logic.

Note that this problem should become less pressing with epoll(), assuming ulimit is raised as well.

amatus

2019-01-26 16:25

developer   ~0013471

I also dislike closing the socket, the delay is a better solution.

I don't see how epoll() will change anything, the socket will be constantly readable and accept() will constantly return -1.

We shouldn't assume anything about ulimit.

Christian Grothoff

2019-01-26 16:35

manager   ~0013472

epoll() will just enable us to go >> 1024 sockets. But you are right, fundamentally it won't change that accept() can fail and we'd busy-loop. Just if the limit is high enough that this never happens in practice, that'll make the issue much less severe.

Christian Grothoff

2019-02-09 23:31

manager   ~0013640

Check for EMFILE added in 4f9169370..d974bae72. We will then suspend accepting connections, and only resume it once one of the existing clients closed the socket.

Christian Grothoff

2019-02-12 08:43

manager   ~0013667

Tested it, works fine here.

Issue History

Date Modified Username Field Change
2019-01-25 18:25 amatus New Issue
2019-01-26 06:09 Christian Grothoff Note Added: 0013469
2019-01-26 06:09 Christian Grothoff Target Version => 0.11.0
2019-01-26 06:10 Christian Grothoff Status new => confirmed
2019-01-26 16:25 amatus Note Added: 0013471
2019-01-26 16:35 Christian Grothoff Note Added: 0013472
2019-02-09 23:21 Christian Grothoff Assigned To => Christian Grothoff
2019-02-09 23:21 Christian Grothoff Status confirmed => assigned
2019-02-09 23:31 Christian Grothoff Note Added: 0013640
2019-02-09 23:32 Christian Grothoff Assigned To Christian Grothoff => amatus
2019-02-09 23:32 Christian Grothoff Status assigned => feedback
2019-02-12 08:43 Christian Grothoff Assigned To amatus => Christian Grothoff
2019-02-12 08:43 Christian Grothoff Status feedback => resolved
2019-02-12 08:43 Christian Grothoff Resolution open => fixed
2019-02-12 08:43 Christian Grothoff Fixed in Version => 0.11.0
2019-02-12 08:43 Christian Grothoff Note Added: 0013667
2019-02-28 11:17 Christian Grothoff Status resolved => closed