それが僕には楽しかったんです。

僕と MySQL と時々 MariaDB

最速のEchoサーバーを目指して、LinuxKernelモジュールを作っていく part2

はじめに

前回はカーネルモジュールで出力をやるところまでやった。
rabbitfoot141.hatenablog.com
今回は、気合でカーネルスレッドを扱えるようにする。

実装

EchoサーバではTCPを使用する、それをスレッドでああだこうだして複数接続を可能にしたい。

その目的のために今回は頑張ってカーネルスレッドを実装する。

kernel moduleでカーネルスレッド


参考にしたのはまつもとりーさんの次の記事。
hb.matsumoto-r.jp

linux/kthread.hとlinux/sched.hいうヘッダーファイルにある関数を使う。

kthread.hがカーネルスレッドに関するあれこれで、sched.hがカーネルで扱うプロセスやそれを扱うtask_structという構造体を使うためにある。

それでは早速コードを晒す。

#include <linux/kthread.h>
#include <linux/sched.h>

struct task_struct *task;

static int kthread_cb(void *arg){

    printk("[%s] running as kthread\n", task->comm);

    while(!kthread_should_stop()){
        schedule();
    }

    return 0;

}

グローバル変数としてtask_structを宣言している。
これにプロセスとして起動したいあれこれを代入して使う。

kthread_cb関数ではカーネルスレッドとしての動かしたい処理を書いている。

それを次のモジュール本体のコードで次のように使う。

static int fastecho_init_module(void){

        printk("Fastest Echo Server Start!!");

        //make kernel thread
        task = kthread_create(kthread_cb, NULL, "lrf141:fastecho");
        
        printk("[%s] wake up as kthread\n", task->comm);

        //launch task
        wake_up_process(task);
        
        return 0;
}

static void fastecho_cleanup_module(void){

        printk("Fastest Echo Server is unloaded!");
        printk("[%s] stop kthread\n", task->comm);
        kthread_stop(task);

}

まず前のコードで宣言したtask_structにkthread_create関数の戻り値を代入する
これでスレッドが使える様になるので、printkの次でwake_up_process関数を呼び出し、プロセスとして起動する

rmmod時にはそれを止める処理を書いている。


これを前回のモジュール本体に組み込んで次のようにする。

$ make
$ sudo insmod fastecho.ko
$ ps auwx | grep "\[lrf141:faste
cho\]"
root     30557 98.3  0.0      0     0 ?        R    16:49   0:05 [lrf141:fast
echo]
$ dmesg
[176532.823327] Fastest Echo Server Start!!
[176532.826178] [lrf141:fastecho] wake up as kthread
[176532.827453] [lrf141:fastecho] running as kthread
[176586.304842] Fastest Echo Server is unloaded![lrf141:fastecho] stop kthrea
d
$ sudo rmmod fastecho.ko

おわりに

まつもとりーさんの記事のおかげでなんとかカーネルスレッドを動かすことはできたので
次はネットワークの部分を実装していきたい。