- M2 MacBook Proの起動ボリュームがSteamでゲームをダウンロード中に残り41KBになるまで埋まり、macOSがファイル削除すらできない状態に陥った
- Finderのゴミ箱を空にする操作、Terminalの
rmやfind -exec rm、Disk UtilityのTime Machineスナップショット削除まで、すべて「No space left on device」系のエラーで失敗した
- 再起動後はブートも途中で止まり、recoveryOSやApple siliconのShare Diskで別のMacにマウントしても削除を強制できなかった
- ドライブ初期化とmacOS再インストール後にTime Machine復元を試みたが、Venturaで復元が中断され、Sonoma 14.4と既存の14.3.1のバージョン差、SMB/Sambaネットワークマウント失敗が続いた
- 最終的に最新のTime Machineディスクイメージを外付け1TB SSDへコピーし、ホームディレクトリのファイルとアプリを手動復旧したが、ストレージ枯渇とバックアップ復元失敗が重なると熟練者でも対処は難しい
ストレージ枯渇で削除もできなくなったMac
- M2 MacBook Proのストレージが、Steamで正規購入したゲームをダウンロードしている最中にいっぱいになった
- macOSはドライブが危険なほど埋まっていても大容量のSteamダウンロードを止めず、起動ボリュームには41KBしか残らなかった
- 重要なファイルの大半はクラウドにあり、ローカルの大きなファイルを必ず保持しなければならない状況ではなかった
- 問題は単なる容量不足ではなく、OSがどの方法でもファイルを削除できない状態だったことだ
疑われた原因: SteamダウンロードとローカルTime Machineスナップショット
- ギガビットのインターネット接続と大きなSteamファイルにより、macOSがストレージ使用量の増加を制御できなかった可能性がある
- 同時に、macOSがローカルTime Machineスナップショットを作成していた点も疑われた
- macOSは外付けまたはネットワークのTime Machine保存先へバックアップ中でも、直近24時間のローカルバックアップを提供するためスナップショットを保持する
- Steamのファイルは見た目には1つの巨大ファイルのようでも、Time Machineの観点では別の扱いになっていた可能性がある
- ローカルの実ファイルと特殊に生成されたスナップショットが競合した可能性はあるが、正確な原因は特定されていない
すべて失敗した削除の試み
- Finderでゴミ箱を空にする操作は
File > Empty Trashから試したが失敗した
- エラーメッセージは「The operation can’t be completed because the disk is full」だった
- Terminalは起動できたが、標準的なUnixの
rmコマンドは動作しなかった
- エラーメッセージは「No space left on device」だった
- 大きなファイルを探し、
-execオプションでrmを実行するfindベースの代替手段も失敗した
- Disk UtilityでもAPFS起動ボリュームのTime Machineスナップショットを選んで削除しようとしたが、同じ制約に阻まれた
- 通常、スナップショットが占有するのは以前のスナップショットとの差分に必要なストレージだけだ
- この場合も「no space left」エラーが発生した
再起動、recoveryOS、Share Diskも通用しない
- キャッシュ整理を期待して再起動したが、Macはもう正常に起動しなくなった
- 進行バーが半分ほどまで進んだところで失敗する状態が繰り返された
- recoveryOSで起動ボリュームがマウントされていない状態のまま、Disk Utilityの修復や再インストール関連の作業を試したが、Terminalコマンドは同じエラーを返した
- Apple siliconのShare Disk機能でそのドライブを別のMacにマウントしようとした
- Sambaベースのディスク共有経由で削除を強制しようとしたが失敗した
Time Machine復元中にも続いた障害
- 前夜のバックアップを含むTime Machineバックアップがあり、重要データの大半はクラウドにあったため、完全復旧に強くこだわる状況ではなかった
- まずドライブを消去し、macOS RecoveryからMacBook Pro出荷時の標準システムであるVenturaを再インストールした
- macOS起動時にMigration Assistantでネットワーク上のTime Machineバックアップへアクセスし、十分な空き容量を残すため一部の復元項目を外した
- 復元の途中でVenturaが中断し、その後再開しなかった
- その後、Macを当時使っていたmacOSであるSonomaへアップグレードした
- アップグレード自体は成功したが、インストールされたバージョンは14.4だった
- 以前のMacには14.3.1がインストールされていた
- 初期セットアップ段階で直接復元しようとすると、バージョン差のため許可されなかった
Sonoma 14.4のネットワークTime Machineマウント問題
- まずSonomaの基本ユーザーアカウントを作成してからMigration Assistantを実行した
- Migration AssistantはTime Machineバックアップを管理しているネットワーク上のMacを見つけて認識した
- しかし子どものバックアップボリュームをマウントできず、繰り返し「Mount failed」と表示された
- フォーラム検索の結果、SonomaではSMB/Sambaベースのネットワークマウント手順がTime Machine復元で壊れており、解決策は見つからなかった
- この問題はmacOS 14.4でもなお当てはまるようだった
最終的な復旧: バックアップを外付けSSDへコピーして手動移行
- 完全なMigration Assistant復元はあきらめ、必要なアプリとファイルだけを手動で復旧した
- ネットワークバックアップを管理しているMacで、そのコンピュータのディスクイメージをダブルクリックし、Time Machineボリュームのパスワードを入力した
- ネットワークTime Machineボリュームには常に別個のパスワードを設定してあった
- 最新タイムスタンプの付いたディスクアイコンを見つけ、空の外付け1TB SSDへコピーした
- その外付けSSDをMacBook Proの一時アカウントに接続し、必要なファイルを移した
- ホームディレクトリ内のフォルダの大半の内容が含まれていた
- 大きなダウンロードファイルと不要な動画ファイルの一部は除外した
- 外付けSSDは、欠けているファイルがあった場合に追加復旧できるよう、しばらく保管することにした
試せなかった代替策
- ネットワークバックアップ用Time Machineドライブをバックアップ管理Macでアンマウントしたうえで、子どものMacに直接接続することもできた
- その場合、Migration Assistantの移行元として表示された可能性がある
- マウントしたTime Machineディスクイメージから仮想ディスクをコピーし、外付け1TB SSDをMacのソースボリュームのように見せることもできたかもしれない
- この方法が実際に機能したかどうかは確認されていない
- 成功していればMigration Assistantで直接復元できた可能性があった
- すでに数時間の作業と1日以上の試行が積み重なっており、ユーザーも完璧なディレクトリ単位の復旧を強く望んでいなかったため、これ以上の実験は行わなかった
1件のコメント
Hacker News のコメント
投稿者は外部ストレージデバイスから Mac を起動してから内蔵ディスク上の不要なファイルを削除していれば、もっとよかったかもしれない: Use an external storage device as a Mac startup disk
Apple Silicon 搭載 Mac では、外部起動時にすべてのポートが同等ではないという点が意外だった
ストレージデバイスに macOS をインストールする際、Mac ノートブックでは左側ポートのうち一番左の USB-C ポートを避ける必要があり、iMac/Mac mini/Mac Studio/Mac Pro でもモデルごとに避けるべき USB-C ポートが別にある
インストール後はどのポートに接続してもよいとのこと
投稿者は別パーティションである recoveryOS で起動した後、メインのシステムパーティションからファイルを削除しようとしたが、
rmが同じNo space left on deviceエラーで失敗したなので、ほかの人が言っていたように
echo -n >fileでファイルを切り詰める方法なら動いた可能性があるHFS+ のディスク構造について少し知っている範囲で推測すると、ジャーナルファイルも満杯になっており、削除にはジャーナルへの書き込みと、場合によっては拡張が必要なので、削除そのものが一時的にでもさらに多くの空き容量を要求するという奇妙な状態になったように見える
macOS はドライブに 41KB しか残らなくなるまでファイルを書き続けた
NTFS と FAT32 を誤って 0 バイトまで埋めたことがあるが、そのときでも何かを削除することはできた
フォーラムを見て回ると、Sonoma が Time Machine 復元用の SMB/Samba ベースのネットワークマウント手順を壊しており、14.4 でもまだ解決策はないようだ
経験上、SMB は 10.12〜10.13 あたりから信頼しづらく、バグが多すぎるものになっており、今では Apple はこれが動作するかどうかさえ気にしていないように見える
何十年もの Mac 経験がない人たちが、こうした連鎖的なシステム障害に遭遇したらどうするのか、想像したくない
何十年もの Mac 経験はないが、この状況ならまず
fsckを試したはずで、ここで言及されていないのが不思議だディスクの内容を別のディスクへコピーしてからフォーマットし、戻すことができないなら、APFS のドキュメント(https://developer.apple.com/support/downloads/Apple-File-System-Reference.pdf)を見ながら、
ddと 16進エディタでどこを修正すれば空き容量を作れるか探すと思うその後、ガベージコレクションがアクティブなツリーにもう属していないファイルを見つけ、ストレージ領域へ戻す
通常はツリーの変更量を扱える範囲に抑えるため、変更をまとめて処理し、この設計のおかげでファイルシステムのスナップショットは特定のツリーへのもう一つの参照になる
この過程には空き容量が必要だが、CoW ファイルシステムは通常、こうした理由で緊急用のストレージ領域を別に予約している
数年前、10GbE で大きな NAS に接続した Hackintosh 上で BlackMagic Disk Speed Test を使って測定したところ、Windows の SMB は 900MB/s、macOS の SMB は 200MB/s、macOS の NFS と AFP はどちらも 1000MB/s だった
プロの作業に関係する macOS の機能は、残念ながら笑ってしまうレベルだ
AFP は死んだと言われているが、私の Mac Pro ではクライアントとして今でも問題なく動作しており、SMB より性能が良すぎて、ほとんどコメディのように感じる
最後まで満杯にすると問題が起きる可能性がある
BTRFS はメタデータ領域がまだ残っているうちに読み取り専用へ切り替えようとするので、セーフモードで再マウントして何かを削除できるようにしてくれるが、完全な防護策ではない
NTFS と FAT32 は、私の知る限りジャーナリングファイルシステムではない
最初の職場でこれを経験したことがある
誤ってクラスタをジョブファイルでいっぱいにしてしまい、システム管理者が早く直せとメールを送り始めたが、
rmが動かなかったそのとき、削除できない場合でも ファイルの切り詰め はたいてい可能だと学んだ。なので
rm fooがだめなときでも、cat /dev/null > fooで済むことが多い:>filepathがよく効くただしファイルシステムによってはそれもできない場合がある
その場合は、ファイルシステムがサイズ拡張、サイズ縮小、一時的な追加ストレージに対応しているか、下位システムでバックエンドストレージを追加・削除できることを期待するしかない
btrfs のように、単一ブロックデバイス用の構成へ戻すために別のコマンドが必要になることもある
そこでバックアッププロセスが定期的にゴミデータを /dev/null へ直接送るようにした。おそらくその汚いハックは今も動いているはず
/dev/nullは魔法のような存在なので、一度読んでみる価値がある>fileだけでもよい21世紀のファイルシステム形式は UFS よりはるかに複雑で、スナップショットやジャーナリングのような機能のために、ファイルシステムが自らデッドロックに陥る新しい経路が生まれている
結局
truncateで復旧しなければならなかったZFS がこういう状況に強いことは知っていたが、それでも本当にやらかしたと感じたときの「ああ……まずい」という沈み込む感覚はそのままだった
Time Machine は着実に悪くなっているように思う
なぜ安定して正しく動くようにする動機がないのか分からない
sparse bundle が壊れて新しいバックアップを始めなければならなかったり、機能が失敗したりすることを経験していると、今では Time Machine を設定する価値はあまりないと感じる
毎回うまく動いていた iOS/iPadOS のバックアップとはまったく対照的だ
Apple は人々がすべてを iCloud にバックアップして、サービス売上を伸ばすことを望んでいる
複数の Mac で Samba 共有上の Time Machine を何年も動かしているが、むしろ改善しか見ていない
以前は Time Machine の sparse bundle がよく壊れ、新しく作り直すか、以前の ZFS スナップショットを復元して継続する必要があった
そのころは SMB ではなく AFP だったと思う
最近はどの機器でもこうした問題はなく、Time Machine バックアップ用に推奨されている特定のフラグを
smb.confで有効にしてはいる逆に ZFS には、大きな作業中に空き容量が尽きてファイルシステムが固まるのを避けるための slop space がある
デフォルトではボリューム容量の 3.2% を最大 128GB まで予約する
そのため Linux カーネル調整値である
spa_slop_shiftを変更して slop space を減らせば、ファイル削除処理を正常に終えるためのボーナス空間を最大 128GB まで取り戻せる: https://openzfs.github.io/openzfs-docs/Performance%20and%20Tuning/Module%20Parameters.html#spa-slop-shiftこのような理由から、ディスク容量の一定割合を予約する機能は、ZFS や Linux が存在する何十年も前から「本物の」ファイルシステムではよくある機能だった
1980年代の MS-DOS シェアウェアの端末プログラムの大半は、帯域の限られた接続でのファイルダウンロードを非常にうまくこなしていたのに、現在の MS Windows はその程度であるはずの作業すらひどい、というのに少し似ている
詳しくは
man tune2fsを見ればよい現代的な、あるいはそれほど現代的でない他の大半のファイルシステムも同様だ
記憶では、1980年代の SunOS の UFS もそうだった: https://en.wikipedia.org/wiki/SunOS
何かを削除するのに、実際には一時的であれ永続的であれ、より多くの容量が必要になることがある、という考えを人々は理解しにくい
他のコメントでは、スナップショットやジャーナリングのような現代的なファイルシステムが、削除のために空き領域から割り当てる必要がある理由を詳しく扱っている
他の分野でも同様に、Wikipedia の初期10年間には、ページを削除してサーバー容量を節約しようとする試みは実際には逆効果になる、と頻繁に説明する必要があった
少なくとも2004年ごろ以降、削除は内部データベースにレコードを追加していたからだ
Rahul Dhesi の ZOO アーカイブ形式では、項目の削除はヘッダーレコードにフラグを立てるだけであり、新しいバージョンを追加しても以前のバージョンを上書きしない VMS 式のファイルバージョン管理もあった
MS/DR/PC-DOS と FAT の時代には、削除復元ユーティリティがインストールされていると、ファイル削除時に復元情報を含むデータベースへ新しい項目を保存するため、より多くの容量が必要になることがあった
古いディスク圧縮ユーティリティの一部はメタデータまで圧縮していたため、メタデータ変更によって圧縮率が変わり、外部から見えるボリュームサイズが実際に増えるというまれな状況も起こり得た
削除すれば空き容量が増える という考えは広く浸透しているが、厳密には常に正しいわけではない
2018年10月に同じ問題に遭遇し、以下の Stack Overflow の質問に残しておいた
幸い、削除できる追加の APFS パーティションがあったので、ディスク容量を確保できた
それを突き止めるまでにかなり時間がかかり、その間は本当にパニック状態だった
https://apple.stackexchange.com/questions/338721/disk-full-terminal-in-recovery-mode-won-t-delete-files-boot-kernel-panics
macOS Mojave をアップデートした直後、
.dmgを作っている途中でディスクを満杯にしてしまい、システムが固まった再起動するとカーネルパニックが起き、リカバリーモードで起動してディスクをマウントし、ターミナルで
rm /path/to/large/fileを実行したが、No space left on deviceと表示された本質的には 2008 年の Unix スレッドと同じ問題だった: https://www.unix.com/linux/69889-unable-remove-file-using-rm-disk-space-full.html
echo x > /path/to/large/fileも役に立たず、「ドライブを消去してバックアップから復元せよ」以外の提案が必要だった昔の Unix ファイルシステムが root 用に 5% を予約していたのに似ている
仮想メモリパーティションを削除すれば、十分な大きさがあるという前提で、ファイル削除が可能になるだけの空き容量を取り戻せるかもしれない
コンテナは実際に使われるときだけ割り当てられるためだ
印象的だ
rmすら失敗する状況は経験したことがないが、内蔵ストレージが 256GB 以下の最近の Mac を使い、管理する不快さは経験したなので、約 16GB の プレースホルダーファイルを作っておくようにしている
どうせ容量が埋まってアップデートやほかの作業を妨げるなら、
ncduで外科手術のように整理しなくても、そのファイルを消すだけで済むたとえば従業員や機材の 1 時間分のコストで、既存の 4 倍大きい新しいドライブを買う、といった具合だ
iPhone でも似たようなことを経験した
ディスクがあまりにも満杯で、何かを削除しても実際には何も起きていないように見えた
再起動するとログインできず、もう一度再起動するとブートループに陥った
さらにもう一度再起動すると、ホーム画面にはアプリアイコンが残っているのに実際のアプリは消えていて、アイコンが空で起動もできないという不整合な状態で起動した
データの整合性が心配になり、結局バックアップから復元した
これは APFS がコピーオンライト方式で、スナップショットをサポートしているために起きた結果だと確信している
変更がすぐに永続反映されず、ファイルの以前のバージョンがスナップショットに残るなら、スナップショットのメタデータ用の領域すらないと困ったことになる
ディスク容量が不足していればスナップショットをスキップすることもできるかもしれないが、それでも CoW メタデータの問題は残る
2024 年にもなって賢い APFS ボリューム管理機能がすべてあるのに、ユーザー領域を埋めるだけで iPhone のような「封印された」デバイスを DFU 復元が必要な状態にできるというのは驚きだ
逆に、単一のデータ/ブートボリュームを使う Windows 11 の業務用ノート PC でうっかり容量を満杯にしたときは、それでも起動して問題を片付けることができた
少し前、Linux インストールのシステムパーティションでも似た状況に遭遇した
そもそもパーティションが小さすぎ、アップデートが積み重なって、何かを削除し始めるための領域すらほとんどなくなっていた
ほんの少しでも削除できるサブディレクトリを見つけるのに 30 分ほどかかった
内開きのドアを開けられないほどガラクタでいっぱいの部屋に閉じ込められたような気分だった
その小さな足がかりから、だんだんより大きな領域を削除できるようになり、最終的に整理した後は二度とそうならないようパーティションサイズを増やした
熟練ユーザーなら、パーティションの後ろに常に少し 未割り当て領域を残しておくべき、という教訓になりそうだ