#!/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 |