2 ポイント 投稿者 GN⁺ 2024-04-05 | 1件のコメント | WhatsAppで共有
  • M2 MacBook Proの起動ボリュームがSteamでゲームをダウンロード中に残り41KBになるまで埋まり、macOSがファイル削除すらできない状態に陥った
  • Finderのゴミ箱を空にする操作、Terminalのrmfind -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件のコメント

 
GN⁺ 2024-04-05
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 でファイルを切り詰める方法なら動いた可能性がある
    • ファイルシステム自体がデッドロックに陥っていたなら、どこから起動してもファイルシステムドライバ経由でファイルを削除する方法は通用しない
    • recoveryOS や Mac Share Disk/Target Disk モードでも駄目だったのに、なぜその方法ならうまくいくと考えるのか気になる
    • こういうコメントは、8年後に当時としては古い Mac の問題を解決しようと検索している誰かにとって、本当にありがたいものになりそう
    • Mac ノートブックで起動可能な OS を作るとき、なぜ最初の USB-C ポートを使ってはいけないのか、知っている人がいるのか気になる
  • 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)ファイルシステムでは、すべての変更は新しいファイルツリーを作ってから、ルートがその新しいツリーを指すようにする形で行われる
      その後、ガベージコレクションがアクティブなツリーにもう属していないファイルを見つけ、ストレージ領域へ戻す
      通常はツリーの変更量を扱える範囲に抑えるため、変更をまとめて処理し、この設計のおかげでファイルシステムのスナップショットは特定のツリーへのもう一つの参照になる
      この過程には空き容量が必要だが、CoW ファイルシステムは通常、こうした理由で緊急用のストレージ領域を別に予約している
    • Apple は Samba が GPLv3 を採用した後、かなり前に独自実装へ切り替えた: https://lists.samba.org/archive/samba-announce/2007/000122.html, https://www.engadget.com/2011-03-24-apple-to-drop-samba-networking-tools-from-lion.html
    • Apple らしく、SMB の性能は数年前にはひどく遅く、最近でもようやく我慢できる程度にすぎず、同じハードウェア上の NFS や、皮肉にも Appleshare よりずっと遅い
      数年前、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 と ZFS でも同じことは起こり得る
      最後まで満杯にすると問題が起きる可能性がある
      BTRFS はメタデータ領域がまだ残っているうちに読み取り専用へ切り替えようとするので、セーフモードで再マウントして何かを削除できるようにしてくれるが、完全な防護策ではない
      NTFS と FAT32 は、私の知る限りジャーナリングファイルシステムではない
    • 今のところ、これが唯一まともな技術的説明のように見える
  • 最初の職場でこれを経験したことがある
    誤ってクラスタをジョブファイルでいっぱいにしてしまい、システム管理者が早く直せとメールを送り始めたが、rm が動かなかった
    そのとき、削除できない場合でも ファイルの切り詰め はたいてい可能だと学んだ。なので rm foo がだめなときでも、cat /dev/null > foo で済むことが多い

    • シェルでは :>filepath がよく効く
      ただしファイルシステムによってはそれもできない場合がある
      その場合は、ファイルシステムがサイズ拡張、サイズ縮小、一時的な追加ストレージに対応しているか、下位システムでバックエンドストレージを追加・削除できることを期待するしかない
      btrfs のように、単一ブロックデバイス用の構成へ戻すために別のコマンドが必要になることもある
    • 数年前、ファイルシステムへ常に書き込める必要がある中核インフラが、デッドロック状態になって復旧不能に壊れかねない状況があった
      そこでバックアッププロセスが定期的にゴミデータを /dev/null へ直接送るようにした。おそらくその汚いハックは今も動いているはず
      /dev/null は魔法のような存在なので、一度読んでみる価値がある
    • 実際には単に >file だけでもよい
    • ただし、ここにある複数のコメントのように 切り詰めすら失敗する 状況もある
      21世紀のファイルシステム形式は UFS よりはるかに複雑で、スナップショットやジャーナリングのような機能のために、ファイルシステムが自らデッドロックに陥る新しい経路が生まれている
    • Samba のログレベルをデバッグのために高くしすぎ、その後戻すのを忘れて、巨大なログファイルで ZFS ルート SSD をいっぱいにしたことがある
      結局 truncate で復旧しなければならなかった
      ZFS がこういう状況に強いことは知っていたが、それでも本当にやらかしたと感じたときの「ああ……まずい」という沈み込む感覚はそのままだった
  • Time Machine は着実に悪くなっているように思う
    なぜ安定して正しく動くようにする動機がないのか分からない
    sparse bundle が壊れて新しいバックアップを始めなければならなかったり、機能が失敗したりすることを経験していると、今では Time Machine を設定する価値はあまりないと感じる
    毎回うまく動いていた iOS/iPadOS のバックアップとはまったく対照的だ

    • もう Time Capsule を売っていないからだ
      Apple は人々がすべてを iCloud にバックアップして、サービス売上を伸ばすことを望んでいる
    • Mac を使っていない立場から見ると、これはペンギンのマスコットがいるか、本社がワシントン州にあるデスクトップ OS だったなら、ものすごい非難を呼んだであろう 壊滅的で弁解不能なバグ のように聞こえる
    • Time Machine が突然もう働きたくないと決めて、バックアップを消して最初からやり直さなければならなかった回数が多すぎる
    • macOS の品質管理は Scott Forstall を解雇してから低下してきたし、実のところ彼がいた時代でも驚くほどの水準ではなかった
    • 自分の経験は違う
      複数の 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 はその程度であるはずの作業すらひどい、というのに少し似ている
    • ext4 にも同じ機能があり、ただし名前は reserved blocks と呼ばれている
      詳しくは 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 も役に立たず、「ドライブを消去してバックアップから復元せよ」以外の提案が必要だった

    • 1GB 程度の小さな 追加パーティションを作っておくのは、よい保険になるかもしれない
      昔の Unix ファイルシステムが root 用に 5% を予約していたのに似ている
    • その StackExchange の投稿には、その後ほかの潜在的な解決策も付いた
      仮想メモリパーティションを削除すれば、十分な大きさがあるという前提で、ファイル削除が可能になるだけの空き容量を取り戻せるかもしれない
    • APFS ではそれほど単純ではない
      コンテナは実際に使われるときだけ割り当てられるためだ
  • 印象的だ
    rm すら失敗する状況は経験したことがないが、内蔵ストレージが 256GB 以下の最近の Mac を使い、管理する不快さは経験した
    なので、約 16GB の プレースホルダーファイルを作っておくようにしている
    どうせ容量が埋まってアップデートやほかの作業を妨げるなら、ncdu で外科手術のように整理しなくても、そのファイルを消すだけで済む

    • CockroachDB もノード起動時に同じことをしているのを見た: https://www.cockroachlabs.com/docs/v23.2/cluster-setup-troubleshooting#automatic-ballast-files
    • プレースホルダーファイルの大きな利点は、必要なときにその領域を解放して 長期的な解決策を実行する時間を稼げることだ
      たとえば従業員や機材の 1 時間分のコストで、既存の 4 倍大きい新しいドライブを買う、といった具合だ
  • iPhone でも似たようなことを経験した
    ディスクがあまりにも満杯で、何かを削除しても実際には何も起きていないように見えた
    再起動するとログインできず、もう一度再起動するとブートループに陥った
    さらにもう一度再起動すると、ホーム画面にはアプリアイコンが残っているのに実際のアプリは消えていて、アイコンが空で起動もできないという不整合な状態で起動した
    データの整合性が心配になり、結局バックアップから復元した
    これは APFS がコピーオンライト方式で、スナップショットをサポートしているために起きた結果だと確信している
    変更がすぐに永続反映されず、ファイルの以前のバージョンがスナップショットに残るなら、スナップショットのメタデータ用の領域すらないと困ったことになる
    ディスク容量が不足していればスナップショットをスキップすることもできるかもしれないが、それでも CoW メタデータの問題は残る

    • 自分もまったく同じことを経験した
      2024 年にもなって賢い APFS ボリューム管理機能がすべてあるのに、ユーザー領域を埋めるだけで iPhone のような「封印された」デバイスを DFU 復元が必要な状態にできるというのは驚きだ
      逆に、単一のデータ/ブートボリュームを使う Windows 11 の業務用ノート PC でうっかり容量を満杯にしたときは、それでも起動して問題を片付けることができた
  • 少し前、Linux インストールのシステムパーティションでも似た状況に遭遇した
    そもそもパーティションが小さすぎ、アップデートが積み重なって、何かを削除し始めるための領域すらほとんどなくなっていた
    ほんの少しでも削除できるサブディレクトリを見つけるのに 30 分ほどかかった
    内開きのドアを開けられないほどガラクタでいっぱいの部屋に閉じ込められたような気分だった
    その小さな足がかりから、だんだんより大きな領域を削除できるようになり、最終的に整理した後は二度とそうならないようパーティションサイズを増やした

    • 最初からパーティションを拡張しなかった理由が気になる
      熟練ユーザーなら、パーティションの後ろに常に少し 未割り当て領域を残しておくべき、という教訓になりそうだ