NetBSD Advent Calendar 2018 18日目の記事です。
今日はNetBSD-8.0におけるLuaカーネルモジュールについて紹介しようと思います。
LuaカーネルモジュールはNetBSD-7.0から搭載された機能で、以前にもいくつか記事を書いていました。
NetBSD-8.0では、Luaカーネルモジュールがどう進化(?)しているか見てみようと思います。
NetBSD-8.0でLuaカーネルモジュールを動かす。
まずはさっそく、Luaカーネルモジュールのサンプルを動かしてみます。
Luaカーネルモジュールのロード
Luaカーネルモジュールのロードの前に、 ./MAKEDEV lua
を実行しておきます。
# cd /dev
# ./MAKEDEV lua
#
Luaカーネルモジュールをロードします。 sysctl -w kern.lua.verbose=1
を設定しておくと、うまく動かない時に有用なデバッグ情報が得られるかもしれません。
# moaload lua
# modstat | grep lua
lua misc filesys - 1 109317 -
luasystm misc filesys - 0 889 lua
#
# sysctl -w kern.lua.verbose=1
kern.lua.verbose: 0 -> 1
サンプルLuaスクリプトを動かしてみます。 /usr/src/sys/modules/examples/luahello/luahello.lua
を見ると以下のように書かれているので、この手順で実行します。
/usr/src/sys/modules/examples/luahello/luahello.lua:
# Print `Hello Lua world' in dmesg(8)
#
# Tutorial
# 1. Load the lua and luasystm modules.
# modload lua
# modload luasystm
#
# 2. Create Lua state for our code
# luactl create state1
#
# 3. Require systm(9lua) for state1
# luactl require state1 systm
#
# 4. Load our code in state1
# luactl load state1 ./luahello.lua
#
# NB. The path with our code must contain at least single '/' character
サンプル実行時の地味な注意点
が、上記のサンプルを実行する際にひとつ注意する箇所があります。
Luaのソースコードコメントは --
なのですが、NetBSDのライセンス表記は #
で始まる行で記載されいています。
シェルスクリプト等では #
から始まる行はコメント行として扱われますが、Luaでは文法エラーになってしまいます...。
luactl load state1 ./luahello.lua
とかしても、以下のようなエラーになってしまうので注意してください。
# luactl load state1 ./luahello.lua
luactl: LUALOAD: Invalid argument
sysctl -w kern.lua.verbose=1
しておくと以下のようなカーネルメッセージが出力されますが、ちょっとデバッグ情報としては弱いですね...。
LuaでHello,Worldする
ごく簡単なサンプルなので、自分でHello,Worldを作成してしまうのが早そうです。
以下のようなサンプルを作成して動かしてみます。
systm.print("Hello, Lua kernel module (^_^)\n")
無事にHello,Worldが表示されました。
NetBSDの7.0から8.0におけるLuaカーネルモジュールの変更箇所(あまり変わってなかった...)
さて、NetBSD 7.0から8.0でLuaカーネルモジュールがどう変わっているのか気になります。それぞれのカーネルソースツリーから差分を抽出し\
、変更箇所を見てみます。
Lua周りのファイルは何か追加されているようです。
$ find /pub/src/NetBSD/8.0/usr/src/sys/modules/ | grep lua | grep -v CVS
/pub/src/NetBSD/8.0/usr/src/sys/modules/examples/luahello
/pub/src/NetBSD/8.0/usr/src/sys/modules/examples/luahello/luahello.lua
/pub/src/NetBSD/8.0/usr/src/sys/modules/examples/luareadhappy
/pub/src/NetBSD/8.0/usr/src/sys/modules/examples/luareadhappy/Makefile
/pub/src/NetBSD/8.0/usr/src/sys/modules/examples/luareadhappy/happy.lua
/pub/src/NetBSD/8.0/usr/src/sys/modules/examples/luareadhappy/luareadhappy.c
/pub/src/NetBSD/8.0/usr/src/sys/modules/lua
/pub/src/NetBSD/8.0/usr/src/sys/modules/lua/Makefile
/pub/src/NetBSD/8.0/usr/src/sys/modules/lua/infinite.lua
/pub/src/NetBSD/8.0/usr/src/sys/modules/lua/lua.c
/pub/src/NetBSD/8.0/usr/src/sys/modules/lua/luavar.h
/pub/src/NetBSD/8.0/usr/src/sys/modules/lua/test.lua
/pub/src/NetBSD/8.0/usr/src/sys/modules/luapmf
/pub/src/NetBSD/8.0/usr/src/sys/modules/luapmf/Makefile
/pub/src/NetBSD/8.0/usr/src/sys/modules/luapmf/luapmf.c
/pub/src/NetBSD/8.0/usr/src/sys/modules/luasystm
/pub/src/NetBSD/8.0/usr/src/sys/modules/luasystm/Makefile
/pub/src/NetBSD/8.0/usr/src/sys/modules/luasystm/luasystm.c
/pub/src/NetBSD/8.0/usr/src/sys/modules/luasystm/test.lua
$
$ find /pub/src/NetBSD/7.1.1/usr/src/sys/modules/ | grep lua | grep -v CVS
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/examples/luahello
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/examples/luahello/luahello.lua
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/lua
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/lua/Makefile
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/lua/infinite.lua
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/lua/lua.c
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/lua/luavar.h
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/lua/test.lua
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/luapmf
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/luapmf/Makefile
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/luapmf/luapmf.c
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/luasystm
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/luasystm/Makefile
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/luasystm/luasystm.c
/pub/src/NetBSD/7.1.1/usr/src/sys/modules/luasystm/test.lua
/usr/src/sys/modules/examples/luareadhappy/happy.lua
というサンプルが追加されています。[3日目](https://qiita.com/furandon_pig/i\
tems/647c21cbe21eeb3aafc2)のカーネルモジュールの記事で紹介しした、 readhappy
モジュールのLua版のようです。
$ find /pub/src/NetBSD/7.1.1/usr/src/sys/modules/ | grep lua | grep -v CVS | sed -e "s/^.*\/usr\//\/usr\//" > _7.1.1.txt
$ find /pub/src/NetBSD/8.0/usr/src/sys/modules/ | grep lua | grep -v CVS | sed -e "s/^.*\/usr\//\/usr\//" > _8.0.txt
$
$ diff -ur _7.1.1.txt _8.0.txt
--- _7.1.1.txt 2018-12-18 21:10:05.961585000 +0900
+++ _8.0.txt 2018-12-18 21:10:17.549985000 +0900
@@ -1,5 +1,9 @@
/usr/src/sys/modules/examples/luahello
/usr/src/sys/modules/examples/luahello/luahello.lua
+/usr/src/sys/modules/examples/luareadhappy
+/usr/src/sys/modules/examples/luareadhappy/Makefile
+/usr/src/sys/modules/examples/luareadhappy/happy.lua
+/usr/src/sys/modules/examples/luareadhappy/luareadhappy.c
/usr/src/sys/modules/lua
/usr/src/sys/modules/lua/Makefile
/usr/src/sys/modules/lua/infinite.lua
/usr/src/sys/modules/lua
以下の差分を確認してみます。
$ cd /pub/src/NetBSD/8.0/usr/src/sys/modules/lua
$ for i in `find . -type f | grep -v CVS`
do
diff -ur /pub/src/NetBSD/7.1.1/usr/src/sys/modules/lua/${i} /pub/src/NetBSD/8.0/usr/src/sys/modules/lua/${i}
done
差分は以下になるのですが、LuaモジュールについてはNetBSD 7.0から8.0で大きな変更が入った感じはないですね...。
(NetBSD-8.0に合わせたカーネル関数の扱い方の対応が入った的な修正のみのようです)
--- /pub/src/NetBSD/7.1.1/usr/src/sys/modules/lua/./lua.c 2017-07-23 14:56:36.000000000 +0900
+++ /pub/src/NetBSD/8.0/usr/src/sys/modules/lua/./lua.c 2018-01-07 18:27:32.000000000 +0900
@@ -1,8 +1,8 @@
-/* $NetBSD: lua.c,v 1.13.2.3.4.1 2017/07/23 05:56:36 snj Exp $ */
+/* $NetBSD: lua.c,v 1.23.2.1 2018/01/07 09:27:32 snj Exp $ */
/*
+ * Copyright (c) 2011 - 2017 by Marc Balmer <mbalmer@NetBSD.org>.
* Copyright (c) 2014 by Lourival Vieira Neto <lneto@NetBSD.org>.
- * Copyright (c) 2011, 2013 by Marc Balmer <mbalmer@NetBSD.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -141,7 +141,8 @@
mutex_init(&sc->sc_state_lock, MUTEX_DEFAULT, IPL_VM);
cv_init(&sc->sc_state_cv, "luastate");
- pmf_device_register(self, NULL, NULL);
+ if (!pmf_device_register(self, NULL, NULL))
+ aprint_error_dev(self, "couldn't establish power handler\n");
/* Sysctl to provide some control over behaviour */
sysctl_createv(&sc->sc_log, 0, NULL, &node,
@@ -152,7 +153,7 @@
CTL_KERN, CTL_CREATE, CTL_EOL);
if (node == NULL) {
- printf(": can't create sysctl node\n");
+ aprint_error(": can't create sysctl node\n");
return;
}
@@ -287,6 +288,7 @@
struct pathbuf *pb;
struct vattr va;
struct lua_loadstate ls;
+ struct lua_state_info *states;
int error, n;
klua_State *K;
@@ -306,14 +308,25 @@
LIST_FOREACH(s, &lua_states, lua_next) {
if (n > info->num_states)
break;
- copyoutstr(s->lua_name, info->states[n].name,
- MAX_LUA_NAME, NULL);
- copyoutstr(s->lua_desc, info->states[n].desc,
- MAX_LUA_DESC, NULL);
- info->states[n].user = s->K->ks_user;
n++;
}
info->num_states = n;
+ states = kmem_alloc(sizeof(*states) * n, KM_SLEEP);
+ if (copyin(info->states, states, sizeof(*states) * n)
+ == 0) {
+ n = 0;
+ LIST_FOREACH(s, &lua_states, lua_next) {
+ if (n > info->num_states)
+ break;
+ strcpy(states[n].name, s->lua_name);
+ strcpy(states[n].desc, s->lua_desc);
+ states[n].user = s->K->ks_user;
+ n++;
+ }
+ copyout(states, info->states,
+ sizeof(*states) * n);
+ kmem_free(states, sizeof(*states) * n);
+ }
}
break;
case LUACREATE:
@@ -402,8 +415,8 @@
if (pb == NULL)
return ENOMEM;
NDINIT(&nd, LOOKUP, FOLLOW | NOCHROOT, pb);
- pathbuf_destroy(pb);
error = vn_open(&nd, FREAD, 0);
+ pathbuf_destroy(pb);
if (error) {
if (lua_verbose)
device_printf(sc->sc_dev,
@@ -519,6 +532,10 @@
md->mod_name);
luaL_requiref(L, md->mod_name, md->open, 0);
+ LIST_FOREACH(m, &s->lua_modules, mod_next)
+ if (m == md)
+ return 1;
+
md->refcount++;
LIST_INSERT_HEAD(&s->lua_modules, md, mod_next);
return 1;
@@ -640,7 +657,7 @@
klua_State *
klua_newstate(lua_Alloc f, void *ud, const char *name, const char *desc,
- int ipl)
+ int ipl)
{
klua_State *K;
struct lua_state *s;
@@ -707,6 +724,7 @@
struct lua_module *m;
int error = 0;
+ /* XXX consider registering a handler instead of a fixed name. */
lua_getglobal(K->L, "onClose");
if (lua_isfunction(K->L, -1))
lua_pcall(K->L, -1, 0, 0);
@@ -797,9 +815,11 @@
static const struct cfiattrdata luabus_iattrdata = {
"luabus", 0, { { NULL, NULL, 0 },}
};
+
static const struct cfiattrdata *const lua_attrs[] = {
&luabus_iattrdata, NULL
};
+
CFDRIVER_DECL(lua, DV_DULL, lua_attrs);
extern struct cfattach lua_ca;
static int lualoc[] = {
@@ -807,6 +827,7 @@
-1,
-1
};
+
static struct cfdata lua_cfdata[] = {
{
.cf_name = "lua",
まとめ
Luaカーネルモジュールについて、NetBSD 7.0と8.0の間での変更箇所を見てみました。実際にはほとんど変更がないという状態でしたが、 luareadhappy
というサンプルが追加されており、ユーザランド側のLuaスクリプトで定義した関数をカーネル内から呼び出すというサンプルのようです。
明日の記事ではこのサンプルの中身を見てゆこうと思います。
参考URL
- Lua Basic Syntax