第4章 便利な SystemTap スクリプト
本章では、各種のサブシステムの監視および調査に使用可能な SystemTap スクリプトをいくつか説明します。これらのスクリプトはすべて、systemtap-testsuite パッケージをインストールすると、
/usr/share/systemtap/testsuite/systemtap.examples/
ディレクトリーで使用できます。
4.1. ネットワーク リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
以下のセクションでは、ネットワーク関連の関数を追跡し、ネットワークアクティビティーのプロファイルを構築するスクリプトを説明します。
4.1.1. ネットワークのプロファイリング リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
このセクションでは、ネットワークアクティビティーのプロファイルを実行する方法を説明します。例4.1「nettop.stp」 では、マシン上で各プロセスが生成しているネットワークトラフィックの量が確認できます。
例4.1 nettop.stp
print_activity()
関数は、以下の式を使用する点に注意してください。
n_xmit ? @sum(ifxmit[pid, dev, exec, uid])/1024 : 0 n_recv ? @sum(ifrecv[pid, dev, exec, uid])/1024 : 0
n_xmit ? @sum(ifxmit[pid, dev, exec, uid])/1024 : 0
n_recv ? @sum(ifrecv[pid, dev, exec, uid])/1024 : 0
これらの式は、
if
または else
条件分岐です。2 番目のステートメントは、次の疑似コードをより簡潔に記述したものです。
if n_recv != 0 then @sum(ifrecv[pid, dev, exec, uid])/1024 else 0
if n_recv != 0 then
@sum(ifrecv[pid, dev, exec, uid])/1024
else
0
例4.1「nettop.stp」 では、どのプロセスがシステム上でネットワークトラフィックを生成しているかを追跡し、各プロセスについて以下の情報を提供します。
PID
— 一覧表示されているプロセスの ID。UID
— ユーザー ID。ユーザー ID が0
の場合は、root ユーザーを指します。DEV
— データの送受信に使用されるイーサネットデバイス (eth0、eth1 など)。XMIT_PK
— プロセスが送信したパケット数。RECV_PK
— プロセスが受信したパケット数。XMIT_KB
— プロセスが送信したデータ量 (キロバイト単位)。RECV_KB
— サービスが受信したデータ量 (キロバイト単位)。
例4.1「nettop.stp」 では、5 秒ごとにネットワークプロファイルのサンプルが提供されます。この設定は、
probe timer.ms(5000)
を適切に編集すると、変更できます。例4.2「例4.1「nettop.stp」 出力サンプル」 には、例4.1「nettop.stp」 からの 20 秒間の出力の抜粋が含まれています。
例4.2 例4.1「nettop.stp」 出力サンプル
4.1.2. ネットワークソケットコードで呼び出された関数の追跡 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
このセクションでは、カーネルの
net/socket.c
ファイルから呼び出された関数を追跡する方法について説明します。このタスクでは、各プロセスがカーネルレベルでネットワークと対話する様子が詳細に分かります。
例4.3 socket-trace.stp
例4.3「socket-trace.stp」 は、例3.6「thread_indent.stp」 と同じものです。これは以前、
thread_indent()
が機能する様子を説明するために SystemTap 関数 で使用されました。
例4.4 例4.3「socket-trace.stp」 出力サンプル
例4.4「例4.3「socket-trace.stp」 出力サンプル」 には、3 秒間の 例4.3「socket-trace.stp」 の出力を引用してあります。
thread_indent()
が提供するこのスクリプトの出力に関する詳細情報は、SystemTap 関数 例3.6「thread_indent.stp」 を参照してください。
4.1.3. 着信 TCP 接続の監視 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
このセクションでは、着信 TCP 接続の監視方法を説明します。このタスクは、承認されていない、疑わしい、さもなくば望ましくないネットワークアクセス要求をリアルタイムで特定する場合に便利です。
例4.5 tcp_connections.stp
例4.5「tcp_connections.stp」 の実行中は、システムが受け付けた着信 TCP 接続の以下の情報がリアルタイムで出力されます。
- 現在の
UID
CMD
- 接続を受け付けるコマンド- そのコマンドの
PID
- 接続が使用するポート
- TCP 接続の発信元となる IP アドレス
例4.6 例4.5「tcp_connections.stp」 出力サンプル
UID CMD PID PORT IP_SOURCE 0 sshd 3165 22 10.64.0.227 0 sshd 3165 22 10.64.0.227
UID CMD PID PORT IP_SOURCE
0 sshd 3165 22 10.64.0.227
0 sshd 3165 22 10.64.0.227
4.1.4. カーネルでのネットワークパケットドロップの監視 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Linux のネットワークスタックは、様々な理由でパケットを破棄する場合があります。一部の Linux カーネルには、パケットが破棄された場所を簡単に追跡するトレースポイント
kernel.trace("kfree_skb")
が含まれています。例4.7「dropwatch.stp」 は、kernel.trace("kfree_skb")
を使用して、パケットの破棄を追跡します。スクリプトは、5 秒間隔ごとにパケットを破棄する場所を要約します。
例4.7 dropwatch.stp
kernel.trace("kfree_skb")
は、カーネル内でネットワークパケットがドロップした場所を追跡します。kernel.trace("kfree_skb")
には、解放されているバッファーへのポインター ($skb
) と、解放されているバッファーのカーネルコード内での場所 ($location
) という 2 つの引数があります。
dropwatch.stp スクリプトを 15 秒間実行すると、例4.8「例4.7「dropwatch.stp」 出力サンプル」 のような結果が出力されます。ここでは、トレースポイントアドレスと実際のアドレスのミスの数が記載されています。
例4.8 例4.7「dropwatch.stp」 出力サンプル
パケットドロップの場所をより意味のあるものにするには、
/boot/System.map-$(uname -r)
ファイルを参照してください。このファイルには、各関数の開始アドレスが記載されており、例4.8「例4.7「dropwatch.stp」 出力サンプル」 の出力のアドレスを特定の関数名にマップできます。次の /boot/System.map-$(uname -r)
ファイルのスニペットを考えると、アドレス 0xffffffff8024cd0f が関数 unix_stream_recvmsg
にマップされます。また、アドレス 0xffffffff8044b472 は関数 arp_rcv
にマップされます。