今回はプログラムの話。タイトル通り、LinuxのOOM Killerが発動したことを検知したいという話です。組み込みでLinuxを使っていると、OOM Killerが動き出すこと自体異常事態なので、検知してリカバリ処理を挟みたい場合があるのです。「OOM Killerとは何者か」というところはググれば情報がたくさん出てくるのでそちらを参照していただきたく。
さて、そんなわけでLinuxカーネルのソースを見ていたのですが、ちゃんとフックできるようになっていますね。やっぱり同じ要求はあるらしい。register_oom_notifier()でnotifierを登録しておくと、OOM Killerが発動したタイミングで呼んでもらえるようです。
さっそく実験。以下のようなカーネルモジュールを書きました。
#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/notifier.h> #include <linux/oom.h> #include <linux/err.h> static int hoom_oom_handler(struct notifier_block *self, unsigned long val, void *parm) { printk(KERN_INFO "Raised OOM killer!\n"); return NOTIFY_OK; } static struct notifier_block hoom_oom_nb = { .notifier_call = hoom_oom_handler }; static int hoom_init(void) { int err; if ((err = register_oom_notifier(&hoom_oom_nb)) < 0) { printk(KERN_INFO "probe error %d\n", err); return err; } return 0; } module_init(hoom_init); static void hoom_exit(void) { unregister_oom_notifier(&hoom_oom_nb); } module_exit(hoom_exit); MODULE_LICENSE("GPL");
カーネルモジュールを組み込んだ時実行される hoom_init()の中でregister_oom_notifier()を呼んで、hoom_oom_handler()をnotifierとして登録しています。OOM Killerが発動したら、"Raised OOM killer!”という文字列がカーネルのログに出力されます。
ビルド用のKbuildは以下の通り。
obj-m := mod_hookoom.o mod_hookoom-objs := hookoom.o
ビルドした手順、は長くなるので次回書きます。
ビルド後にこれをinsmodして組み込みました。なお組み込みLinuxを想定した調査ですが、実験はUbuntu 14.04(カーネル3.13.0-43)を載せた仮想マシン上で行っています。
~/work/hookoom>$ sudo insmod mod_hookoom.ko ~/work/hookoom>$ ~/work/hookoom>$ lsmod Module Size Used by mod_hookoom 12571 0 :
さて次はOOM Killerを発動させないといけません。メモリリークを意図的に起こすということで、このとき使ったmemeaterというプログラムをまたビルドして実行しました。すると、
~/work/memeater>$ ./memeater 強制終了 ~/work/memeater>$
意図通り強制終了されました。
このときカーネルログを確認したところ、
~/work/memeater>$ dmesg : [ 187.009487] Raised OOM killer! [ 187.009655] memeater invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0 : [ 187.010420] Out of memory: Kill process 1262 (memeater) score 943 or sacrifice child [ 187.010505] Killed process 1262 (memeater) total-vm:458758196kB, anon-rss:1284992kB, file-rss:28kB :
見事memeaterが OOM KillerにKillされたログとともに、”Raised OOM Killer!”がログ出力されました。
つづく。