From: deivid Date: 2022-01-23T14:34:59+00:00 Subject: [ruby-dev:51149] [Ruby master Bug#18437] 3.1.0 install stucks on FreeBSD & NFS Issue #18437 has been updated by deivid (David Rodríguez). That's great to hear. Yes, we fixed this differently by avoiding flock on non Windows platforms, since it didn't seem necessary and we were not using it in previous versions. But I think your patch might still bel valuable for Windows where `flock` seems necessary. ---------------------------------------- Bug #18437: 3.1.0 install stucks on FreeBSD & NFS https://bugs.ruby-lang.org/issues/18437#change-96104 * Author: os (Shigeki OHARA) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [x86_64-freebsd13.0] * Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- ## 概要 FreeBSD マシンで NFS 上のホームディレクトリーへ Ruby 3.1.0 を rbenv install 3.1.0 でインストールしようとすると、 gem のインストールで処理が止まってしまいます。 ## 再現手順 ### 環境 * OS (NFS クライアント): FreeBSD 13.0-RELEASE-p5 * NFS サーバー: CentOS 7.9 * NFSv4 * rbenv 1.2.0-6-g304cb7b, ruby-build 20211225-2-g927aec4 ### 手順 ``` % rbenv install 3.1.0 ``` ### 結果 10 数分待ってもインストールは終了せず。 このとき、 rbenv install のログは下記箇所で止まっています。 ``` (snip...) installing default gems from lib: /home/XXXXXXXX/.rbenv-amd64-freebsd13/versions/3.1.0/lib/ruby/gems/3.1.0 abbrev 0.1.0 ``` その後、 C-c すると、下記トレースで終了します。 ``` /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems.rb:793:in `flock': Interrupt from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems.rb:793:in `block in open_with_flock' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems.rb:790:in `open' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems.rb:790:in `open_with_flock' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems/stub_specification.rb:113:in `data' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems/stub_specification.rb:203:in `valid?' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems/specification.rb:778:in `select' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems/specification.rb:778:in `gemspec_stubs_in' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems/specification.rb:824:in `default_stubs' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems/specification.rb:850:in `stubs_for_pattern' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems/specification.rb:811:in `stubs' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems/specification.rb:1085:in `latest_specs' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems/specification.rb:1092:in `latest_spec_for' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems/installer.rb:514:in `generate_plugins' from /tmp/ruby-build.20211227102425.80508.kNmLXp/ruby-3.1.0/lib/rubygems/installer.rb:324:in `install' from ./tool/rbinstall.rb:899:in `block in install' from ./tool/rbinstall.rb:713:in `no_write' from ./tool/rbinstall.rb:899:in `install' from ./tool/rbinstall.rb:1002:in `block in install_default_gem' from ./tool/rbinstall.rb:989:in `each' from ./tool/rbinstall.rb:989:in `install_default_gem' from ./tool/rbinstall.rb:927:in `block in
' from ./tool/rbinstall.rb:1127:in `block in
' from ./tool/rbinstall.rb:1124:in `each' from ./tool/rbinstall.rb:1124:in `
' gmake: *** [uncommon.mk:383: do-install-all] 割り込み ``` 下記サイトによると、 NFS 上の排他的ロックは書き込みできるモードでオープンする必要があるとのことなので、 * https://blog.tmtms.net/entry/2016/03/11/flock 下記のようなパッチを当てて試したところ、 rbenv install 3.1.0 が完遂するようになりました。 ``` diff -ur ruby-3.1.0.orig/lib/rubygems/specification.rb ruby-3.1.0/lib/rubygems/specification.rb --- ruby-3.1.0.orig/lib/rubygems/specification.rb 2021-12-25 21:23:14.000000000 +0900 +++ ruby-3.1.0/lib/rubygems/specification.rb 2021-12-27 12:21:31.756622831 +0900 @@ -1116,7 +1116,7 @@ file = file.dup.tap(&Gem::UNTAINT) return unless File.file?(file) - code = Gem.open_with_flock(file, 'r:UTF-8:-', &:read) + code = Gem.open_with_flock(file, 'r+:UTF-8:-', &:read) code.tap(&Gem::UNTAINT) diff -ur ruby-3.1.0.orig/lib/rubygems/stub_specification.rb ruby-3.1.0/lib/rubygems/stub_specification.rb --- ruby-3.1.0.orig/lib/rubygems/stub_specification.rb 2021-12-25 21:23:14.000000000 +0900 +++ ruby-3.1.0/lib/rubygems/stub_specification.rb 2021-12-27 12:21:05.161104183 +0900 @@ -9,7 +9,7 @@ PREFIX = "# stub: ".freeze # :nodoc: - OPEN_MODE = 'r:UTF-8:-'.freeze + OPEN_MODE = 'r+:UTF-8:-'.freeze class StubLine # :nodoc: all attr_reader :name, :version, :platform, :require_paths, :extensions, ``` 先のサイトによると、読み込み専用で排他的ロックを掛けると、 Linux では EBADF になるようなのですが、 FreeBSD だとブロックするようです。 ``` % cat locktest.rb #!/usr/bin/env ruby require "timeout" filepath = ARGV.shift File.open(filepath, "w").close # just touch File.open(filepath, "r") do |f| Timeout.timeout(3) do f.flock(File::LOCK_EX) end end % ruby locktest.rb /tmp/locktest.lock % ruby locktest.rb ~/locktest.lock Traceback (most recent call last): 5: from locktest.rb:5:in `
' 4: from locktest.rb:5:in `open' 3: from locktest.rb:6:in `block in
' 2: from /usr/local/lib/ruby/2.7/timeout.rb:110:in `timeout' 1: from locktest.rb:7:in `block (2 levels) in
' locktest.rb:7:in `flock': execution expired (Timeout::Error) % ``` -- https://bugs.ruby-lang.org/