From 6ff8785c9277c5978e6dc01cb1b3da25d6bae2db Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 5 Jun 2023 10:12:52 +0000 Subject: [PATCH 23/23] LISTEN_FDS-inherited sockets are immortal across SIGHUP When using systemd-style socket activation, consider the inherited socket immortal and do not drop it on SIGHUP. This means configs w/o any `listen' directives at all can continue to work after SIGHUP. I only noticed this while writing some tests in Perl 5 and the test suite is two lines shorter to test this feature :> --- lib/unicorn/http_server.rb | 7 ++++++- t/client_body_buffer_size.t | 1 - t/integration.t | 1 - 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb index dd92b38..f1b4a54 100644 --- a/lib/unicorn/http_server.rb +++ b/lib/unicorn/http_server.rb @@ -77,6 +77,7 @@ def initialize(app, options = {}) options[:use_defaults] = true self.config = Unicorn::Configurator.new(options) self.listener_opts = {} + @immortal = [] # immortal inherited sockets from systemd # We use @self_pipe differently in the master and worker processes: # @@ -158,6 +159,7 @@ def listeners=(listeners) end set_names = listener_names(listeners) dead_names.concat(cur_names - set_names).uniq! + dead_names -= @immortal.map { |io| sock_name(io) } LISTENERS.delete_if do |io| if dead_names.include?(sock_name(io)) @@ -807,17 +809,20 @@ def inherit_listeners! # inherit sockets from parents, they need to be plain Socket objects # before they become Kgio::UNIXServer or Kgio::TCPServer inherited = ENV['UNICORN_FD'].to_s.split(',') + immortal = [] # emulate sd_listen_fds() for systemd sd_pid, sd_fds = ENV.values_at('LISTEN_PID', 'LISTEN_FDS') if sd_pid.to_i == $$ # n.b. $$ can never be zero # 3 = SD_LISTEN_FDS_START - inherited.concat((3...(3 + sd_fds.to_i)).to_a) + immortal = (3...(3 + sd_fds.to_i)).to_a + inherited.concat(immortal) end # to ease debugging, we will not unset LISTEN_PID and LISTEN_FDS inherited.map! do |fd| io = Socket.for_fd(fd.to_i) + @immortal << io if immortal.include?(fd) io.autoclose = false io = server_cast(io) set_server_sockopt(io, listener_opts[sock_name(io)]) diff --git a/t/client_body_buffer_size.t b/t/client_body_buffer_size.t index b1a99f3..3067f28 100644 --- a/t/client_body_buffer_size.t +++ b/t/client_body_buffer_size.t @@ -36,7 +36,6 @@ POSIX::mkfifo($fifo, 0600) or die "mkfifo: $!"; seek($conf_fh, 0, SEEK_SET); truncate($conf_fh, 0); print $conf_fh <do_kill('HUP'); diff --git a/t/integration.t b/t/integration.t index a568758..bb2ab51 100644 --- a/t/integration.t +++ b/t/integration.t @@ -17,7 +17,6 @@ my $u1 = "$tmpdir/u1"; print $conf_fh < $srv }); my $curl = which('curl');