View Issue Details

IDProjectCategoryView StatusLast Update
0005511GNUnetutil librarypublic2019-02-28 10:17
Reporteramatus Assigned ToChristian Grothoff Due Date
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Platformamd64OSdebianOS Version9
Product VersionGit master 
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 05: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 15: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 15: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 22: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 07:43

manager   ~0013667

Tested it, works fine here.

Issue History

Date ModifiedUsernameFieldChange
2019-01-25 17:25amatusNew Issue
2019-01-26 05:09Christian GrothoffNote Added: 0013469
2019-01-26 05:09Christian GrothoffTarget Version => 0.11.0
2019-01-26 05:10Christian GrothoffStatusnew => confirmed
2019-01-26 15:25amatusNote Added: 0013471
2019-01-26 15:35Christian GrothoffNote Added: 0013472
2019-02-09 22:21Christian GrothoffAssigned To => Christian Grothoff
2019-02-09 22:21Christian GrothoffStatusconfirmed => assigned
2019-02-09 22:31Christian GrothoffNote Added: 0013640
2019-02-09 22:32Christian GrothoffAssigned ToChristian Grothoff => amatus
2019-02-09 22:32Christian GrothoffStatusassigned => feedback
2019-02-12 07:43Christian GrothoffAssigned Toamatus => Christian Grothoff
2019-02-12 07:43Christian GrothoffStatusfeedback => resolved
2019-02-12 07:43Christian GrothoffResolutionopen => fixed
2019-02-12 07:43Christian GrothoffFixed in Version => 0.11.0
2019-02-12 07:43Christian GrothoffNote Added: 0013667
2019-02-28 10:17Christian GrothoffStatusresolved => closed