diff options
author | Eric Wong <e@80x24.org> | 2019-06-30 22:19:39 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2019-06-30 22:25:25 +0000 |
commit | 8472ccddd410a136b5aaa8bb886c7cf0dc302411 (patch) | |
tree | c5f33963c285a1e027ac8c89c8497c67df1e1e80 /lib/PublicInbox/Daemon.pm | |
parent | 3eb26fe04dae68612c841e749abd2848ce78ae59 (diff) | |
download | public-inbox-8472ccddd410a136b5aaa8bb886c7cf0dc302411.tar.gz |
For users relying on socket activation via service manager (e.g. systemd) and running multiple service instances (@1, @2), we need to ensure configuration of the socket is NonBlocking. Otherwise, service managers such as systemd may clear the O_NONBLOCK flag for a small window where accept/accept4 blocks: public-inbox-nntpd@1 |systemd |public-inbox-nntpd@2 --------------------------+----------------+-------------------- F_SETFL,O_NONBLOCK|O_RDWR | | (not running, yet) |F_SETFL, O_RDWR | |fork+exec @2... | accept(...) # blocks! | |(started by systemd) | |F_SETFL,O_NONBLOCK|O_RDWR | |accept(...) non-blocking It's a very small window where O_NONBLOCK can be cleared, but it exists, and I finally hit it after many years.
Diffstat (limited to 'lib/PublicInbox/Daemon.pm')
-rw-r--r-- | lib/PublicInbox/Daemon.pm | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/lib/PublicInbox/Daemon.pm b/lib/PublicInbox/Daemon.pm index 2b7ac266..2046a7f5 100644 --- a/lib/PublicInbox/Daemon.pm +++ b/lib/PublicInbox/Daemon.pm @@ -155,9 +155,9 @@ sub daemon_prepare ($) { my $s = eval { $sock_pkg->new(%o) }; warn "error binding $l: $! ($@)\n" unless $s; umask $prev; - if ($s) { $listener_names{sockname($s)} = $s; + $s->blocking(0); push @listeners, $s; } } @@ -363,6 +363,14 @@ sub inherit () { foreach my $fd (3..$end) { my $s = IO::Handle->new_from_fd($fd, 'r'); if (my $k = sockname($s)) { + if ($s->blocking) { + $s->blocking(0); + warn <<""; +Inherited socket (fd=$fd) is blocking, making it non-blocking. +Set 'NonBlocking = true' in the systemd.service unit to avoid stalled +processes when multiple service instances start. + + } $listener_names{$k} = $s; push @rv, $s; } else { |