Hello,

This was originally https://issues.guix.gnu.org/77610.

Guix recently switched to systemd-style socket activation 
(https://www.freedesktop.org/software/systemd/man/latest/daemon.html#Socket-Based%20Activation)
 for their daemon.

When I tried this on a Guix Hurd VM the first connection to the dameon is now 
consistently failing with EAGAIN.  Afterwards connections are behaving as 
expected.

It turns out that the first socket returned by accept(2) is O_NONBLOCK.

A very basic reproducing daemon is something like:

--8<---------------cut here---------------start------------->8---
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <fcntl.h>

int
main (int argc, char **argv)
{

  int fd = 3;
  int client;
  char buffer[1024];
  ssize_t num_read;
  
  while (1)
    {
      client = accept(fd, NULL, NULL);
      if (client < 0) return 1;
      fprintf(stderr, "Accepting connection\n");
      if ((fcntl(client, F_GETFL) & O_NONBLOCK) != 0)
{
  fprintf(stderr, "Socket is O_NONBLOCK\n");
}
      num_read = read(client, buffer, sizeof(buffer) -1);      
      fprintf(stderr,"Received: %s\n", buffer);
      write(client, buffer, num_read);
      close(client);
    }
  return 0;
}
--8<---------------cut here---------------end--------------->8---

When I try to use this with the shepherd service manager and connect to the 
socket 2 times the following is logged:

--8<---------------cut here---------------start------------->8---
[...]
Service test running with value #<<systemd-service> endpoints: (#<<endpoint> 
name: "test" address: #(1 "/tmp/test/test") style: 1 backlog: 128 owner: 1000 
group: 998 permissions: 493 bind-attempts: 5>) sockets: (#<input-output: socket 
25>) command: ("/tmp/main")>.
Running value of service test changed to #<<process> id: 174 command: 
("/tmp/main")>.
[main] Accepting connection
[main] Socket is O_NONBLOCK
[main] Received: hi
[main] Accepting connection
[main] Received: hi
--8<---------------cut here---------------end--------------->8---

When I disable the #:lazy-start? option in the service (this causes shepherd to 
start the daemon as soon as possible rather than on the first connection) this 
does not happen.

Any ideas what the reason could be?
Thanks.


Reply via email to