[systemd-devel] Problem with sd_listen_fds(0)

Lennart Poettering lennart at poettering.net
Fri Jun 28 13:08:56 UTC 2019


On Do, 27.06.19 13:44, Mantas Mikulėnas (grawity at gmail.com) wrote:

> On Thu, Jun 27, 2019 at 1:29 PM Donat Zenichev <donat.zenichev at gmail.com>
> wrote:
>
> > Hi systemd community.
> > Recently I've come accross one interesting problem with API of systemd.
> > The problem is that, I'm not able to read commands comming to the AF_UNIX
> > socket, that was created by systemd and passed to my program using
> > sd_listen_fds(0) function.
> >
> > What actually program requires, is AF_UNIX (AF_LOCAL) socket of type
> > SOCK_STREAM.
> > In case if I create this socket manually, using socket(AF_LOCAL,
> > SOCK_STREAM, 0) function, it works out as expected.
> >
> > But, when I create a socket using systemd socket unit, reading fails with
> > "-1" return value.
> >
> > What I actually do, is that I check if there are some sockets created for
> > me using sd_listen_fds(0), and in case it returns 1 (so 1 socket created),
> > program goes further and sets a file descriptor value to fd =
> > SD_LISTEN_FDS_START + 0;
> > Since the SD_LISTEN_FDS_START is pre-defined to value '3', my file
> > descriptor will always be '3'.
> >
> > But when it comes to reading, with read() function, it fails with the
> > errno EINVAL - Invalid argument.
> > It's not a matter of a other parameters than a file descriptor, since with
> > manual creation of socket it works out as I said.
> >
> > An initializing of the socket descriptor, when creating it by systemd
> > passes as normal, so program starts.
> > But any further command received on fd fails with '-1' return value.
> >
>
> As this is a stream socket, by default the program will receive the
> *listener* socket. Systemd will start your service as soon as someone
> connects, but your program still needs to accept() each connection first.

Addendum: you can set Accept=true in the socket unit file. If you do,
then systemd will accept the connection and spawn a new instance of
your service for each connection. For that to work you need to name
your service unit file foo at .service (if you socket unit file is called
foo.socket), i.e. the "@" indicates it's a service that shall be
instantiated multiple times.

Lennart

--
Lennart Poettering, Berlin


More information about the systemd-devel mailing list