systemtapでmodule parameterを扱う

systemtapでguru modeを利用してcのコードを直接スクリプトに書くことで、module parameterを使うことができるみたいなんだけど、そもそもモジュールロード時のパラメタの設定方法がよくわからなかったので、調べてみた。


とりあえず、サンプルのスクリプト

$ cat mod_param.stp
global stap_global_val;

%{
static unsigned long c_mod_param;
module_param(c_mod_param, ulong, 0644);
MODULE_PARM_DESC(c_mod_param, "sample parameter");
%}

function my_func:long() %{
	THIS->__retvalue = c_mod_param;
%}

probe begin {
	printf("stap_global_val = %d\n", stap_global_val);
	printf("c_module_param  = %d\n", my_func());
	exit();
}


これを実行するとこんな感じ*1

$ sudo stap -w -g -m mod_param mod_param.stp
stap_global_val = 0
c_module_param  = 0


で、上記コマンドを実行すると、カレントディレクトリにmod_param.koができるので、modinfoコマンドで見てみる。

$ modinfo mod_param.ko
filename:       /hoge/mod_param.ko
license:        GPL
description:    systemtap-generated probe
license:        GPL
depends:        
vermagic:       3.5.4-2.fc17.x86_64 SMP mod_unload 
parm:           c_mod_param:sample parameter (ulong)
parm:           _stp_bufsize:buffer size (int)
parm:           stap_global_val:int64_t

cで書いた変数は確かにパラメタとなっていることが分かる。さらに、一番下の行に注目すると、systemtapスクリプト内で定義したグローバル変数(not c言語)であるstap_global_valもモジュールパラメータとなっているではありませんか。知らなかったよ。


ここで、stapのmanによるとsystemtapグローバル変数はstapコマンドのオプションで設定できるとのこと。

$ man stap
<snip>
-G NAME=VALUE
        Sets the value of global variable NAME to VALUE when staprun  is
        invoked.   This  applies  to scalar variables declared global in
        the script/tapset.
<snip>


ということで、やってみる。

$ sudo stap -w -g -m mod_param -G stap_global_val=123 -G c_mod_param=456 mod_param.stp
stap_global_val = 123
c_module_param  = 456

素晴らしい。


[結論]
systemtapで作成したモジュールのモジュールパラメタをstap実行時に設定する方法は、-G パラメタ名=<値>とすればよい。

*1:systemtapスクリプト内でグローバル変数を定義しているんだけど、使っていないからwarningがでる。それを回避するために-wを追加。