LinuxのD状態プロセスをpsとwchanで調査する方法|NFSハング・I/O待機の原因切り分けとkillできない時の対処

運営:リナックスマスター.JP(代表 宮崎智広)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > Linuxトラブルシューティング > LinuxのD状態プロセスをpsとwchanで調査する方法|NFSハング・I/O待機の原因切り分けとkillできない時の対処
「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でストレージ障害を早期発見できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

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 }'

D 状態のプロセスが多数いる場合は 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]

出力例(環境により異なります): リンク先に NFS マウントポイント(例: /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

疎通が取れれば NFS サーバー側で問題が起きていないか確認する。疎通なしであればネットワーク断またはサーバーダウンと判断し、マウントの切り離しに進む。

2. NFS マウントの強制切り離し

通常の umount は EBUSY で失敗するため、umount -l(lazy umount)を使う。mount コマンドの使い方で解説しているとおり、-l オプションはファイルシステムを名前空間から即座に切り離し、使用中のプロセスが終了した段階でクリーンアップされる。

# lazy umount で NFS を強制切り離し # 注意: 書き込み中のデータは失われる可能性がある。本番適用前に影響範囲を確認する $ sudo umount -l /mnt/nfs

umount 後、D 状態プロセスはシステムコールが ESTALE または EIO を返して自然に終了する。

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

・hard(デフォルト):NFS サーバーが復旧するまで永続的に待つ。データ整合性は高いが D 状態が長期化する
・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

障害対応で I/O が詰まっている状況では、iotop が D 状態プロセスをリストアップし、どのデバイスへの待ちが発生しているかの手がかりを与えてくれる。

トラブルシュート:よくある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状態プロセスのような障害対応から設計・構築まで体系的に学べます。詳細はセミナーページをご確認ください。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録

運営

リナックスマスター.JP(代表 宮崎智広)

株式会社イーネットマーキュリーが運営するLinux教育サイトです。代表の宮崎智広は現役のLinuxサーバー管理者として20年以上の実務経験を持ち、累計3,100名以上のエンジニアを指導してきました。実践型のLinuxセミナーや無料マニュアルの配布を通じてLinux人材の育成に取り組んでいます。