読者です 読者をやめる 読者になる 読者になる

TenForward

技術ブログ。はてなダイアリーから移転しました

Linux kernel ソースの netlink の connector のサンプルを動かす

Linux

(2009/3/25 に修正)

Linux の Netlink という仕組みを少々調べてました.一部を除いて資料が少なくてイマイチ何が出きるのか全貌は把握出来てませんが...

その中の NETLINK_CONNECTOR は Documentaion/connector にサンプルがあって,今回調べるきっかけとなった事に使えるかも? と思って,とりあえずサンプルを動かしてみたものの動かない... というのを動かしたメモ.

ソースを見る限りの動きとしては

  • cn_test.c は 1 秒おきにカウンタに +1 して,netlink のソケットにそのメッセージを送っている
  • ucon.c は,cn_test と同じグループ(?)で netlink へ接続して,そのメッセージを受け取っている

という感じです*1

とりあえず,以下でカーネルモジュールが一つ (cn_test.ko),実行ファイルが一つ (ucon) 出来ます.(V=1 はなくても良いけど)

# cd path/to/sample
# make -C /usr/src/linux M=`pwd` V=1

これで

# insmod cn_test.ko
# ./ucon

とやっても無反応...

付属のドキュメント connector.txt を見ると,

2.6.14 netlink code only allows to select a group which is less or equal to the maximum group number, which is used at netlink_kernel_create() time.

と書かれた部分があります.cn_test.c を見ると,この idx と val の定義は

static struct cb_id cn_test_id = { 0x123, 0x456 };

となっているけど,linux/connector.h の CN_NETLINK_USERS は /usr/include/linux/connector.h によると 6 (vanilla kernel の場合) なので,6 以下じゃないとダメっぽい.とりあえず connector.h から拝借して,

static struct cb_id cn_test_id = { CN_IDX_PROC, CN_VAL_PROC };

と書き換えて,ucon.c も

# diff /usr/src/linux/Documentation/connector/ucon.c ./ucon.c
118c117
<     l_local.nl_groups = 0x123; /* bitmask of requested groups */
    • -
> l_local.nl_groups = CN_IDX_PROC;

という感じに変えて make したら無事

bash-3.2# insmod cn_test.ko
bash-3.2# ./ucon 
Wed Feb 25 19:26:42 2009 : [1.2] [00000002.00000000]
Wed Feb 25 19:26:43 2009 : [1.2] [00000003.00000000]
Wed Feb 25 19:26:44 2009 : [1.2] [00000004.00000000]
Wed Feb 25 19:26:45 2009 : [1.2] [00000005.00000000]

という風に 1 秒おきにメッセージが get できましたとさ.(上記出力にはメッセージ出てませんが,出すようにすれば "counter = 1" みたいなメッセージは出力出来ました)

CN_IDX_PROC とか CN_VAL_PROC は connector をモジュールでなく,カーネル組み込みにしたときに,drivers/connector/cn_proc.c というコードもコンパイルされますが,その中で使っているようです."Provide a connector that reports process events to userspace. Send events such as fork, exec, id change (uid, gid, suid, etc), and exit." という用途のもの.なので勝手に使ったらダメですが,とりあえず現在動いているカーネルで定義されている id で,ということでとりあえず使って見ました.

正式には connector.h に追加するみたいですね.

なんでこんなの調べてたかというと,/proc を使わずに,プログラムからシステムの各種情報を取得したかったからなんですよね.それにしてはこれは大げさなので,「出来そう」というのは分かったけど,多分採用せず.これでやるのが妥当かどうかもよく分からないですし.(^^;)

*1:他にそのまま実行しても実行されませんが,cn_test.c もメッセージを受け取る関数があるし,コールバックも設定されていますし,ucon.c もメッセージを送るコードも一応ありました.