Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix systemd unix path handling #2007

Merged
merged 4 commits into from Oct 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions History.md
Expand Up @@ -4,6 +4,7 @@
* Your feature goes here (#Github Number)

* Bugfixes
* Fix socket activation of systemd (pre-existing) unix binder files (#1842, #1988)
* Deal with multiple calls to bind correctly (#1986, #1994, #2006)

## 4.2.0 / 2019-09-23
Expand Down
7 changes: 4 additions & 3 deletions lib/puma/binder.rb
Expand Up @@ -361,7 +361,7 @@ def inherit_ssl_listener(fd, ctx)
# Tell the server to listen on +path+ as a UNIX domain socket.
#
def add_unix_listener(path, umask=nil, mode=nil, backlog=1024)
@unix_paths << path
@unix_paths << path unless File.exist? path

# Let anyone connect by default
umask ||= 0
Expand Down Expand Up @@ -399,7 +399,7 @@ def add_unix_listener(path, umask=nil, mode=nil, backlog=1024)
end

def inherit_unix_listener(path, fd)
@unix_paths << path
@unix_paths << path unless File.exist? path

if fd.kind_of? TCPServer
s = fd
Expand All @@ -420,7 +420,8 @@ def close_listeners
io.close
uri = URI.parse(l)
next unless uri.scheme == 'unix'
File.unlink("#{uri.host}#{uri.path}")
unix_path = "#{uri.host}#{uri.path}"
File.unlink unix_path if @unix_paths.include? unix_path
end
end

Expand Down
1 change: 0 additions & 1 deletion lib/puma/cluster.rb
Expand Up @@ -529,7 +529,6 @@ def run
@suicide_pipe.close
read.close
@wakeup.close
@launcher.close_binder_unix_paths
end
end

Expand Down
5 changes: 1 addition & 4 deletions lib/puma/launcher.rb
Expand Up @@ -184,6 +184,7 @@ def run
when :exit
# nothing
end
@binder.close_unix_paths
end

# Return which tcp port the launcher is using, if it's using TCP
Expand All @@ -204,10 +205,6 @@ def close_binder_listeners
@binder.close_listeners
end

def close_binder_unix_paths
@binder.close_unix_paths
end

private

# If configured, write the pid of the current process out
Expand Down
1 change: 0 additions & 1 deletion lib/puma/single.rb
Expand Up @@ -118,7 +118,6 @@ def run
rescue Interrupt
# Swallow it
end
@launcher.close_binder_unix_paths
end
end
end
21 changes: 21 additions & 0 deletions test/test_binder.rb
Expand Up @@ -78,6 +78,27 @@ def test_allows_both_tcp_and_unix
assert_parsing_logs_uri [:tcp, :unix]
end

def test_pre_existing_unix
skip UNIX_SKT_MSG unless UNIX_SKT_EXIST
unix_path = "test/#{name}_server.sock"

File.open(unix_path, mode: 'wb') { |f| f.puts 'pre existing' }
@binder.parse ["unix://#{unix_path}"], @events

assert_match %r!unix://#{unix_path}!, @events.stdout.string

refute_includes @binder.instance_variable_get(:@unix_paths), unix_path

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's also call close_unix_paths and assert that the file is not removed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@binder.close_unix_paths

assert File.exist?(unix_path)

ensure
if UNIX_SKT_EXIST
File.unlink unix_path if File.exist? unix_path
end
end

private

def assert_parsing_logs_uri(order = [:unix, :tcp])
Expand Down
20 changes: 19 additions & 1 deletion test/test_integration_cluster.rb
Expand Up @@ -12,7 +12,25 @@ def setup
end

def teardown
super if HAS_FORK
return if skipped?
super
end

def test_pre_existing_unix
skip UNIX_SKT_MSG unless UNIX_SKT_EXIST

File.open(@bind_path, mode: 'wb') { |f| f.puts 'pre existing' }

cli_server "-w #{WORKERS} -q test/rackup/sleep_step.ru", unix: :unix

stop_server

assert File.exist?(@bind_path)

ensure
if UNIX_SKT_EXIST
File.unlink @bind_path if File.exist? @bind_path
end
end

def test_siginfo_thread_print
Expand Down