2009/11/27

Ubuntu 8.10 (interpid)以降でのsystemtap

systemtapはUbuntu 8.10以降でもapt-get経由で提供されていますが、使うには少し問題がありそうです。

Ubuntu 9.10にsystemtapをapt-getで導入しましたが、linux-image-debug-*パッケージは提供されていませんでした。 systemtapの提案パッケージの中にはlinux-debug-2.6がありますが、リポジトリには存在していません。 関連する情報はいくつかUbuntuのバグデータベースなどにありました。

手元で確認したのは9.10だけですが、8.10からdebugパッケージがなくなっているようです。 理由として、デバッグ情報を含むことでパッケージリポジトリのサイズが大きくなってしまう事が挙げられています。

開発版では最新のdebug情報付きのカーネルが配布されていますが、1世代分しか提供されていないようです。 LTSでは提供して欲しいけれど、どうなるか情報はみつけられていません。 kernel teamのMLログを漁るしかないか…。

Ubuntu 9.10でのカーネル再構築

とりあえず手元の9.10でsystemtapを試すために、デバッグ情報付きのカーネルを作成する事にしました。 手順はKernelCompile [help.ubuntu.com] に従います。

ビルド環境
  • VMWare Workstation 6.5.3上のVM
  • CPU: 1つ (Host CPU Phenom II X4 940 の1コア)
  • OS: Ubuntu 9.10 i386版
  • Memory: 512MB (後半1.5GB)
  • HDD1: 8GB (/, ext3)
  • HDD2: 30GB (/home, ext3)

Googleで検索すると/usr/srcでlinux-source-2.6.31.tar.bz2を展開して、make-kpkgを使う方法がよくみつかりますが、Ubuntuのお勧めはgitから最新のアーカイブを取得する方法のようですね…。 今回は(2.)の"sudo apt-get build-dep" & "apt-get source"でカーネルのソースコードを展開する事にしました。

少し手順がわかりずらいかも。debian/scripts/misc/oldconfigはないので、$ debian/rules updateconfigsを使うしかないのですが、$ chmod a+x *は本文を良く読めばいいのだけれど、次のようにcdコマンドを使わずに実行できるよう書くべきかもしれません。

chmod a+x debian.master/scripts/misc/*

デバッグ情報を含むdebファイルを作成するために、debian.master/rules.d/i386.mkの中に"skipdbg = false"の設定を加える必要があります。

また"Alternate Build Method: The Old-Fashioned Debian Way"のセクションが同じページに並んでいるので、かなりまぎらわしく、間違ってこの手順も実行してしまわないか心配になります。

実際の再構築手順

まずは事前準備。

$ sudo apt-get install fakeroot kernel-wedge build-essential makedumpfile
$ sudo apt-get build-dep linux
$ sudo apt-get build-dep linux-image-$(uname -r)

いったん準備が終れば、カーネルのソースコードが必要な時にsudoを使わずに自分の権限でファイルを取得&展開できます。 カーネルのコンパイル用に適当なファイルシステムを準備して、任意のディレクトリ(以下、~/mykernel)を作成して移動するのが良いでしょう。

$ mkdir ~/mykernel
$ cd ~/mykernel
$ apt-get source linux-image-$(uname -r)
$ cd linux-2.6.31/
$ chmod a+x debian.master/scripts/misc/*
$ echo "skipdbg = false" >> debian.master/rules.d/i386.mk

最後の一行でi386.mkの最下行に"skipdbg = false"を加えます。 右辺は"false"でなくても"true"以外の文字列なら何でも良いようです。

ただskipdbgオプションは手順には載ってないですね。 このオプションは debian.master/rules.d/2-binary-arch.mk の中で使われていました。

$ cp debian.master/control.d/vars.generic debian.master/control.d/vars.mygeneric
$ tmpf=$(mktemp)
$ sed -e 's/^\(flavours.*\)$/\1 mygeneric/' debian.master/rules.d/i386.mk > $tmpf
$ diff $tmpf debian.master/rules.d/i386.mk
5c5
< flavours        = generic generic-pae 386 mygeneric
---
> flavours        = generic generic-pae 386 
$ cp $tmpf debian.master/rules.d/i386.mk
$ rm $tmpf

diffの引数は"oldfile, newfile"の順番ですが、そのままcpの引数に使えるように またmktempを使ってテンプファイルを作らなくても、"$tmpf"の個所は適当な新規のファイル名にしてもらえれば良いのですが、例として載せてみました。

$ cp debian.master/config/i386/config.flavour.generic debian.master/config/i386/config.flavour.mygeneric
$ cp ./debian.master/abi/2.6.31-15.49/i386/generic ./debian.master/abi/2.6.31-15.49/i386/mygeneric
$ cp ./debian.master/abi/2.6.31-15.49/i386/generic.modules ./debian.master/abi/2.6.31-15.49/i386/mygeneric.modules

$ debian/rules updateconfigs
$ fakeroot debian/rules clean
$ time AUTOBUILD=1 fakeroot debian/rules binary-mygeneric

CPUが複数コアを持っているようであれば、"CONCURRENCY_LEVEL=2"を付ける例にならうと良いでしょう。 make-kpkgを使った場合は、並列コンパイルが難しいようですから、こちらの方法を使う理由になるかもしれないですね。

コンパイルが終ると一つ上のディレクトリにdebパッケージが作成されます。

作成したパッケージの導入

同じバージョンに見えますが、埋め込まれているハッシュ値が違うのでdebugパッケージだけでは十分ではありません。

$ uname -r
2.6.31-15-generic
$ cd ..
$ sudo dpkg -i linux-headers-2.6.31-15-mygeneric_2.6.31-15.50_i386.deb linux-image-2.6.31-15-mygeneric_2.6.31-15.50_i386.deb linux-image-debug-2.6.31-15-mygeneric_2.6.31-15.50_i386.ddeb

あとは再起動をしてsystemtapの稼働を確認します。

systemtapの確認

単純なスクリプトで確認します。

$ sudo stap -v -e 'probe syscall.open { printf("%d %s\n", tid(), execname()) }'
1572 vmware-guestd
1222 hald-addon-stor
....

出力があれば完了です。 ひょっとすると何かの機能を呼び出したタイミングで不具合があるかもしれませんが、いまのところうまく動いているようです。

0 件のコメント: