ps aux を見たら STATUS 列が D のプロセスがいくつも並んでいる。kill -9 を打っても一向に消えないし、サーバーのレスポンスが次第に落ちていく。」D 状態のプロセスはシグナルを受け付けないため、root 権限でも強制終了できない。放置するとシステムの I/O キューが詰まり、後続プロセスも連鎖して D 状態に陥るケースがある。
この記事では、Linux の D 状態(TASK_UNINTERRUPTIBLE)が発生する仕組みと、
ps や /proc/[pid]/wchan を使った原因の切り分けから対処までを解説する。NFS ハングとストレージ I/O 待機のどちらが原因かを素早く判断し、ハングしたマウントを強制解除するまでの手順を順番に押さえる。想定環境は RHEL 9系/Rocky Linux 9系/AlmaLinux 9系および Ubuntu 24.04 LTS とする。この記事のポイント
・D状態(TASK_UNINTERRUPTIBLE)プロセスはkill -9を受け付けない
・/proc/[pid]/wchanでカーネル内の待機場所を素早く特定できる
・NFSハングには「soft,timeo」オプションと強制アンマウントで対処する
・dmesgのI/Oエラーとiotopでストレージ障害を早期発見できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
D状態(TASK_UNINTERRUPTIBLE)とは何か
Linux のプロセスは実行中に複数の状態を持つ。ps aux の STAT 列で確認できる主な状態は次のとおりだ。・R(Running):CPU で実行中、または CPU 待ちキューにある
・S(Sleeping):割り込み可能なスリープ。シグナルや I/O 完了を待っており、kill 可能
・D(Disk sleep):割り込み不可のスリープ(TASK_UNINTERRUPTIBLE)。I/O 完了やカーネルロック解放を待っており、シグナルを無視する
・Z(Zombie):終了済みだが親プロセスの wait() 呼び出しを待っている
・T(Stopped):SIGSTOP や SIGTSTP で停止中
D 状態の本質は「カーネルが意図的にシグナルを遮断した状態」だ。I/O 応答を中途で受け取るとデータ破損の恐れがあるため、カーネルはシグナルを無視しながら I/O 完了を待つ。通常は数ミリ秒以内に解消される。数分以上続く D 状態は何らかの異常を示している。
D状態になる主な原因
・NFS マウントのハング:NFS サーバーがダウンするか、ネットワーク断が発生した場合、hard マウントオプション(デフォルト)の NFS にアクセスしているプロセスが永続的に D 状態になる。運用現場で最も頻度が高い原因だ・ストレージデバイスの異常:HDD/SSD の I/O が応答しなくなった場合、read/write を待つプロセスが D 状態に陥る。障害発生したディスクへのアクセスが続くほどプロセスが蓄積する
・カーネルロックの競合:稀なケースだが、カーネルのバグや特定ドライバーの不具合でロック解放が起きないことがある
・loopback NFS:同一ホストに対してループバック構成の NFS を組んでいる環境でも発生する
D状態プロセスの検出手順
まず STAT 列が D になっているプロセスを洗い出す。# D状態プロセスを一覧表示する $ ps aux | awk '$8 == "D" { print }'
watch コマンドで定期的に確認しながら推移を観察する。増加中であれば障害原因がまだ解消されていないと判断できる。# 10秒ごとにD状態プロセスを監視する $ watch -n 10 'ps aux | awk '\''$8 == "D" { print }'\'''
/proc/[pid]/ で原因を深掘りする
D 状態プロセスの PID がわかったら、/proc/[pid]/ 以下のファイルを確認して待機場所を特定する。1. wchan でカーネル内の待機場所を確認する
/proc/[pid]/wchan には、プロセスがカーネル内のどの関数で待機しているかが表示される。トラブルシューティングで最初に読むファイルだ。# PID=1234 のプロセスが待機している関数を確認する(要root) $ cat /proc/1234/wchan nfs_wait_on_requests
nfs_wait_on_requests と表示された場合は NFS の I/O 待ちが原因だ。代表的な wchan 出力と意味は次のとおりだ。・
nfs_wait_on_requests / nfs_read_data:NFS の I/O 待ち・
jbd2_journal_commit_transaction:ext4 のジャーナルコミット待ち・
blk_mq_get_tag:ブロックデバイスのリクエスト待ち(ストレージ障害を疑う)・
schedule:汎用ロック待ち(詳細は後述の /proc/[pid]/stack で追う)2. status でプロセスの状態を確認する
# プロセスの詳細情報を確認する $ cat /proc/1234/status | head -5 Name: cp State: D (disk sleep) Tgid: 1234 Pid: 1234 PPid: 1200
State: D (disk sleep) となっていれば D 状態が確定する。3. fd で開いているファイルを確認する
# PID=1234 が開いているファイルを確認する $ ls -la /proc/1234/fd lrwxrwxrwx 1 user user 64 ... 3 -> /mnt/nfs/data/file.log lrwxrwxrwx 1 user user 64 ... 4 -> socket:[12345]
/mnt/nfs/)配下のパスがあれば NFS ハングが原因である可能性が高い。Linux ポート確認の全コマンドで紹介している lsof -p 1234 でも同じ情報を確認できる。NFSハング時の対処
wchan がnfs_xxx を示し、fd に NFS パスが見つかった場合は NFS ハングが原因だ。1. NFS サーバーへの疎通確認
まず NFS サーバーに到達できるかを確認する。# NFS サーバーへの疎通確認 $ ping -c 4 192.168.1.10 # NFS ポート(2049/TCP)の確認 $ nc -zv 192.168.1.10 2049
2. NFS マウントの強制切り離し
通常のumount は EBUSY で失敗するため、umount -l(lazy umount)を使う。mount コマンドの使い方で解説しているとおり、-l オプションはファイルシステムを名前空間から即座に切り離し、使用中のプロセスが終了した段階でクリーンアップされる。# lazy umount で NFS を強制切り離し # 注意: 書き込み中のデータは失われる可能性がある。本番適用前に影響範囲を確認する $ sudo umount -l /mnt/nfs
3. 再発防止:NFS マウントオプションの見直し
本番環境で NFS ハングを防ぐには、マウントオプションにsoft(または softerr)と timeo(タイムアウト 0.1 秒単位)を設定する方法がある。# /etc/fstab の NFS エントリ例(タイムアウト 30 秒で諦める設定) # 【重要】soft オプションはデータ破損リスクがある。書き込み系では慎重に判断する 192.168.1.10:/export/data /mnt/nfs nfs defaults,soft,timeo=300,retrans=3 0 0
・soft:タイムアウト後に I/O エラー(EIO)を返しプロセスを解放する。データ破損リスクがあるため、書き込み系では慎重に使用する
・softerr:Linux カーネル 5.11 以降で利用可能。soft より安全で、読み取り系のみタイムアウトを許容する
ストレージ・ディスクI/O起因のD状態を調査する
wchan がjbd2_xxx や blk_xxx など、NFS 以外のカーネル関数を示す場合は、ローカルストレージの I/O 待ちを疑う。1. dmesg でカーネルのエラーログを確認する
# 直近のカーネルログを確認してストレージエラーを探す $ dmesg -T | grep -iE 'error|fail|reset|timeout' | tail -20
Buffer I/O error on dev sda や EXT4-fs error が出ていればストレージ障害が疑われる。SMART 情報(smartctl -a /dev/sda)で HDD/SSD の健全性も確認する。2. iotop でI/Oを占有しているプロセスを特定する
# I/O を消費しているプロセスをリアルタイム表示する(要 root) $ sudo iotop -oPa
トラブルシュート:よくあるD状態の症状と対処
「umount -l の後もD状態プロセスが消えない」
lazy umount は名前空間から切り離すだけで、既存のファイル操作はカーネル内で保留される。待機中の操作が EIO/ESTALE を受け取ってシステムコールが戻った時点でプロセスは終了する。数分待っても消えない場合はカーネルバグの可能性があり、再起動が最終手段になる。「D状態プロセスが急増している」
ストレージデバイスや NFS サーバーがまったく応答しない状況では、そのデバイスにアクセスしようとするプロセスが次々と D 状態になる。まずdmesg でデバイスエラーを確認し、ストレージまたは NFS の障害対応を先に進める。個々のプロセスを kill しても根本は解消しない。「wchan が 'schedule' など汎用関数を示している」
明確なデバイス系関数でなければ、カーネルの汎用ロック待ちだ。cat /proc/[pid]/stack(カーネル 4.9 以降、root 権限が必要)でスタックトレースを確認すると、待機している関数を詳しく追える。ただしこの操作自体がシステム負荷を上げる場合があるため、本番環境では慎重に判断する。本記事のまとめ
D 状態プロセスのトラブルシューティングは「どこで待っているか(wchan)」「何を開いているか(fd)」「カーネルログに何が出ているか(dmesg)」の 3 点確認から始まる。NFS ハングとストレージ I/O 待機では対処がまったく異なるため、原因の切り分けが最初のステップだ。| やりたいこと | コマンド |
|---|---|
| D状態プロセスを一覧表示する | ps aux | awk '$8 == "D" { print }' |
| プロセスの待機関数を確認する | cat /proc/[pid]/wchan |
| プロセスが開いているファイルを確認する | ls -la /proc/[pid]/fd |
| カーネルのI/Oエラーを確認する | dmesg -T | grep -iE 'error|fail' |
| NFSマウントを強制切り離しする | sudo umount -l /mnt/nfs |
| I/O負荷プロセスをリアルタイム確認する | sudo iotop -oPa |
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、Linux Master Pro Seminar(2日間ハンズオン)では、D状態プロセスのような障害対応から設計・構築まで体系的に学べます。詳細はセミナーページをご確認ください。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます