[systemd-devel] Why systemd keeps references on passed sockets ?
Francis Moreau
francis.moro at gmail.com
Wed Sep 9 08:56:37 UTC 2020
On Tue, Sep 8, 2020 at 5:41 PM Lennart Poettering
<lennart at poettering.net> wrote:
>
> On Di, 08.09.20 17:35, Francis Moreau (francis.moro at gmail.com) wrote:
>
> > On Mon, Sep 7, 2020 at 4:38 PM Lennart Poettering
> > <lennart at poettering.net> wrote:
> > >
> > > "React on the socket close?" — What do you mean by that?
> > >
> >
> > I mean if my service explicitly calls close() then systemd could stop
> > the socket on its side so its are freed until the service is
> > restarted. I think it is what you described below.
>
> close() just drops a ref to the socket. Only when close() drops the
> last ref something actually happens on the socket and it is
> destroyed. This means: systemd doesn't get notified about your code
> invoking close(), because all you did is drop one ref of many.
>
> > > Note that on Linux you can invoke shutdown() on a listening socket
> > > (i.e. not just on the connection socket, but on a listening
> > > socket). iirc in that case systemd actually notices and will put the
> > > .socket unit in failure mode...
> > >
> >
> > I looked at the code and there is:
> >
> > if (state != SOCKET_LISTENING)
> > socket_unwatch_fds(s);
> >
> > So I'm not sure how systemd can react on shutdown(). And I tried to
> > call shutdown() in my service but it has no effects.
>
> Hmm, that suggests we'd have to slightly update our logic then for
> this to work: keep the listening fds in the poll, but turn off all
> the EPOLLIN bit we listen on.
>
> > > Would that work for you? (Maybe we could even tweak this a bit in
> > > systemd, so that when you invoke shutdown() on the socket systemd
> > > holds for you we do not consider that a failure anymore, but a clean
> > > way to tell systemd to stop the socket).
> >
> > That is a good idea especially if systemd doesn't consider an error
> > when the service closes or shutdown the socket.
> >
> > But again in the code I can see:
> >
> > sd_event_add_io(UNIT(s)->manager->event, &p->event_source, p->fd,
> > EPOLLIN, socket_dispatch_io, p);
> >
> > It seems that it only listens to "EPOLLIN" events. So it doesn't
> > listen to "EPOLLUP".
>
> EPOLLHUP is always implied, you don't have to specify it. if you
> specifiy zero as mask you will still get notified about EPOLLHUP +
> EPOLLERR.
>
Thank you for the info
> But you are right we currently remove the fd from polling while the
> socket's service is running. We'd have to change that (as mentioned
> above). happy to review a PR for that.
I'm afraid I'm not skilled enough in systemd internals to work on this, sorry.
More information about the systemd-devel
mailing list