From 5e3d05997769dd270123b9c2479938704de078de Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 3 Jul 2019 23:34:31 +0000 Subject: examples/unicorn@.service: note the NonBlocking flag It's racy otherwise when starting simultaneous instanced units. Without specifying NonBlocking=true, systemd will clear the O_NONBLOCK flag every time it starts a new service instance. There's a small window where systemd can clear O_NONBLOCK immediately after it's set by Ruby (or kgio): unicorn@1 |systemd |unicorn@2 ---------------------------+----------------+-------------------- F_SETFL, O_NONBLOCK|O_RDWR | | (not running, yet) |F_SETFL, O_RDWR | |fork | | exec unicorn@2 | accept4(...) # blocks! | | (now started by systemd) | |F_SETFL,O_NONBLOCK|O_RDWR | |accept4(...) non-blocking --- examples/unicorn@.service | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/unicorn@.service b/examples/unicorn@.service index d95eb83..946de44 100644 --- a/examples/unicorn@.service +++ b/examples/unicorn@.service @@ -14,7 +14,14 @@ After = unicorn.socket # bundler users must use the "--keep-file-descriptors" switch, here: # ExecStart = bundle exec --keep-file-descriptors unicorn -c ... ExecStart = /usr/bin/unicorn -c /path/to/unicorn.conf.rb /path/to/config.ru + +# NonBlocking MUST be true if using socket activation with unicorn. +# Otherwise, there's a small window in-between when the non-blocking +# flag is set by us and our accept4 call where systemd can momentarily +# make the socket blocking, causing us to block on accept4: +NonBlocking = true Sockets = unicorn.socket + KillSignal = SIGQUIT User = nobody Group = nogroup -- cgit v1.2.3-24-ge0c7