Bug #18437
closed3.1.0 install stucks on FreeBSD & NFS
Description
概要¶
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 <main>'
from ./tool/rbinstall.rb:1127:in `block in <main>'
from ./tool/rbinstall.rb:1124:in `each'
from ./tool/rbinstall.rb:1124:in `<main>'
gmake: *** [uncommon.mk:383: do-install-all] 割り込み
下記サイトによると、 NFS 上の排他的ロックは書き込みできるモードでオープンする必要があるとのことなので、
下記のようなパッチを当てて試したところ、
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 `<main>'
4: from locktest.rb:5:in `open'
3: from locktest.rb:6:in `block in <main>'
2: from /usr/local/lib/ruby/2.7/timeout.rb:110:in `timeout'
1: from locktest.rb:7:in `block (2 levels) in <main>'
locktest.rb:7:in `flock': execution expired (Timeout::Error)
%
Updated by deivid (David Rodríguez) almost 3 years ago
Hello! Sorry for this issue, can you open a pull request to fix it at https://github.com/rubygems/rubygems?
Updated by os (Shigeki OHARA) almost 3 years ago
I tried installing the latest development version of Ruby and RubyGems, and successfully completed it.
% rbenv install 3.2.0-dev
Cloning https://github.com/ruby/ruby.git...
Installing ruby-master...
Installed ruby-master to /home/XXXXXXXX/.rbenv-amd64-freebsd13/versions/3.2.0-dev
% rbenv local 3.2.0-dev
% ruby -v
ruby 3.2.0dev (2022-01-22T16:02:38Z master ab1aa90c32) [x86_64-freebsd13.0]
% ruby -rrubygems -e "p Gem::VERSION"
"3.4.0.dev"
%
Updated by deivid (David Rodríguez) almost 3 years ago
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.
Updated by os (Shigeki OHARA) almost 3 years ago
Oh, I see. Thanks for the fix.
I think this issue has been resolved.
# 自分で Issue 閉じれないんですね……。
Updated by kou (Kouhei Sutou) almost 3 years ago
- Status changed from Open to Closed