エンジョイAsobi

スマホとWindowsとLinuxを遊ぶ。

Linux Ubuntu

OOM Killerの発動を検知したい

投稿日:2014年12月15日 更新日:

今回はプログラムの話。タイトル通り、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!”がログ出力されました。

つづく

-Linux, Ubuntu

関連記事

カーネルモジュールのビルド

前回、OOM Killerの発動を検知するテスト用のカーネルモジュールをビルドしたと書きました。前回は長くなるのを避けてビルド手順を端折ったので、改めて記録しておきます。ここを見ながらビルドしました。 …

Hyper-VでUbuntu 14.04を試す(2)

前回の続きです。 作成した仮想マシンにUbuntu 14.04のサーバー版をインストールするところまで。スクリーンショットでどうぞ。 なぜかこのときキーボードの自動検出に失敗したんですよね…。 しよう …

Hyper-VでUbuntu 14.04を試す(3)

前回、仮想マシンにUbuntu 14.04をインストールしました。 続いて環境整備。 まずはIPアドレスをDHCPから固定アドレスに変更。うちの宅内LANではSSHしたりリモートデスクトップしたりする …

Hyper-VでUbuntu 14.04を試す(1)

ついにリリースされました、Ubuntu 14.04。 実験用にインストールした13.10はともかく、実用に使っていた12.04マシンの調子が最近悪くて。インストールし直したかったけど、あと少しで14. …

Ubuntu 14.04 64bitで32bitアプリを使う

新たにVMを作ってUbuntu 12.04から14.04に乗り換えたわけですが、セットアップしていて最初に困ったのは、12.04で使っていた32bitアプリを14.04上で動かそうとしたとき。 Ubu …