sysinfo プロバイダは、sys という名前で分類されるカーネル統計情報のプローブを使用できるようにします。これらの統計情報は、mpstat(1M) などのシステム監視ユーティリティーへの入力を提供するので、sysinfo プロバイダは、観測された異常動作の迅速な検査を可能にします。
sysinfo プロバイダは、sys に分類されるカーネル統計情報内のフィールドに対応したプローブを使用できるようにします。sysinfo から提供されたプローブは、対応する sys 値が増分される直前に起動します。以下は、kstat(1M) コマンドを使って、sys に分類されるカーネル統計情報の名前と現在の値を両方表示する例です。
$ kstat -n sys module: cpu instance: 0 name: sys class: misc bawrite 123 bread 2899 bwrite 17995 ... |
表 23–1 に、sysinfo プローブを一覧します。
表 23–1 sysinfo プローブ
bawrite |
バッファーからデバイスへの非同期書き出しが行われる直前に起動するプローブ。 |
bread |
デバイスからのバッファーの物理読み取りが行われたときに起動するプローブ。bread は、デバイスがバッファーを要求したあと、処理の完了が保留される前に起動します。 |
bwrite |
バッファーからデバイスへの書き出しが行われる直前に起動するプローブ。書き出しは、同期書き出し、非同期書き出しの両方を含みます。 |
idlethread |
CPU がアイドルループに入ったときに起動するプローブ。 |
intrblk |
割り込みスレッドがブロックされたときに起動するプローブ。 |
inv_swtch |
実行中のスレッドが CPU の解放を強制されたとき起動するプローブ。 |
lread |
デバイスからのバッファーの論理読み取りが行われたときに起動するプローブ。 |
lwrite |
バッファーからデバイスへの論理書き込みが行われたときに起動するプローブ。 |
modload |
カーネルモジュールがロードされたときに起動するプローブ。 |
modunload |
カーネルモジュールがアンロードされたときに起動するプローブ。 |
msg |
msgsnd(2) または msgrcv(2) システムコールが発行されたあと、メッセージキュー操作が行われる前に起動するプローブ。 |
mutex_adenters |
所有されている適応型ロックの獲得が試みられたときに起動するプローブ。このプローブが起動するときは、lockstat プロバイダの adaptive-block プローブ、または adaptive-spin プローブも起動します。詳細については、第 18 章lockstat プロバイダを参照してください。 |
namei |
ファイルシステム内で名前の検索が試みられたときに起動するプローブ。 |
nthreads |
スレッドが作成されたときに起動するプローブ。 |
phread |
生の入出力読み取りが行われる直前に起動するプローブ。 |
phwrite |
生の入出力書き込みが行われる直前に起動するプローブ。 |
procovf |
システムのプロセステーブルのエントリがなくなったため新しいプロセスを作成できないときに起動するプローブ。 |
pswitch |
CPU が実行スレッドを切り替えたときに起動するプローブ。 |
readch |
正常に読み取りが行われたあと、この読み取りの実行スレッドに制御が移る前に起動するプローブ。読み取りに使用されるシステムコールは、read(2)、readv(2)、pread(2) のいずれかです。arg0 には、正常に読み取られたバイト数が格納されます。 |
rw_rdfails |
書き込み側が読み取り/書き込みロックを保持している場合、または必要としている場合に、この読み取り/書き込みロックの読み取りロックが試みられたとき起動するプローブ。このプローブが起動するときは、lockstat プロバイダの rw-block プローブも起動します。詳細については、第 18 章lockstat プロバイダを参照してください。 |
rw_wrfails |
読み取り/書き込みロックが 1 つ以上の読み取り側、または単一の書き込み側によって保持されている場合に、この読み取り/書き込みロックを保持していない書き込み側による書き込みロックが試みられたとき起動するプローブ。このプローブが起動するときは、lockstat プロバイダの rw-block プローブも起動します。詳細については、第 18 章lockstat プロバイダを参照してください。 |
sema |
システムコール semop(2) が発行されたあと、セマフォー操作が行われる前に起動するプローブ。 |
sysexec |
システムコール exec(2) が発行されたときに起動するプローブ。 |
sysfork |
システムコール fork(2) が発行されたときに起動するプローブ。 |
sysread | |
sysvfork |
システムコール vfork(2) が発行されたときに起動するプローブ。 |
syswrite | |
trap |
プロセッサトラップが発生したときに起動するプローブ。ただし、一部のプロセッサ、特に UltraSPARC 系プロセッサでは、一部の軽量トラップを処理するときにこのプローブを起動しないことがあります。 |
ufsdirblk |
UFS ファイルシステムによるディレクトリブロックの読み取りが行われたときに起動するプローブ。UFS については、ufs(7FS) のマニュアルページを参照してください。 |
ufsiget |
i ノードの取得時に起動するプローブ。UFS については、ufs(7FS) のマニュアルページを参照してください。 |
ufsinopage |
データページが関連付けられていないコア内の i ノードの再利用が可能になったあと起動するプローブ。UFS については、ufs(7FS) のマニュアルページを参照してください。 |
ufsipage |
データページが関連付けられたコア内の i ノードの再利用が可能になったあと起動するプローブ。このプローブは、関連付けられたデータページがディスクにフラッシュされたあとで起動します。UFS については、ufs(7FS) のマニュアルページを参照してください。 |
writech |
正常に書き込みが行われたあと、この書き込みの実行スレッドに制御が移る前に起動するプローブ。書き込みに使用されるシステムコールは、write(2)、writev(2)、pwrite(2) のいずれかです。arg0 には、正常に書き込まれたバイト数が格納されます。 |
xcalls |
クロスコールが行われる直前に起動するプローブ。クロスコールは、一方の CPU から、別の CPU によるすばやい処理を要求するオペレーティングシステム機構です。 |
sysinfo プローブには、次の引数があります。
arg0 |
統計情報の増分値。この引数の値は、ほとんどのプローブでは 1 ですが、別の値をとるプローブもあります。 |
arg1 |
増分対象の統計情報の、現在値のポインタ。arg0 の値に従って増分される量を 64 ビット値で表します。このポインタを間接参照することにより、コンシューマ側で、プローブの統計情報の現在のカウントを特定できます。 |
arg2 |
統計情報の増分が行われる CPU の cpu_t 構造体のポインタ。この構造体は <sys/cpuvar.h> に定義されていますが、カーネル実装の一部であるため、「非公開」と見なします。 |
ほとんどの sysinfo プローブでは、arg0 の値は 1 です。ただし、readch プローブでは arg0 が読み取られたバイト数に、writech プローブでは書き込まれたバイト数になります。この機能を利用すると、実行可能ファイルの名前から読み取りのサイズを特定できます。次の例を参照してください。
# dtrace -n readch'{@[execname] = quantize(arg0)}' dtrace: description 'readch' matched 4 probes ^C xclock value ------------- Distribution ------------- count 16 | 0 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1 64 | 0 acroread value ------------- Distribution ------------- count 16 | 0 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3 64 | 0 FvwmAuto value ------------- Distribution ------------- count 2 | 0 4 |@@@@@@@@@@@@@ 13 8 |@@@@@@@@@@@@@@@@@@@@@ 21 16 |@@@@@ 5 32 | 0 xterm value ------------- Distribution ------------- count 16 | 0 32 |@@@@@@@@@@@@@@@@@@@@@@@@ 19 64 |@@@@@@@@@ 7 128 |@@@@@@ 5 256 | 0 fvwm2 value ------------- Distribution ------------- count -1 | 0 0 |@@@@@@@@@ 186 1 | 0 2 | 0 4 |@@ 51 8 | 17 16 | 0 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@ 503 64 | 9 128 | 0 Xsun value ------------- Distribution ------------- count -1 | 0 0 |@@@@@@@@@@@ 269 1 | 0 2 | 0 4 | 2 8 |@ 31 16 |@@@@@ 128 32 |@@@@@@@ 171 64 |@ 33 128 |@@@ 85 256 |@ 24 512 | 8 1024 | 21 2048 |@ 26 4096 | 21 8192 |@@@@ 94 16384 | 0 |
sysinfo プロバイダは、arg2 を、カーネル実装の内部構造体である cpu_t のポインタに設定します。sysinfo プローブは、統計情報の増分が行われる CPU 上で起動します。情報を得たい CPU を特定するには、cpu_t 構造体の cpu_id メンバーを使用します。
以下は、mpstat(1M) の出力例です。
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl 12 90 22 5760 422 299 435 26 71 116 11 1372 5 19 17 60 13 46 18 4585 193 162 431 25 69 117 12 1039 3 17 14 66 14 33 13 3186 405 381 397 21 58 105 10 770 2 17 11 70 15 34 19 4769 109 78 417 23 57 115 13 962 3 14 14 69 16 74 16 4421 437 406 448 29 77 111 8 1020 4 23 14 59 17 51 15 4493 139 110 378 23 62 109 9 928 4 18 14 65 18 41 14 4204 494 468 360 23 56 102 9 849 4 17 12 68 19 37 14 4229 115 87 363 22 50 106 10 845 3 15 14 67 20 78 17 5170 200 169 456 26 69 108 9 1119 5 21 25 49 21 53 16 4817 78 51 394 22 56 106 9 978 4 17 22 57 22 32 13 3474 486 463 347 22 48 106 9 769 3 17 17 63 23 43 15 4572 59 34 361 21 46 102 10 947 4 15 22 59 |
この出力をよく見ると、システムが比較的アイドル状態にあるのに xcal フィールドの値が大きすぎることがわかります。mpstat は、xcal フィールドの値を決めるとき、sys カーネル統計情報の xcalls フィールドを調べます。したがって、次の例のように xcalls sysinfo プローブを有効にすれば、この異常について簡単に調べることができます。
# dtrace -n xcalls'{@[execname] = count()}' dtrace: description 'xcalls' matched 4 probes ^C dtterm 1 nsrd 1 in.mpathd 2 top 3 lockd 4 java_vm 10 ksh 19 iCald.pl6+RPATH 28 nwadmin 30 fsflush 34 nsrindexd 45 in.rlogind 56 in.routed 100 dtrace 153 rpc.rstatd 246 imapd 377 sched 431 nfsd 1227 find 3767 |
この出力から、クロスコールのソースをどこで探せばよいかがわかります。ほとんどのクロスコールは、find(1) プロセス数個に影響を受けています。問題をもっと詳しく調べるには、次の D スクリプトを使用します。
syscall:::entry /execname == "find"/ { self->syscall = probefunc; self->insys = 1; } sysinfo:::xcalls /execname == "find"/ { @[self->insys ? self->syscall : "<none>"] = count(); } syscall:::return /self->insys/ { self->insys = 0; self->syscall = NULL; }
このスクリプトでは、syscall プロバイダを使って、find からのクロスコールがどのシステムコールに起因するか調べます。ページフォルトに起因するクロスコールなど、システムコールに起因しないクロスコールも存在します。この場合は <none> と出力されます。このスクリプトを実行すると、次のような出力が得られます。
# dtrace -s ./find.d dtrace: script './find.d' matched 444 probes ^C <none> 2 lstat64 2433 getdents64 14873 |
find によるクロスコールの大部分が、システムコール getdents(2) によって行われています。以降の作業は、調べたい内容に応じて異なります。たとえば、find プロセスが getdents を呼び出している理由を調べたい場合は、find がクロスコールを引き起こしたときに ustack() を集積するような D スクリプトを作成するとよいでしょう。getdents の呼び出しがクロスコールを引き起こす理由を調べたい場合は、find がクロスコールを引き起こしたときに stack() を集積するような D スクリプトを作成するとよいでしょう。次の作業が何であっても、xcalls プローブを利用することで、異常な監視結果が出力された原因を簡単に突き止めることができます。
以下の表に、sysinfo プロバイダの安定性を DTrace の安定性機構に従って示します。安定性機構の詳細については、第 39 章安定性を参照してください。
要素 |
名前の安定性 |
データの安定性 |
依存クラス |
---|---|---|---|
プロバイダ |
発展中 |
発展中 |
ISA |
モジュール |
非公開 |
非公開 |
不明 |
機能 |
非公開 |
非公開 |
不明 |
名前 |
発展中 |
発展中 |
ISA |
引数 |
非公開 |
非公開 |
ISA |