sysinfo プロバイダは、sys カーネル統計情報のプローブを使用できるようにします。これらの統計情報は、mpstat などのシステム監視ユーティリティーの入力となります。sysinfo プロバイダのプローブは、kstat コマンドで表示される sys の値が増分される直前に起動します。次に、sysinfo プロバイダが提供するプローブを一覧します。
バッファーからデバイスへの非同期書き出しが行われる直前に起動するプローブ。
デバイスからのバッファーの物理読み取りが行われたときに起動するプローブ。bread は、デバイスがバッファーを要求したあと、処理の完了が保留される前に起動します。
バッファーからデバイスへの書き出しが行われる直前に起動するプローブ。書き出しは、同期書き出し、非同期書き出しの両方を含みます。
定期的なシステムクロックにより、「CPU がアイドル状態である」という判断が下されたとき起動するプローブ。このプローブは、システムクロックのコンテキストで起動します。したがって、システムクロックを実行している CPU 上で起動することになります。cpu_t の引数 (arg2) は、アイドル状態だと判断された CPU を表します。
定期的なシステムクロックにより、「CPU がカーネルで実行中である」という判断が下されたとき起動するプローブ。このプローブは、システムクロックのコンテキストで起動します。したがって、システムクロックを実行している CPU 上で起動することになります。cpu_t の引数 (arg2) は、カーネルで実行中であると判断された CPU を表します。
定期的なシステムクロックにより、「CPU がユーザーモードで実行中である」という判断が下されたとき起動するプローブ。このプローブは、システムクロックのコンテキストで起動します。したがって、システムクロックを実行している CPU 上で起動することになります。cpu_t の引数 (arg2) は、ユーザーモードで実行中であると判断された CPU を表します。
定期的なシステムクロックにより、「CPU 上に入出力待ちのスレッドがあるほかはアイドル状態である」という判断が下されたとき起動するプローブ。このプローブは、システムクロックのコンテキストで起動します。したがって、システムクロックを実行している CPU 上で起動することになります。cpu_t の引数 (arg2) は、入出力待ち状態だと判断された CPU を表します。
CPU がアイドルループに入ったときに起動するプローブ。
割り込みスレッドがブロックされたときに起動するプローブ。
実行中のスレッドが CPU の解放を強制されたとき起動するプローブ。
デバイスからのバッファーの論理読み取りが行われたときに起動するプローブ。
バッファーからデバイスへの論理書き込みが行われたときに起動するプローブ。
カーネルモジュールがロードされたときに起動するプローブ。
カーネルモジュールがアンロードされたときに起動するプローブ。
msgsnd(2) または msgrcv(2) システムコールが発行されたあと、メッセージキュー操作が行われる前に起動するプローブ。
所有されている適応型ロックの獲得が試みられたときに起動するプローブ。このプローブが起動するときは、lockstat プロバイダの adaptive-block プローブ、または adaptive-spin プローブも起動します。
ファイルシステム内で名前の検索が試みられたときに起動するプローブ。
スレッドが作成されたときに起動するプローブ。
生の入出力読み取りが行われる直前に起動するプローブ。
生の入出力書き込みが行われる直前に起動するプローブ。
システムのプロセステーブルのエントリがなくなったため新しいプロセスを作成できないときに起動するプローブ。
CPU が実行スレッドを切り替えたときに起動するプローブ。
正常に読み取りが行われたあと、この読み取りの実行スレッドに制御が移る前に起動するプローブ。読み取りは、read(2)、readv(2)、または pread(2) システムコールによって行われます。arg0 には、正常に読み取られたバイト数が格納されます。
書き込み側が読み取りロックまたは書き込みロックを保持している場合、または必要としている場合に、読み取りロックが試みられたとき起動するプローブ。このプローブが起動するときは、lockstat プロバイダの rw-block プローブも起動します。
読み取り側か別の書き込み側が読み取りロックまたは書き込みロックを保持している場合に、書き込みロックが試みられたとき起動するプローブ。このプローブが起動するときは、lockstat プロバイダの rw-block プローブも起動します。
システムコール semop(2) が発行されたあと、セマフォー操作が行われる前に起動するプローブ。
システムコール exec(2) が発行されたときに起動するプローブ。
システムコール fork(2) が発行されたときに起動するプローブ。
システムコール read、readv、または pread が発行されたときに起動するプローブ。
システムコール vfork(2) が発行されたときに起動するプローブ。
システムコール write(2)、writev(2)、または pwrite(2) が発行されたときに起動するプローブ。
プロセッサトラップが発生したときに起動するプローブ。ただし、一部のプロセッサ、特に UltraSPARC 系プロセッサでは、一部の軽量トラップを処理するときにこのプローブを起動しないことがあります。
UFS ファイルシステムによるディレクトリブロックの読み取りが行われたときに起動するプローブ。UFS については、ufs(7FS) のマニュアルページを参照してください。
i ノードの取得時に起動するプローブ。UFS については、ufs(7FS) のマニュアルページを参照してください。
データページが関連付けられていないコア内の i ノードの再利用が可能になったあと起動するプローブ。UFS については、ufs(7FS) のマニュアルページを参照してください。
データページが関連付けられたコア内の i ノードの再利用が可能になったあと起動するプローブ。このプローブは、関連付けられたデータページがディスクにフラッシュされたあとで起動します。UFS については、ufs(7FS) のマニュアルページを参照してください。
定期的なシステムクロックにより、「CPU 上に入出力待ちのスレッドがあるほかはアイドル状態である」という判断が下されたとき起動するプローブ。このプローブは、システムクロックのコンテキストで起動します。したがって、システムクロックを実行している CPU 上で起動することになります。cpu_t の引数 (arg2) は、入出力待ち状態だと判断された CPU を表します。wait_ticks_io と cpu_ticks_wait には、意味上の違いはありません。wait_ticks_io は、履歴上の理由で提供されているだけです。
正常に書き込みが行われたあと、この書き込みの実行スレッドに制御が移る前に起動するプローブ。書き込みに使用されるシステムコールは、 write、writev、pwrite のいずれかです。arg0 には、正常に書き込まれたバイト数が格納されます。
クロスコールが行われる直前に起動するプローブ。クロスコールは、一方の CPU から、別の CPU によるすばやい処理を要求するオペレーティングシステム機構です。
quantize 集積関数は、引数の二乗度数分布を示す棒グラフを表示します。次の例では、quantize 関数を使って、10 秒間にシステム上の全プロセスで実行される read 呼び出しのサイズを確認します。sysinfo プローブの引数 arg0 には、統計情報の増分の分量を指定します。ほとんどの sysinfo プローブでは、この値は 1 です。ただし、readch プローブと writech プローブは例外です。これらのプローブでは、引数 arg0 に、実際に読み取られるバイト数、または実際に書き込まれるバイト数を指定します。
# cat -n read.d 1 #!/usr/sbin/dtrace -s 2 sysinfo:::readch 3 { 4 @[execname] = quantize(arg0); 5 } 6 7 tick-10sec 8 { 9 exit(0); 10 } # dtrace -s read.d dtrace: script 'read.d' matched 5 probes CPU ID FUNCTION:NAME 0 36754 :tick-10sec bash value ---------- Distribution ---------- count 0 | 0 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 13 2 | 0 file value ---------- Distribution ---------- count -1 | 0 0 | 2 1 | 0 2 | 0 4 | 6 8 | 0 16 | 0 32 | 6 64 | 6 128 |@@ 16 256 |@@@@ 30 512 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 199 1024 | 0 2048 | 0 4096 | 1 8192 | 1 16384 | 0 grep value ---------- Distribution ---------- count -1 | 0 0 |@@@@@@@@@@@@@@@@@@@ 99 1 | 0 2 | 0 4 | 0 8 | 0 16 | 0 32 | 0 64 | 0 128 | 1 256 |@@@@ 25 512 |@@@@ 23 1024 |@@@@ 24 2048 |@@@@ 22 4096 | 4 8192 | 3 16384 | 0 |
次に、mpstat(1M) コマンドの出力例を示します。
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl 0 2189 0 1302 14 1 215 12 54 28 0 12995 13 14 0 73 1 3385 0 1137 218 104 195 13 58 33 0 14486 19 15 0 66 2 1918 0 1039 12 1 226 15 49 22 0 13251 13 12 0 75 3 2430 0 1284 220 113 201 10 50 26 0 13926 10 15 0 75 |
xcal 欄と syscl 欄の値が異常に大きいため、システムパフォーマンスが浪費されている可能性があります。システムは比較的アイドル状態にあり、入出力の待ち時間が異常に長くなっているわけでもありません。xcal 欄の数値は sys kstat の xcalls フィールドから読み取られたものであり、秒単位で表されています。クロスコールを行う実行可能ファイルを確認するには、次のような dtrace コマンドを入力します。
# dtrace -n 'xcalls {@[execname] = count()}' dtrace: description 'xcalls ' matched 3 probes ^C find 2 cut 2 snmpd 2 mpstat 22 sendmail 101 grep 123 bash 175 dtrace 435 sched 784 xargs 22308 file 89889 # |
出力結果から、大量のクロスコールが file(1) と xargs(1) のプロセスによって行われていることがわかります。これらのプロセスを確認するには、pgrep(1) コマンドと ptree(1) を使用します。
# pgrep xargs 15973 # ptree 15973 204 /usr/sbin/inetd -s 5650 in.telnetd 5653 -sh 5657 bash 15970 /bin/sh ./findtxt configuration 15971 cut -f1 -d: 15973 xargs file 16686 file /usr/bin/tbl /usr/bin/troff /usr/bin/ul /usr/bin/vgrind /usr/bin/catman |
出力結果から、xargs コマンドと file コマンドがカスタムユーザーシェルスクリプトの一部であることがわかります。このスクリプトを検出するには、次のコマンドを実行します。
# find / -name findtxt /usrs1/james/findtxt # cat /usrs1/james/findtxt #!/bin/sh find / -type f | xargs file | grep text | cut -f1 -d: > /tmp/findtxt$$ cat /tmp/findtxt$$ | xargs grep $1 rm /tmp/findtxt$$ # |
このスクリプトは、多くのプロセスを同時に実行しています。パイプ経由で大量のプロセス間通信が行われています。パイプ数が多いと、スクリプトリソースが集中的に使用されます。このスクリプトは、システム上のすべてのテキストファイルの検出を試みたあと、各ファイルから特定のテキストを検索します。