Challenging Lua in the NetBSD kernel
2014/01/02(木) 18:16 NetBSD はてブ情報 はてブに登録 はてブ数

Preparation

dec27# uname -a
NetBSD dec27 6.99.28 NetBSD 6.99.28 (GENERIC) #0: Fri Dec 27 23:23:48 UTC 2013  builds@b8.netbsd.org:/home/builds/ab/HEAD/amd64/201312272220Z-obj/home/builds/ab/HEAD/src/sys/arch/amd64/compile/GENERIC amd64
Run as root user.
$ su -
Terminal type is xterm.
dec27#
Run luactl(8).
dec27# luactl
luactl: /dev/lua: Device not configured
dec27# tail -1 /var/log/messages
Jan  2 07:18:18 dec27 /netbsd: WARNING: module error: incompatible module class for `lua' (3 != 1)
Load the module of Lua.
dec27# modload lua
dec27# tail -1 /var/log/messages
Jan  2 07:19:42 dec27 /netbsd: lua0: Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
Run luactl.
dec27# luactl
0 active states:
OK!

Check kernel status by sysctl.
Set the verbose option for debug.
dec27# sysctl -a|grep kern.lua
kern.lua.require = 1
kern.lua.autoload = 1
kern.lua.bytecode = 0
kern.lua.verbose = 0
kern.lua.maxcount = 0
dec27# sysctl -w kern.lua.verbose=1
kern.lua.verbose: 0 -> 1
Create the new state of Lua.
dec27# luactl create s1
s1 created
dec27# tail -1 /var/log/messages
Jan  2 07:25:15 dec27 /netbsd: lua0: state s1 created
dec27# luactl
1 active state:
Name             Creator  Description
s1               user

Hello world!

Create a file(hello1.lua).
dec27# cat hello1.lua
-- hello world!
print("hello world!\n")
Run hello1.lua by luactl.
dec27# luactl load s1 ./hello1.lua
luactl: LUALOAD: Invalid argument
dec27# tail -2 /var/log/messages
Jan  2 07:28:38 dec27 /netbsd: lua0: loading ./hello1.lua into state s1
Jan  2 07:28:38 dec27 /netbsd: lua0: execution error: [string "hello1.lua"]:2: attempt to call global 'print' (a nil value)
Load the system module(luasystm.kmod) for print().
dec27# modload luasystm
dec27# tail -1 /var/log/messages
Jan  2 07:28:02 dec27 /netbsd: lua0: registered lua module systm
dec27# modstat|grep lua
lua              misc       filesys    1     ffffffff81168000 123347   -
luasystm         misc       filesys    0     ffffffff81187000 1784     lua
Modify to systm.print() from print().
dec27# cat hello1.lua
-- hello world!
systm.print("hello world!\n")
Run hello1.lua.
dec27# luactl load s1 ./hello1.lua
luactl: LUALOAD: Invalid argument
dec27# tail -2 /var/log/messages
Jan  2 07:32:53 dec27 /netbsd: lua0: loading ./hello1.lua into state s1
Jan  2 07:32:53 dec27 /netbsd: lua0: execution error: [string "hello1.lua"]:2: attempt to index global 'systm' (a nil value)
Enable the system module by luactl.
dec27# luactl require s1 systm
systm required by s1
dec27# tail -1 /var/log/messages
Jan  2 07:33:55 dec27 /netbsd: lua0: requiring module systm to state s1
Try again.
dec27# luactl load s1 ./hello1.lua
./hello1.lua loaded into s1
dec27# tail -2 /var/log/messages
Jan  2 07:35:16 dec27 /netbsd: lua0: loading ./hello1.lua into state s1
Jan  2 07:35:16 dec27 /netbsd: hello world!
OK!

Call other functions of system module.

dec27# cat hello2.lua
-- print systm.xxx (src/sys/module/luasystm/luasystm.c)
function uname()
  tbl = {"copyright", "cpu_model", "machine", "machine_arch", "osrelease", "ostype", "kernel_ident", "version"}
  for i = 1, #tbl do
    systm.print(systm[tbl[i]] .. "\n")
  end
end

-- hello world!
systm.print("hello world!\n")

-- print systm.xxx
uname()
Run hello2.lua.
dec27# luactl load s1 ./hello2.lua
./hello2.lua loaded into s1
dec27# tail -18  /var/log/messages
Jan  2 07:36:58 dec27 /netbsd: lua0: loading ./hello2.lua into state s1
Jan  2 07:36:58 dec27 /netbsd: hello world!
Jan  2 07:36:58 dec27 /netbsd: Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
Jan  2 07:36:58 dec27 /netbsd:    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
Jan  2 07:36:58 dec27 /netbsd:    The NetBSD Foundation, Inc.  All rights reserved.
Jan  2 07:36:58 dec27 /netbsd: Copyright (c) 1982, 1986, 1989, 1991, 1993
Jan  2 07:36:58 dec27 /netbsd:    The Regents of the University of California.  All rights reserved.
Jan  2 07:36:58 dec27 /netbsd:
Jan  2 07:36:58 dec27 /netbsd:
Jan  2 07:36:58 dec27 /netbsd: Intel 686-class
Jan  2 07:36:58 dec27 /netbsd: amd64
Jan  2 07:36:58 dec27 /netbsd: x86_64
Jan  2 07:36:58 dec27 /netbsd: 6.99.28
Jan  2 07:36:58 dec27 /netbsd: NetBSD
Jan  2 07:36:58 dec27 /netbsd: GENERIC
Jan  2 07:36:58 dec27 /netbsd: NetBSD 6.99.28 (GENERIC) #0: Fri Dec 27 23:23:48 UTC 2013
Jan  2 07:36:58 dec27 /netbsd:  builds@b8.netbsd.org:/home/builds/ab/HEAD/amd64/201312272220Z-obj/home/builds/ab/HEAD/src/sys/arch/amd64/compile/GENERIC
Jan  2 07:36:58 dec27 /netbsd:
OK!

Call the function of another file.

Create & load new file(add.lua).
dec27# cat add.lua
function add(x, y)
 return x + y
end
dec27# luactl load s1 ./add.lua
./add.lua loaded into s1
dec27# tail -1 /var/log/messages
Jan  2 07:39:57 dec27 /netbsd: lua0: loading ./add.lua into state s1
Create & run hello3.lua.
dec27# cat hello3.lua
-- hello world!
systm.print("hello world!\n")

-- call function on add.lua
systm.print("1 + 2 = " .. add(1,2) .. "\n")
dec27# luactl load s1 ./hello3.lua
./hello3.lua loaded into s1
dec27# tail -3 /var/log/messages
Jan  2 07:41:32 dec27 /netbsd: lua0: loading ./hello3.lua into state s1
Jan  2 07:41:32 dec27 /netbsd: hello world!
Jan  2 07:41:32 dec27 /netbsd: 1 + 2 = 3
OK!

Call the lua function from C function in kernel module.

hello4.lua
  -> lcl(x, y) @ lualabo.kmod
    -> add(x, y) @ add.lua
Make directories for kernel module (lualabo).
dec27# mkdir /stand/amd64/6.99.28/modules/lualabo
dec27# mkdir /usr/src/sys/modules/lualabo
dec27# cd /usr/src/sys/modules/lualabo
Create sources of kernel module based on /usr/src/sys/modules/luasystm.
dec27# cat Makefile
#       $NetBSD$

.include "../Makefile.inc"

KMOD=           lualabo
SRCS=           lualabo.c

CPPFLAGS+=      -I${S}/../external/mit/lua/dist/src \
                -I${S}/modules/lua

.include <bsd.kmodule.mk>
dec27#
dec27#
dec27# cat lualabo.c
/*      $NetBSD$ */

/*
 * Copyright (c) 2011, 2013 Marc Balmer <mbalmer@NetBSD.org>.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the Author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/* Lua labo kernel services module */

#include <sys/param.h>
#include <sys/lua.h>
#include <sys/callout.h>
#ifdef _MODULE
#include <sys/module.h>
#endif
#include <sys/systm.h>

#include <lua.h>
#include <lauxlib.h>

#ifdef _MODULE
MODULE(MODULE_CLASS_MISC, lualabo, "lua");

static int
lcl(lua_State *L)
{
        int x,y;

        x = lua_tointeger(L, -2);
        y = lua_tointeger(L, -1);

        lua_getglobal(L, "add");
        lua_pushnumber(L, x);
        lua_pushnumber(L, y);
        lua_pcall(L, 2, 1, 0); /* 2 args, 1 ret */

        printf("lcl()@lualabo: add = %d\n", (int) lua_tointeger(L, -1));

        return 0;
}
/* callouts */

/* mutexes */

static const luaL_Reg labo_lib[ ] = {
        { "lcl",                        lcl },

        /* callouts */

        /* mutexes */

        {NULL, NULL}
};


static int
luaopen_labo(void *ls)
{
        lua_State *L = (lua_State *)ls;

        luaL_register(L, "labo", labo_lib);

        return 1;
}

static int
lualabo_modcmd(modcmd_t cmd, void *opaque)
{
        int error;

        switch (cmd) {
        case MODULE_CMD_INIT:
                error = lua_mod_register("labo", luaopen_labo);
                break;
        case MODULE_CMD_FINI:
                error = lua_mod_unregister("labo");
                break;
        default:
                error = ENOTTY;
        }
        return error;
}
#endif
Build & install lualabo.kmod.
dec27# /usr/obj/tooldir.NetBSD-6.99.28-amd64/bin/nbmake-amd64
dec27# cp lualabo.kmod /stand/amd64/6.99.28/modules/lualabo/
Load lualabo.
dec27# modload lualabo
dec27# tail -1 /var/log/messages
Jan  2 07:49:16 dec27 /netbsd: lua0: registered lua module labo
dec27#
dec27# luactl require s1 labo
labo required by s1
dec27# tail -1 /var/log/messages
Jan  2 07:49:44 dec27 /netbsd: lua0: requiring module labo to state s1
Create hello4.lua.
dec27# cat hello4.lua
-- hello world!
systm.print("hello world!\n")

-- call function on add.lua via lualabo.kmod
labo.lcl(2, 4)
Run hello4.lua.
dec27# luactl load s1 ./hello4.lua
./hello4.lua loaded into s1
dec27# tail -3 /var/log/messages
Jan  2 07:51:39 dec27 /netbsd: lua0: loading ./hello4.lua into state s1
Jan  2 07:51:39 dec27 /netbsd: hello world!
Jan  2 07:51:39 dec27 /netbsd: lcl()@lualabo: add = 6

名前:  非公開コメント   

  • TB-URL  http://www.tokuda.net/diary/0819/tb/