はじめに
Community Radio には夜の番組用の音声がありますが、小さな素材ディスクがいっぱいです。管理者は大きなアクセスログの名前をすでに削除しました。アーカイブは配信できるのに、容量は戻りません。大切な録音を消しても本来の原因は解決しません。
Nginx が保持しているファイルを見つけ、文書化されたログ再オープン信号を使い、元のサービスを動かしたまま新しい音声全体を保存して再生します。必要なのは基本的な端末経験だけです。C、デバイスのフォーマット、ストレージ設定は不要です。素材は練習用の英語合成音声です。
コマンドには Workstation、試聴には Radio Player を使います。各ラボは独立した障害を準備します。/home/labex/project/radio 内だけで操作し、確認済みのラジオ master だけに信号を送ってください。無関係なプロセスは学習基盤のものです。
放送局を止めずに容量を回収する
このステップでは、満杯のファイルシステムを特定の削除済みファイルに結び付け、放送局を稼働させたままブロックを回収します。
保護すべき音声を聴く
Radio Player を開き、Archive recording、次に Incoming clip を再生します。アーカイブは素材ディスク内、受け入れ予定の音声は外にあります。3 番目のプレーヤーにはまだ完全な保存済み録音がありません。これは合成した練習音声であり、生のマイクや実際のインタビューではありません。
Workstation では pwd が現在位置、ls がディレクトリエントリを表示します。準備済み放送局ディレクトリから始まります。必要なら cd で戻ります。
cd /home/labex/project/radio
pwd
/home/labex/project/radio
ls
media/ が独立ディスクです。incoming/ はインスタンスの通常ファイルシステム上にあります。services/ には本コースの 2 つの Nginx 設定と master の PID ファイルがあります。media.ext4 は LabEx が用意した固定サイズの backing file なので変更しません。ファイルシステムを作成したりマウント設定を編集したりする必要はありません。
失敗と対象範囲を確認する
findmnt -T はパスが属するファイルシステムを表示します。対象は正確に media ディレクトリ、ソースは /dev/loop... デバイス、種類は ext4 のはずです。ルートファイルシステムは別のソースです。loop デバイスは、この容量制限付きディスクイメージをブロックデバイスとして見せます。
findmnt -T media -o TARGET,SOURCE,FSTYPE
findmnt -T incoming -o TARGET,SOURCE,FSTYPE
cp はファイルをコピーします。次のコピーは意図的に No space left on device で失敗する想定です。不完全なコピー先が残る場合があります。これらのファイルに不要な sudo は使いません。
cp incoming/evening-recording.wav media/recordings/evening-recording.wav
これは小さな素材ファイルシステムで起きる実際の容量不足です。元のアーカイブは保護されます。df -h はブロック容量を読みやすい単位で表示します。du -xsh はディレクトリ下で名前から到達できる割り当て済みブロックを合計します。-x は同じファイルシステム内、-s は合計、-h は読みやすい単位です。
df -h media
du -xsh media
df はほぼ全容量の使用を示し、du は少量しか見つけません。両者は別の対象を測ります。この違いだけでは原因を特定できません。メタデータ、予約ブロック、権限、別のマウントビューなども影響します。
実際の保持プロセスを探す
ディレクトリエントリは名前を inode、つまりファイルシステム内のファイル記録に対応させます。ハードリンク数は、その inode を指す名前の数です。プロセスはさらに開いているファイル記述子という番号付き参照を保持できます。最後の名前を削除するとリンク数はゼロになりますが、最後の開いた参照を閉じるまでブロックは残ります。
lsof は開いているファイルを一覧にします。Nginx の master は root なので、読み取り専用の調査に sudo を使います。-nP はホスト名・ポート名の解決を避け、+L1 はリンク数が 1 未満、+f -- media は media を含むファイルシステム、-a は条件の積集合です。この絞り込みを維持してください。全体の一覧には無関係な削除済みメモリファイルや基盤プロセスも出ます。
sudo lsof -nP -a +L1 +f -- /home/labex/project/radio/media
media/logs/access.log (deleted) に対応する Nginx の 2 行、master と worker が表示されるはずです。PID、FD、DEVICE、SIZE/OFF、NLINK、NODE を読みます。デバイスと inode が同じで、NLINK はゼロです。同じファイルのサイズなので足し合わせません。4w なら記述子 4 が書き込み用に開かれています。名前が消えていても、デバイス/inode はこのファイルシステムのファイルを識別できます。
cat はテキストを表示します。実際の設定と master の PID ファイルを読みます。pid と access_log のパスが、この放送局と削除済み素材ログに対応する必要があります。
cat services/studio/nginx.conf
cat services/studio/nginx.pid
次の MASTER はシェル変数です。$(...) はコマンド出力を取得し、二重引用符は値を 1 つの引数に保ちます。ps は選択したプロセス、-o は列、-p はその PID、--ppid はその子も選択します。絞り込んだ lsof の master であり、設定パスも本コースのものか確認します。もう一方は worker で、親 PID がこの master です。
MASTER=$(cat services/studio/nginx.pid)
ps -ww -o pid,ppid,user,args -p "$MASTER" --ppid "$MASTER"
マウント、パス、master の識別が違う場合は操作しません。PID を推測したり全 Nginx に信号を送ったりせず、ディレクトリと設定を再確認します。
このプログラムに再オープンを依頼する
信号の意味はプログラム次第です。Nginx は USR1 をログファイルの再オープンとして文書化しています。古い参照を閉じ、設定された名前を開き直します。TERM は停止、HUP は別の再読み込み動作です。man nginx で手元の文書を開き、SIGNALS を探し、q で戻ります。Nginx の制御文書 にも同じ契約があります。
man nginx
kill は名前付きの信号を送れます。必ずしも終了の意味ではありません。この root master への送信には sudo が必要です。確認した master だけに、文書化された信号を送ります。
sudo kill -USR1 "$MASTER"
容量、保持プロセス、master を再確認します。再オープンは非同期です。保持行が一時的に残るなら、少し待って読み取り専用の確認を繰り返します。
df -h media
sudo lsof -nP -a +L1 +f -- /home/labex/project/radio/media
ps -ww -o pid,ppid,user,args -p "$MASTER" --ppid "$MASTER"
空き容量が戻り、削除済み素材ログの行が消え、同じ master PID が残るはずです。ここでは絞り込んだ lsof の結果が空でも正常です。放送局を止めたり別のファイルシステムのファイルを解放したりしていません。
curl -fsS は URL を読み、HTTP エラーなら失敗し、必要なら短いエラーを表示します。この通常リクエストがまだ動く必要があります。tail -n 2 で新しい名前のアクセスログの末尾 2 行を見ます。
curl -fsS http://127.0.0.1:8080/on-air.txt
tail -n 2 media/logs/access.log
Community Radio: archive and live programme remain available. と新しい GET /on-air.txt ログが見えるはずです。元のプロセスが新しい名前のログを書いています。容量が戻らなければ保持者を再確認します。アーカイブ削除、記述子の切り詰め、サービス停止、マウント作り直しはしません。新しいログがなければ未変更の設定を確認し、正しい master に文書化された再オープンをもう一度依頼します。
完全な録音を保存して使う
このステップでは、失敗した部分コピーを受信予定音声全体で置き換え、バイトを確認し、稼働中の放送局から使います。
待機中のソースとアーカイブは別の役割なので、両方を保存します。同じ宛先への cp 再実行は失敗時の部分ファイルを置き換え、ソースは変更しません。
cp incoming/evening-recording.wav media/recordings/evening-recording.wav
cmp は全バイトを比べ、一致すれば何も表示しません。コピー直後に確認します。
cmp incoming/evening-recording.wav media/recordings/evening-recording.wav
sha256sum は内容の指紋を表示します。同じハッシュはもう 1 つの比較手段です。採点も元のアーカイブとソースを準備時のバイトに照合します。
sha256sum incoming/evening-recording.wav media/recordings/evening-recording.wav
2 行のハッシュは同じでなければなりません。名前やサイズがもっともらしくても、ゼロ埋めやスパースファイルは録音ではありません。別ファイルシステムへのコピーも素材の引き渡しを完了しません。
findmnt -T media/recordings/evening-recording.wav -o TARGET,SOURCE,FSTYPE
元の独立 ext4 素材マウントのままであることを確認します。放送局が実際の保存ファイルを配信できるか試します。-o は curl に素材ディスク外への保存を指示します。そのレスポンスと待機音声を比べます。
curl -fsS http://127.0.0.1:8080/recordings/evening-recording.wav -o /tmp/radio-delivered.wav
cmp incoming/evening-recording.wav /tmp/radio-delivered.wav
Radio Player に戻って再読み込みし、Your saved recording を再生して末尾付近へ移動し、結びの文を聴きます。Archive recording も再生し、Download saved recording で保存済み録音をダウンロードします。Read the on-air message に進むと放送局メッセージがまだ表示されるはずです。ブラウザ音声にはユーザーの再生操作が必要で、バイト保存だけでは再生しません。
形式やネットワークのエラーなら、ソースと宛先を再比較し URL を確認します。満杯時のコピーは WAV ヘッダーやデータが切れる場合があります。回復後に未変更のソースをコピーし直します。不一致時にヘッダーを修理したり、壊れた宛先に合わせてソースを変えたりしません。
df -h media
十分な空き容量と完全な保存音声があるはずです。採点は最終ファイル、マウント識別、開いた記述子、実際のサービス状態を読むだけです。信号送信、音声コピー、ファイル修復、代わりの録音作成は行いません。
まとめ
名前、inode、開いている記述子を区別し、実際のディスク容量を回収しました。ファイルシステムで絞った調査によって削除済みログを正しい Nginx master に結び付け、文書化された USR1 でプロセスを置き換えずに古い参照を解放しました。その後、アーカイブとサービスを守りながら音声全体を保存、比較、ダウンロード、再生しました。
df/du の違いは手掛かりであって診断ではありません。再オープン動作はプログラムごとに異なるため、信号の前に文書を確認します。この練習は独立 ext4 ディスクと合成音声を使い、フォーマット、任意プロセスの終了、完全なログローテーション方針は扱いません。



