Bug #14207
closedFailed to build 2.5.0-rc1 on CircleCI
Description
CircleCI の docker 上で ruby 2.5.0-rc1 をビルドしてみたらエラーになりました。
make 時に多くの拡張ライブラリが "Could not be configured. It will not be installed" となっていて、
fileutilsで "Operation not permitted - copy_file_range" というメッセージが出ていました。
linking ruby
make[2]: Leaving directory '/tmp/ruby-2.5.0-rc1'
make[1]: Leaving directory '/tmp/ruby-2.5.0-rc1'
make[1]: Entering directory '/tmp/ruby-2.5.0-rc1'
*** Following extensions are not compiled:
dbm:
Could not be configured. It will not be installed.
/tmp/ruby-2.5.0-rc1/lib/fileutils.rb:441: Operation not permitted - copy_file_range
Check ext/dbm/mkmf.log for more details.
io/console:
Could not be configured. It will not be installed.
/tmp/ruby-2.5.0-rc1/lib/fileutils.rb:441: Operation not permitted - copy_file_range
Check ext/io/console/mkmf.log for more details.
io/nonblock:
Could not be configured. It will not be installed.
/tmp/ruby-2.5.0-rc1/lib/mkmf.rb:309: closed stream
Check ext/io/nonblock/mkmf.log for more details.
io/wait:
Could not be configured. It will not be installed.
/tmp/ruby-2.5.0-rc1/lib/mkmf.rb:309: closed stream
Check ext/io/wait/mkmf.log for more details.
etc:
Could not be configured. It will not be installed.
/tmp/ruby-2.5.0-rc1/lib/fileutils.rb:441: Operation not permitted - copy_file_range
Check ext/etc/mkmf.log for more details.
(snip)
readline:
Could not be configured. It will not be installed.
/tmp/ruby-2.5.0-rc1/lib/fileutils.rb:441: Operation not permitted - copy_file_range
Check ext/readline/mkmf.log for more details.
gdbm:
Could not be configured. It will not be installed.
/tmp/ruby-2.5.0-rc1/lib/fileutils.rb:441: Operation not permitted - copy_file_range
Check ext/gdbm/mkmf.log for more details.
openssl:
Could not be configured. It will not be installed.
/tmp/ruby-2.5.0-rc1/lib/fileutils.rb:441: Operation not permitted - copy_file_range
Check ext/openssl/mkmf.log for more details.
*** Fix the problems, then remove these directories and try again if you want.
また、 make install から呼ばれる do-install-nodoc ターゲットでも
"Operation not permitted - copy_file_range (Errno::EPERM)" のメッセージが
バックトレースとともに出ていました。
./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems -r./x86_64-linux-fake ./tool/rbinstall.rb --make="make" --dest-dir="" --extout=".ext" --mflags="" --make-flags="" --data-mode=0644 --prog-mode=0755 --installed-list .installed.list --mantype="man"
installing binary commands: /usr/local/ruby-2.5.0-rc1/bin
/tmp/ruby-2.5.0-rc1/lib/fileutils.rb:1291:in `copy_stream': Operation not permitted - copy_file_range (Errno::EPERM)
from /tmp/ruby-2.5.0-rc1/lib/fileutils.rb:1291:in `block (2 levels) in copy_file'
from /tmp/ruby-2.5.0-rc1/lib/fileutils.rb:1290:in `open'
from /tmp/ruby-2.5.0-rc1/lib/fileutils.rb:1290:in `block in copy_file'
from /tmp/ruby-2.5.0-rc1/lib/fileutils.rb:1289:in `open'
from /tmp/ruby-2.5.0-rc1/lib/fileutils.rb:1289:in `copy_file'
from /tmp/ruby-2.5.0-rc1/lib/fileutils.rb:430:in `copy_file'
from /tmp/ruby-2.5.0-rc1/lib/fileutils.rb:782:in `block in install'
from /tmp/ruby-2.5.0-rc1/lib/fileutils.rb:1461:in `block in fu_each_src_dest'
from /tmp/ruby-2.5.0-rc1/lib/fileutils.rb:1475:in `fu_each_src_dest0'
from /tmp/ruby-2.5.0-rc1/lib/fileutils.rb:1459:in `fu_each_src_dest'
from /tmp/ruby-2.5.0-rc1/lib/fileutils.rb:778:in `install'
from ./tool/rbinstall.rb:167:in `install'
from ./tool/rbinstall.rb:346:in `block in <main>'
from ./tool/rbinstall.rb:853:in `block in <main>'
from ./tool/rbinstall.rb:850:in `each'
from ./tool/rbinstall.rb:850:in `<main>'
uncommon.mk:312: recipe for target 'do-install-nodoc' failed
この現象は、ビルドする対象を2.5.0-preview1に変更すると起きませんでした。
また、ローカルPC (Debian) の Docker では 2.5.0-rc1 でも 2.5.0-preview1 でも問題なくビルドできました。
CircleCI 上で git bisect して調べてみると、 r60284 で発生するようになったようです。
CircleCIでのビルド時のログと、再現のための Dockerfile, .circleci/config.yml を添付します。
Files
Updated by sorah (Sorah Fukumori) almost 7 years ago
手元で大丈夫な時の Linux カーネルバージョンって 4.5 以降ですかね?
Ubuntu 16.04 および CircleCI (v2) は 4.4.0 系なので当該システムコールは動かないものの、Debian 9.x はそれより新しいのを想定しているはずなので、
まあちゃんと configure で見ましょうという感じがするな…。
Updated by minimum2scp (Tsuyoshi YAMADA) almost 7 years ago
sorah (Sorah Fukumori) wrote:
手元で大丈夫な時の Linux カーネルバージョンって 4.5 以降ですかね?
はい、4.5 以降です。
tsuyoshi@wezen% uname -a
Linux wezen 4.14.0-1-amd64 #1 SMP Debian 4.14.2-1 (2017-11-30) x86_64 GNU/Linux
Updated by sorah (Sorah Fukumori) almost 7 years ago
- ビルド環境にある unistd の __NR_copy_file_range のマクロの有無だけで判断している
- ユーザーランドにある unistd は Docker 等コンテナホスト側のカーネルのバージョンなんて知らない
- ビルドは copy_file_range システムコールが使えるものと信じて進行する
- しかしビルドされたところでそんなシステムコールは存在しない訳なのでエラーになる
-
docker run --privileged
下の場合は ENOSYS になる - 通常の権限が絞られた Docker コンテナーの場合ここで EPERM になる (!) どうしようもない。
-
その他 sendfile 等も同様に実装されているけれど、これらはかなり古いカーネルから存在するので実用上問題になってないと推測される
どうしましょうね…。
Updated by sorah (Sorah Fukumori) almost 7 years ago
補足すると、ビルド時 configure チェックしたところで結局新しいユーザーランドのパッケージマネージャから降ってくるバイナリはそういうのが含まれる可能性が高いので難しい話になってきた。
個人的にはホストより新しいカーネルを期待しているユーザーランドをコンテナで動かさないでください、という話になりそうで 3rd party issue にしたい気持ちが若干あります。
(本件、CircleCI って事で難易度たかそうですが…)
Updated by sorah (Sorah Fukumori) almost 7 years ago
- File 14207.patch added
copy_file_range の man みる限り EPERM は来なそうなので、こういう救いかたは出来ない事はないのだけれど…。
やはりその環境だと apt-get で降ってくるバイナリとかも同じ目にあいそうな気がするので Ruby だけで救うっていうのもなんかなーという気持ちがありますね。
Updated by sorah (Sorah Fukumori) almost 7 years ago
- File 14207.patch 14207.patch added
patch にゴミが混ざっていたので差し替え
Updated by Glass_saga (Masaki Matsushita) almost 7 years ago
- Status changed from Open to Assigned
- Assignee set to Glass_saga (Masaki Matsushita)
- Target version set to 2.5
Updated by Anonymous almost 7 years ago
- Status changed from Assigned to Closed
Applied in changeset trunk|r61412.
io.c: ignore EPERM
- io.c (nogvl_copy_file_range): ignore EPERM and fallback to
sendfile(2) or read/write. copy_file_range(2) may not exist
even if __NR_copy_file_range is defined in the build environment.
[Bug #14207]
Updated by Glass_saga (Masaki Matsushita) almost 7 years ago
バグレポートありがとうございます。
copy_file_range(2)でerrnoがEPERMだった場合は、sendfile(2)またはread/writeにフォールバックする実装にしました。
これで修正できているかと思います。
Updated by Glass_saga (Masaki Matsushita) almost 7 years ago
- Backport changed from 2.3: UNKNOWN, 2.4: UNKNOWN to 2.3: DONTNEED, 2.4: DONTNEED
Updated by minimum2scp (Tsuyoshi YAMADA) almost 7 years ago
ありがとうございます。
CircleCIのDocker上で最新の trunk をビルドできることと、
2.5.0-rc1 に r61412 のパッチを当てる方法でもビルドできることを確認しました。