rails/rspec/rakeコマンドが使えなくなった(不完全解決)
TL;DR
- railsコマンドやrspecコマンドを使おうとすると、ctrl+Cでストップできないスリープ状態になってしまう
-
ps aux
すると、STATがD+
(Uninterruptible sleep)になっていた
-
- gitやbootsnapのキャッシュ周りが読み込めないみたいだったので、再度リポジトリをcloneし直したり、bootsnapを使わないように設定することで一旦解決
実行環境
- macos :Ventura 13.1
- docker : Docker for Mac (Engine v20.10.6)
- ruby : 2.6.2p47
- rails : 5.2.4.6
経緯と調査録
今ではもう何が原因か定かではないですが、macosのアップデートを久しぶりに行ったあと、docker下のrailsコマンドやrspecコマンド、rakeコマンドを用いると、プロセスが固まってしまうようになってしまいました。
ctrl+Cでterminateできずさすがにおかしいと思い、ps aux
をすると、該当プロセスのSTATのところがD+
になっていました。
...この辺りあまり詳しくなかったので調べてみると、D
はUninterruptible sleepを意味しており、主にIO周りでスタックしているということがわかりました。
IO周りがおかしいといっても、プロセスはエラーも吐かず、何のメッセージも返していないので困ったなとなっていたら、どうやらstrace
コマンドを用いることで、プロセスの処理内容を追うことができるとのことでした。
strace は、特定プロセスのシステムコールレベルでの処理をトレースできるツールです。
straceコマンドはaptであれば、以下のコマンドでインストールできます。
apt install strace
実際にstrace
コマンドを用いてみます。(-fオブションでサブプロセスもトレースできるみたいです)
% strace -f bundle exec rails -v
(中略)
[pid 2511] lstat(".git/refs/heads/master", {st_mode=S_IFREG|0644, st_size=41, ...}) = 0
[pid 2511] open(".git/refs/heads/master", O_RDONLY) = 3
[pid 2511] read(3, "3057cdcf25cd95ba7c1dd56b6119bf83"..., 256) = 41
[pid 2511] read(3, "", 215) = 0
[pid 2511] close(3) = 0
[pid 2511] lstat(".git/refs/HEAD", 0x7ffd740477d0) = -1 ENOENT (No such file or directory)
[pid 2511] open(".git/packed-refs", O_RDONLY) = 3
[pid 2511] fstat(3, {st_mode=S_IFREG|0644, st_size=220008, ...}) = 0
[pid 2511] fstat(3, {st_mode=S_IFREG|0644, st_size=220008, ...}) = 0
[pid 2511] read(3,
ここでストップしました。
むむ...どうやらgit関係のファイルのreadで止まっているっぽいです。たしかにIO周りで何か発生してそう。
消していいものなのかちょっと判断が難しいので、同じプロジェクトのgitリポジトリを別フォルダにクローンして再度ビルドしてみることにしました。
(30分後)
さて、再度ビルドし終えたので、コマンドを叩いてみます。
% bundle exec rails -v
>
また止まってるが...。
straceコマンドを併用してみます。
% strace -f bundle exec rails -v
(中略)
lstat("/usr/local/bundle/gems", {st_mode=S_IFDIR|S_ISGID|0755, st_size=12288, ...}) = 0
lstat("/usr/local/bundle/gems/bootsnap-1.4.4", {st_mode=S_IFDIR|S_ISGID|0755, st_size=4096, ...}) = 0
lstat("/usr/local/bundle/gems/bootsnap-1.4.4/lib", {st_mode=S_IFDIR|S_ISGID|0755, st_size=4096, ...}) = 0
lstat("/usr/local/bundle/gems/bootsnap-1.4.4/lib/bootsnap", {st_mode=S_IFDIR|S_ISGID|0755, st_size=4096, ...}) = 0
lstat("/usr/local/bundle/gems/bootsnap-1.4.4/lib/bootsnap/compile_cache.rb", {st_mode=S_IFREG|0644, st_size=1324, ...}) = 0
open("/app/tmp/cache/bootsnap-load-path-cache", O_RDONLY|O_CLOEXEC) = 5
ioctl(5, TCGETS, 0x7fff935a5830) = -1 ENOTTY (Inappropriate ioctl for device)
fstat(5, {st_mode=S_IFREG|0644, st_size=462385, ...}) = 0
lseek(5, 0, SEEK_CUR) = 0
mmap(NULL, 462848, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6edbeea000
どうも別のファイルで止まっているっぽいですね...。
調べてみるとbootsnap-load-path-cache
はbootsnapのキャッシュみたいです。
一旦rails側でbootsnapを読み込まないようにしてみます。
# require 'bootsnap/setup'
コメントアウトしました。
実行してみます。
% bundle exec rails -v
Rails 5.2.4.6
通りました!
bootsnapを使えるようにしたい(未解決)
やったーと言いたいところですが、bootsnapを使わないのはちょっとだけ気持ち悪いので使える方法がないか調査してみます。
(ここからは章タイトルにあるように未解決です。申し訳ございません)
色々調べていると、bootsnap-load-path-cache
やbootsnap-compile-cache
を削除する
のがいいとのことでした。/app/tmp/cache/
以下を消してみます。
% rm -rf /app/tmp/cache
rm: cannot remove '/app/tmp/cache/.nfs0000000011de3dfa00000003': Device or resource busy
rm: cannot remove '/app/tmp/cache/.nfs0000000011de5efb00000006': Device or resource busy
rm: cannot remove '/app/tmp/cache/.nfs0000000011cf14c100000002': Device or resource busy
rm: cannot remove '/app/tmp/cache/bootsnap-compile-cache/b3/.nfs0000000011cf0a0d00000005': Device or resource busy
何か消せないファイルあるけど...。
nfs?そういえばうちのプロジェクトではdocker for macでのVolumeのマウントが遅いので、nfsを用いたマウントを行っていたなあということを思い出しました。(参考 : https://qiita.com/kunit/items/36d9e5fa710ad26f8010)
たぶん何かしらのプロセスがファイルディスクリプタを掴んだまま死んでいるか何かなのかな〜と思いました。
まあ一旦bootsnapの設定を戻して、コマンド実行してみます。
% bundle exec rails c
Loading development environment (Rails 5.2.4.6)
[1] pry(main)>
お、通った。
キャッシュが効くかもう一回実行してみます。
% strace -f bundle exec rails c
(中略)
lstat("/usr/local/bundle/gems/bootsnap-1.4.4", {st_mode=S_IFDIR|S_ISGID|0755, st_size=4096, ...}) = 0
lstat("/usr/local/bundle/gems/bootsnap-1.4.4/lib", {st_mode=S_IFDIR|S_ISGID|0755, st_size=4096, ...}) = 0
lstat("/usr/local/bundle/gems/bootsnap-1.4.4/lib/bootsnap", {st_mode=S_IFDIR|S_ISGID|0755, st_size=4096, ...}) = 0
lstat("/usr/local/bundle/gems/bootsnap-1.4.4/lib/bootsnap/compile_cache.rb", {st_mode=S_IFREG|0644, st_size=1324, ...}) = 0
open("/app/tmp/cache/bootsnap-load-path-cache", O_RDONLY|O_CLOEXEC) = 5
ioctl(5, TCGETS, 0x7ffea073af40) = -1 ENOTTY (Inappropriate ioctl for device)
fstat(5, {st_mode=S_IFREG|0644, st_size=462441, ...}) = 0
lseek(5, 0, SEEK_CUR) = 0
mmap(NULL, 462848, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe717592000
read(5, 1
やっぱりダメみたいですね...。
bootsnap-load-path-cache
は消してもまた生成されてエラーが出るし、fuser
コマンドでファイルを使用しているプロセスを特定しようとしましたが、Permission deniedが出て特定できませんでした...(何故...)
% apt install psmisc
% fuser bootsnap-load-path-cache
Cannot stat file /proc/36/fd/0: Permission denied
Cannot stat file /proc/36/fd/1: Permission denied
Cannot stat file /proc/36/fd/2: Permission denied
Cannot stat file /proc/36/fd/3: Permission denied
Cannot stat file /proc/36/fd/4: Permission denied
Cannot stat file /proc/36/fd/5: Permission denied
Cannot stat file /proc/36/fd/6: Permission denied
Cannot stat file /proc/36/fd/7: Permission denied
Cannot stat file /proc/36/fd/8: Permission denied
Cannot stat file /proc/36/fd/9: Permission denied
Cannot stat file /proc/39/fd/0: Permission denied
Cannot stat file /proc/39/fd/1: Permission denied
Cannot stat file /proc/39/fd/2: Permission denied
Cannot stat file /proc/39/fd/3: Permission denied
Cannot stat file /proc/39/fd/4: Permission denied
Cannot stat file /proc/39/fd/5: Permission denied
Cannot stat file /proc/39/fd/6: Permission denied
Cannot stat file /proc/39/fd/7: Permission denied
Cannot stat file /proc/39/fd/8: Permission denied
Cannot stat file /proc/39/fd/9: Permission denied
Cannot stat file /proc/39/fd/10: Permission denied
Cannot stat file /proc/39/fd/11: Permission denied
Cannot stat file /proc/39/fd/12: Permission denied
Cannot stat file /proc/39/fd/13: Permission denied
Cannot stat file /proc/39/fd/14: Permission denied
Cannot stat file /proc/39/fd/15: Permission denied
Cannot stat file /proc/39/fd/16: Permission denied
Cannot stat file /proc/39/fd/17: Permission denied
ここから色々調べてみましたが、残念ながらこの件に関しては解決できませんでした。
bootsnapはrails周りの立ち上げを早めてくれるらしいのですが、別にこの状態でもそこまで遅くなく、困らないと思ったため、このままbootsnapは使わない運用で行こうと最終的に判断しました(敗北)。
いかがでしたか?な記事になってしまって大変申し訳無いですが、何かわかる方はコメントなどで教えていただけると助かります...。
Discussion