0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「昨日まで動いてたのに」— macOS + MAMP で突然出る errno=11 Resource deadlock avoided の正体と直し方

0
Posted at

こんな症状、見たことありませんか

macOS + MAMP + Laravel(Composer)のローカル開発で、ある日突然ブラウザが真っ白な 500 を返すようになる。

Notice: require(): Read of N bytes failed with errno=11 Resource deadlock avoided
  in .../vendor/composer/autoload_real.php on line 12
Fatal error: Uncaught Error: Failed opening required '.../vendor/composer/ClassLoader.php'

厄介なのはここからです。

  • リロードしても直らない(エラーが起きるファイルが毎回微妙に変わることすらある)
  • ターミナルで composer dump-autoload を叩くと ハングする
  • cat vendor/composer/ClassLoader.php は普通に読める(=「CLIでは開けるから大丈夫」ではない)
  • 前日まで何の問題もなく動いていた

コードは一切変えていないのに起きる系のバグで、最初は「Composer が壊れた?PHPのバージョン問題?」と当たりを付けて時間を溶かしました。結論から言うと 原因はコードではなく、プロジェクトの置き場所 でした。

原因:~/Documents 配下 + ファイル同期系サービスの組み合わせ

errno=11 は Linux/macOS カーネルが返す EDEADLK(デッドロック回避)です。今回のケースでは、以下のような「ファイルを inode レベルで掴み続ける」サービスが ~/Documents を監視下に置いていることが根本原因でした。

容疑者 何をしているか
iCloud Drive の「デスクトップと書類フォルダ」同期 ~/Documents 全体を File Provider 管理下に置く
Google Drive の File Stream(DFSFileProviderExtension 同様に Documents を監視・同期
Time Machine のローカルスナップショット APFS の COW(copy-on-write)参照を保持
Spotlight のインデクサ 大量ファイル変更時に再インデックスで I/O を握る

これらが APFS のコピーオンライト参照やファイルロックを保持していると、Apache の並列 worker が mmap() で同じファイルを読もうとした瞬間にカーネルがロック取得を諦めて EDEADLK を返します。

ポイントは、CLI の単発 read()cat や PHP の file_get_contents)は通ってしまうこと。Apache のマルチプロセス + mmap の組み合わせのときだけ再現するので、「ターミナルでは読めるし壊れてないはず」という調査の勘が裏切られます。vendor/composer install の度に大量のファイルが新規 inode で作られるため、標的にされやすいディレクトリでもあります。

応急処置(その場をしのぎたいとき)

引っ越しがすぐできない場合は、上から順に試すと大体直ります。

# ① Time Machine の進行中バックアップを止める
tmutil stopbackup

# ② 残っているローカルスナップショットを削除(root 不要)
tmutil listlocalsnapshots /
tmutil deletelocalsnapshots <YYYY-MM-DD-HHMMSS>   # 出てきた ID を指定

# ③ 今後のバックアップ対象から除外
tmutil addexclusion /path/to/project
tmutil isexcluded  /path/to/project   # [Excluded] と出れば OK

# ④ autoload ファイルだけ新しい inode に置き換える(最後の手段)
cd <project>/vendor/composer
for f in *.php; do cp -p "$f" "$f.tmp" && mv "$f.tmp" "$f"; done

# ⑤ Apache を Stop → Start(OPcache をクリア)

ただし、これは絆創膏です。composer install / npm install / ファイル編集のたびに新しい inode が File Provider に再補足され、また再発します

恒久対処:プロジェクトを ~/Documents の外に出す

一番効いたのは単純で、プロジェクトを File Provider の監視が及ばない場所(今回は MAMP の htdocs 配下)に移設することでした。

# 1. MAMP の Apache を Stop(GUI から。CLI の apachectl restart はポート80衝突するので避ける)

# 2. 新ロケーションに clone(mv は File Provider に阻まれてハングすることがあるので使わない)
cd /Applications/MAMP/htdocs
git clone <リモートURL> myapp
cd myapp

# 3. 依存を新ロケーションで再生成(File Provider 圏外なのでクリーンに通る)
composer install
nvm use 22          # node は 20+ 推奨。古い v10 だと vite build が壊れる
npm ci
npm run build

# 4. Laravel のコンパイル済みキャッシュをクリア(旧パスの焼き込み除去)
php artisan optimize:clear

# 5. vhost の DocumentRoot を新パスへ書き換える
#    /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf

# 6. Apache を Start → 動作確認
curl -sL -o /dev/null -w "%{http_code}\n" http://your-local-domain   # 200

.env は git 管理外なので、移設前に控えておくのを忘れずに。DB 接続はパスに依存しないので、移設後もそのまま使えます。

git worktree で配信している場合の注意

Claude Code などで git worktree から配信していると、worktree は .git絶対パス で参照を持っているため、単純な mv で壊れます。対処は2択:

  • 通常チェックアウト1本で配信するようにする(worktree 配信をやめる。一番シンプルで事故りにくい)
  • git worktree move で worktree ごと正しく移設する(.git の参照も書き換わる。ズレたら git worktree repair

複数プロジェクトを並行して worktree 配信していると管理が煩雑になりがちなので、通常チェックアウトでの配信を基本にする方をおすすめします。

再発防止チェックリスト

  • プロジェクトは ~/Documents の外にある
  • ~/Documents 配下に何か残す場合は Time Machine 除外済み(tmutil isexcluded で確認)
  • node は毎回 nvm use でバージョンを固定してから build
  • iCloud「デスクトップと書類」同期・Google Drive File Stream の対象範囲を見直す(開発中の重いリポジトリは外に出す)

まとめ

errno=11 Resource deadlock avoided は、一見 Composer や PHP のバグに見えて、実態は macOS のファイル同期系サービスと Apache の mmap の相性問題 でした。「CLI では読めるのに Apache だけ死ぬ」「昨日まで動いてた」という組み合わせを見たら、まずプロジェクトの置き場所を疑ってみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?