1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

NetBSDAdvent Calendar 2018

Day 18

NetBSD-7.0~8.0でのLuaカーネルモジュールの変更箇所(あまり変更なかった...(T_T))

Posted at

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 しておくと以下のようなカーネルメッセージが出力されますが、ちょっとデバッグ情報としては弱いですね...。

SnapCrab_netbsd8 (base) [実行中] - Oracle VM VirtualBox_2018-12-18_21-7-48_No-00.png

LuaでHello,Worldする

ごく簡単なサンプルなので、自分でHello,Worldを作成してしまうのが早そうです。
以下のようなサンプルを作成して動かしてみます。

systm.print("Hello, Lua kernel module (^_^)\n")

無事にHello,Worldが表示されました。

SnapCrab_netbsd8 (base) [実行中] - Oracle VM VirtualBox_2018-12-18_21-10-26_No-00.png

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

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?