#!/bin/sh
#
# ktrace
# カーネルのトレースをリセットし有効にする
# 指定されている場合はコマンドをバックグラウンドで実行する
# 指定されている場合は休眠 (スリープ) する
# コマンドの実行完了、タイムアウト、キーボードの割り込みを待機
# (注 : キーボード割り込みによってコマンドは終了する)
# カーネルのトレースを無効にする
# カーネルトレースバッファーを抽出する
# 指定されている場合はカーネルのトレースをリセットする
#
TMPDIR=${TMPDIR:-/tmp}
output_file=$TMPDIR/ktrace.tnf
buffer_size=512k
duration=
events=
command=
do_reset=y
child=
alarm=
# 使用法のメッセージ
usage() {
echo ""
echo $1
echo "
Usage: ktrace [-o <output_file>] # デフォルトでは /tmp/ktrace.tnf
[-s <buffer_size>] # デフォルトでは 512k
-e <events> # 有効にするカーネルプローブ (キー)
[-r] # カーネルのトレースをリセットしない
# デフォルトでは、コマンド実行後にリセットする
<cmd> | -t <seconds>
Eg,
# ktrace -e `thread vm io' -t 10
# ktrace -e `thread' -s 256k myapp ...
"
exit 1
}
# 失敗時のメッセージ
fail() {
while [ $# -gt 0 ]
do
echo $1
shift
done
echo "ktrace failed"
exit 2
}
# カーネルのトレースをリセットする
ktrace_reset() {
if [ $1 = "y" ]; then
echo "Resetting kernel tracing"
prex -k >/dev/null 2>&1 <<-EOF
ktrace off
untrace /.*/
disable /.*/
buffer dealloc
EOF
test $? -ne 0 && fail "Could not reset kernel tracing" ¥
"`su root' and retry"
fi
}
# カーネルのトレースを有効にする
ktrace_on() {
echo "Enabling kernel tracing"
prex -k >/dev/null 2>&1 <<-EOF
buffer alloc $buffer_size
trace $events
enable $events
ktrace on
EOF
test $? -ne 0 && fail "Could not enable kernel tracing" ¥
"Check syntax of `-e' argument" ¥
"Check buffer size is not too high"
}
# カーネルのトレースを無効にする
ktrace_off() {
prex -k >/dev/null 2>&1 <<-EOF
ktrace off
EOF
test $? -ne 0 && fail "Could not disable kernel tracing"
echo "Kernel tracing disabled"
}
# カーネルトレースバッファーを抽出する
ktrace_xtract() {
echo "Extracting kernel trace buffer"
tnfxtract $output_file || fail "Could not extract kernel trace
buffer"
ls -l $output_file
}
# コマンドを実行、休眠、またはコマンド実行完了を待機する
run_command() {
trap `interrupt' 0 1 2 3 15
if [ "$command" ]; then
$command &
child=$!
echo "`$command' pid is $child"
fi
if [ "$duration" ]; then
sleep $duration &
alarm=$!
wait $alarm
# XXX test -z "$child" || kill -15 $child
else
wait $child
fi
trap 0 1 2 3 15
}
# キーボード割り込み
interrupt() {
test -z "$alarm" || kill -15 $alarm
test -z "$child" || kill -15 $child
}
# オプションを読み取る
while getopts o:s:t:e:r opt
do
case $opt in
o) output_file="$OPTARG";;
s) buffer_size="$OPTARG";;
t) duration="$OPTARG";;
e) events="$OPTARG";;
r) do_reset="n";;
¥?) usage;;
esac
done
shift `expr $OPTIND - 1`
# 実行するコマンドを取得する
test $# -gt 0 && command="$*"
# オプションを検査
test -z "$events" && usage "No kernel events specified"
test -z "$command" && test -z "$duration" && ¥
usage "No command or time duration specified"
# 検査を実行する
ktrace_reset y # カーネルのトレースをリセット
ktrace_on # カーネルのトレースを有効に
run_command # コマンド実行、待機、または休眠
ktrace_off # カーネルのトレースを無効に
ktrace_xtract # バッファを抽出
ktrace_reset $do_reset # カーネルのトレースを再度リセット
exit 0
|