Home | History | Annotate | Line # | Download | only in lua
lua.c revision 1.14
      1 /*	$NetBSD: lua.c,v 1.13 2014/07/25 08:10:40 dholland Exp $ */
      2 
      3 /*
      4  * Copyright (c) 2014 by Lourival Vieira Neto <lneto (at) NetBSD.org>.
      5  * Copyright (c) 2011 - 2014 by Marc Balmer <mbalmer (at) NetBSD.org>.
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. The name of the Author may not be used to endorse or promote products
     17  *    derived from this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 /* Lua device driver */
     33 
     34 #include <sys/param.h>
     35 #include <sys/fcntl.h>
     36 #include <sys/conf.h>
     37 #include <sys/condvar.h>
     38 #include <sys/device.h>
     39 #include <sys/ioctl.h>
     40 #include <sys/kmem.h>
     41 #include <sys/lock.h>
     42 #include <sys/lua.h>
     43 #include <sys/module.h>
     44 #include <sys/mutex.h>
     45 #include <sys/namei.h>
     46 #include <sys/queue.h>
     47 #include <sys/sysctl.h>
     48 #include <sys/vnode.h>
     49 #include <sys/cpu.h>
     50 
     51 #include <lauxlib.h>
     52 
     53 #include "luavar.h"
     54 
     55 struct lua_softc {
     56 	device_t		 sc_dev;
     57 
     58 	kmutex_t		 sc_lock;
     59 	kcondvar_t		 sc_inuse_cv;
     60 	bool			 sc_inuse;
     61 
     62 	/* Locking access to state queues */
     63 	kmutex_t		 sc_state_lock;
     64 	kcondvar_t		 sc_state_cv;
     65 	bool			 sc_state;
     66 
     67 	struct sysctllog	*sc_log;
     68 };
     69 
     70 static device_t	sc_self;
     71 static bool	lua_autoload_on = true;
     72 static bool	lua_require_on = true;
     73 static bool	lua_bytecode_on = false;
     74 static int	lua_verbose;
     75 static int	lua_max_instr;
     76 
     77 static LIST_HEAD(, lua_state)	lua_states;
     78 static LIST_HEAD(, lua_module)	lua_modules;
     79 
     80 static int lua_match(device_t, cfdata_t, void *);
     81 static void lua_attach(device_t, device_t, void *);
     82 static int lua_detach(device_t, int);
     83 static klua_State *klua_find(const char *);
     84 static const char *lua_reader(lua_State *, void *, size_t *);
     85 static void lua_maxcount(lua_State *, lua_Debug *);
     86 
     87 static int lua_require(lua_State *);
     88 
     89 CFATTACH_DECL_NEW(lua, sizeof(struct lua_softc),
     90 	lua_match, lua_attach, lua_detach, NULL);
     91 
     92 dev_type_open(luaopen);
     93 dev_type_close(luaclose);
     94 dev_type_ioctl(luaioctl);
     95 
     96 const struct cdevsw lua_cdevsw = {
     97 	.d_open = luaopen,
     98 	.d_close = luaclose,
     99 	.d_read = noread,
    100 	.d_write = nowrite,
    101 	.d_ioctl = luaioctl,
    102 	.d_stop = nostop,
    103 	.d_tty = notty,
    104 	.d_poll = nopoll,
    105 	.d_mmap = nommap,
    106 	.d_kqfilter = nokqfilter,
    107 	.d_discard = nodiscard,
    108 	.d_flag = D_OTHER | D_MPSAFE
    109 };
    110 
    111 struct lua_loadstate {
    112 	struct vnode	*vp;
    113 	size_t		 size;
    114 	off_t		 off;
    115 };
    116 
    117 extern struct cfdriver lua_cd;
    118 
    119 static int
    120 lua_match(device_t parent, cfdata_t match, void *aux)
    121 {
    122 	return 1;
    123 }
    124 
    125 static void
    126 lua_attach(device_t parent, device_t self, void *aux)
    127 {
    128 	struct lua_softc *sc;
    129 	const struct sysctlnode *node;
    130 
    131 	if (sc_self)
    132 		return;
    133 
    134 	sc = device_private(self);
    135 	sc->sc_dev = self;
    136 	sc_self = self;
    137 
    138 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
    139 	cv_init(&sc->sc_inuse_cv, "luactl");
    140 
    141 	mutex_init(&sc->sc_state_lock, MUTEX_DEFAULT, IPL_VM);
    142 	cv_init(&sc->sc_state_cv, "luastate");
    143 
    144 	pmf_device_register(self, NULL, NULL);
    145 
    146 	/* Sysctl to provide some control over behaviour */
    147         sysctl_createv(&sc->sc_log, 0, NULL, &node,
    148             CTLFLAG_OWNDESC,
    149             CTLTYPE_NODE, "lua",
    150             SYSCTL_DESCR("Lua options"),
    151             NULL, 0, NULL, 0,
    152             CTL_KERN, CTL_CREATE, CTL_EOL);
    153 
    154         if (node == NULL) {
    155 		printf(": can't create sysctl node\n");
    156                 return;
    157 	}
    158 
    159 	/*
    160 	 * XXX Some of the sysctl values must not be changed after the
    161 	 * securelevel has been raised.
    162 	 */
    163         sysctl_createv(&sc->sc_log, 0, &node, NULL,
    164             CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
    165             CTLTYPE_BOOL, "require",
    166             SYSCTL_DESCR("Enable the require command"),
    167             NULL, 0, &lua_require_on, 0,
    168 	    CTL_CREATE, CTL_EOL);
    169 
    170         sysctl_createv(&sc->sc_log, 0, &node, NULL,
    171             CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
    172             CTLTYPE_BOOL, "autoload",
    173             SYSCTL_DESCR("Enable automatic load of modules"),
    174             NULL, 0, &lua_autoload_on, 0,
    175 	    CTL_CREATE, CTL_EOL);
    176 
    177         sysctl_createv(&sc->sc_log, 0, &node, NULL,
    178             CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
    179             CTLTYPE_BOOL, "bytecode",
    180             SYSCTL_DESCR("Enable loading of bytecode"),
    181             NULL, 0, &lua_bytecode_on, 0,
    182 	    CTL_CREATE, CTL_EOL);
    183 
    184         sysctl_createv(&sc->sc_log, 0, &node, NULL,
    185             CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
    186             CTLTYPE_INT, "verbose",
    187             SYSCTL_DESCR("Enable verbose output"),
    188             NULL, 0, &lua_verbose, 0,
    189 	    CTL_CREATE, CTL_EOL);
    190 
    191         sysctl_createv(&sc->sc_log, 0, &node, NULL,
    192             CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
    193             CTLTYPE_INT, "maxcount",
    194             SYSCTL_DESCR("Limit maximum instruction count"),
    195             NULL, 0, &lua_max_instr, 0,
    196 	    CTL_CREATE, CTL_EOL);
    197 
    198 	aprint_normal_dev(self, "%s\n", LUA_COPYRIGHT);
    199 }
    200 
    201 static int
    202 lua_detach(device_t self, int flags)
    203 {
    204 	struct lua_softc *sc;
    205 	struct lua_state *s;
    206 
    207 	sc = device_private(self);
    208 	pmf_device_deregister(self);
    209 
    210 	if (sc->sc_log != NULL) {
    211 		sysctl_teardown(&sc->sc_log);
    212 		sc->sc_log = NULL;
    213 	}
    214 
    215 	/* Traverse the list of states and close them */
    216 	while ((s = LIST_FIRST(&lua_states)) != NULL) {
    217 		LIST_REMOVE(s, lua_next);
    218 		klua_close(s->K);
    219 		if (lua_verbose)
    220 			device_printf(self, "state %s destroyed\n",
    221 			    s->lua_name);
    222 		kmem_free(s, sizeof(struct lua_state));
    223 	}
    224 	mutex_destroy(&sc->sc_lock);
    225 	cv_destroy(&sc->sc_inuse_cv);
    226 	mutex_destroy(&sc->sc_state_lock);
    227 	cv_destroy(&sc->sc_state_cv);
    228 	sc_self = NULL;
    229 	return 0;
    230 }
    231 
    232 int
    233 luaopen(dev_t dev, int flag, int mode, struct lwp *l)
    234 {
    235 	struct lua_softc *sc;
    236 	int error = 0;
    237 
    238 	if (minor(dev) > 0)
    239 		return ENXIO;
    240 
    241 	sc = device_lookup_private(&lua_cd, minor(dev));
    242 	if (sc == NULL)
    243 		return ENXIO;
    244 
    245 	mutex_enter(&sc->sc_lock);
    246 	while (sc->sc_inuse == true) {
    247 		error = cv_wait_sig(&sc->sc_inuse_cv, &sc->sc_lock);
    248 		if (error)
    249 			break;
    250 	}
    251 	if (!error)
    252 		sc->sc_inuse = true;
    253 	mutex_exit(&sc->sc_lock);
    254 
    255 	if (error)
    256 		return error;
    257 	return 0;
    258 }
    259 
    260 int
    261 luaclose(dev_t dev, int flag, int mode, struct lwp *l)
    262 {
    263 	struct lua_softc *sc;
    264 
    265 	if (minor(dev) > 0)
    266 		return ENXIO;
    267 	sc = device_lookup_private(&lua_cd, minor(dev));
    268 	mutex_enter(&sc->sc_lock);
    269 	sc->sc_inuse = false;
    270 	cv_signal(&sc->sc_inuse_cv);
    271 	mutex_exit(&sc->sc_lock);
    272 	return 0;
    273 }
    274 
    275 int
    276 luaioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
    277 {
    278 	struct lua_softc *sc;
    279 	struct lua_info *info;
    280 	struct lua_create *create;
    281 	struct lua_require *require;
    282 	struct lua_load *load;
    283 	struct lua_state *s;
    284 	struct lua_module *m;
    285 	kauth_cred_t cred;
    286 	struct nameidata nd;
    287 	struct pathbuf *pb;
    288 	struct vattr va;
    289 	struct lua_loadstate ls;
    290 	int error, n;
    291 	klua_State *K;
    292 
    293 	sc = device_lookup_private(&lua_cd, minor(dev));
    294 	if (!device_is_active(sc->sc_dev))
    295 		return EBUSY;
    296 
    297 	switch (cmd) {
    298 	case LUAINFO:
    299 		info = data;
    300 		if (info->states == NULL) {
    301 			info->num_states = 0;
    302 			LIST_FOREACH(s, &lua_states, lua_next)
    303 				info->num_states++;
    304 		} else {
    305 			n = 0;
    306 			LIST_FOREACH(s, &lua_states, lua_next) {
    307 				if (n > info->num_states)
    308 					break;
    309 				copyoutstr(s->lua_name, info->states[n].name,
    310 				    MAX_LUA_NAME, NULL);
    311 				copyoutstr(s->lua_desc, info->states[n].desc,
    312 				    MAX_LUA_DESC, NULL);
    313 				info->states[n].user = s->K->ks_user;
    314 				n++;
    315 			}
    316 			info->num_states = n;
    317 		}
    318 		break;
    319 	case LUACREATE:
    320 		create = data;
    321 
    322 		if (*create->name == '_') {
    323 			if (lua_verbose)
    324 				device_printf(sc->sc_dev, "names of user "
    325 				    "created states must not begin with '_'");
    326 				return ENXIO;
    327 		}
    328 		LIST_FOREACH(s, &lua_states, lua_next)
    329 			if (!strcmp(s->lua_name, create->name)) {
    330 				if (lua_verbose)
    331 					device_printf(sc->sc_dev,
    332 					    "state %s exists\n", create->name);
    333 				return EBUSY;
    334 			}
    335 
    336 		K = kluaL_newstate(create->name, create->desc, IPL_NONE);
    337 		K->ks_user = true;
    338 
    339 		if (K == NULL)
    340 			return ENOMEM;
    341 		if (lua_verbose)
    342 			device_printf(sc->sc_dev, "state %s created\n",
    343 			    create->name);
    344 		break;
    345 	case LUADESTROY:
    346 		create = data;
    347 
    348 		K = klua_find(create->name);
    349 
    350 		if (K != NULL && (K->ks_user == true)) {
    351 			klua_close(K);
    352 			return 0;
    353 		}
    354 		return EBUSY;
    355 	case LUAREQUIRE:	/* 'require' a module in a State */
    356 		require = data;
    357 		LIST_FOREACH(s, &lua_states, lua_next)
    358 			if (!strcmp(s->lua_name, require->state))
    359 				LIST_FOREACH(m, &lua_modules, mod_next)
    360 					if (!strcmp(m->mod_name,
    361 					    require->module)) {
    362 					    	if (lua_verbose)
    363 						    	device_printf(
    364 						    	    sc->sc_dev,
    365 					    		    "requiring module "
    366 					    		    "%s to state %s\n",
    367 					    		    m->mod_name,
    368 					    		    s->lua_name);
    369 						klua_lock(s->K);
    370 					    	m->open(s->K->L);
    371 						klua_unlock(s->K);
    372 					    	m->refcount++;
    373 					    	LIST_INSERT_HEAD(
    374 					    	    &s->lua_modules, m,
    375 					    	    mod_next);
    376 					    	return 0;
    377 					}
    378 		return ENXIO;
    379 	case LUALOAD:
    380 		load = data;
    381 		if (strrchr(load->path, '/') == NULL)
    382 			return ENXIO;
    383 
    384 		LIST_FOREACH(s, &lua_states, lua_next)
    385 			if (!strcmp(s->lua_name, load->state)) {
    386 				if (lua_verbose)
    387 					device_printf(sc->sc_dev,
    388 					    "loading %s into state %s\n",
    389 					    load->path, s->lua_name);
    390 				cred = kauth_cred_get();
    391 				pb = pathbuf_create(load->path);
    392 				if (pb == NULL)
    393 					return ENOMEM;
    394 				NDINIT(&nd, LOOKUP, FOLLOW | NOCHROOT, pb);
    395 				pathbuf_destroy(pb);
    396 				error = vn_open(&nd, FREAD, 0);
    397 				if (error) {
    398 					if (lua_verbose)
    399 						device_printf(sc->sc_dev,
    400 						    "error vn_open %d\n",
    401 						    error);
    402 					return error;
    403 				}
    404 				error = VOP_GETATTR(nd.ni_vp, &va,
    405 				    kauth_cred_get());
    406 				if (error) {
    407 					VOP_UNLOCK(nd.ni_vp);
    408 					vn_close(nd.ni_vp, FREAD,
    409 					    kauth_cred_get());
    410 					if (lua_verbose)
    411 						device_printf(sc->sc_dev,
    412 						    "erro VOP_GETATTR %d\n",
    413 						    error);
    414 					return error;
    415 				}
    416 				if (va.va_type != VREG) {
    417 					VOP_UNLOCK(nd.ni_vp);
    418 					vn_close(nd.ni_vp, FREAD,
    419 					    kauth_cred_get());
    420 					return EINVAL;
    421 				}
    422 				ls.vp = nd.ni_vp;
    423 				ls.off = 0L;
    424 				ls.size = va.va_size;
    425 				VOP_UNLOCK(nd.ni_vp);
    426 				klua_lock(s->K);
    427 				error = lua_load(s->K->L, lua_reader, &ls,
    428 				    strrchr(load->path, '/') + 1, "bt");
    429 				vn_close(nd.ni_vp, FREAD, cred);
    430 				switch (error) {
    431 				case 0:	/* no error */
    432 					break;
    433 				case LUA_ERRSYNTAX:
    434 					if (lua_verbose)
    435 						device_printf(sc->sc_dev,
    436 						    "syntax error\n");
    437 					klua_unlock(s->K);
    438 					return EINVAL;
    439 				case LUA_ERRMEM:
    440 					if (lua_verbose)
    441 						device_printf(sc->sc_dev,
    442 						    "memory error\n");
    443 					klua_unlock(s->K);
    444 					return ENOMEM;
    445 				default:
    446 					if (lua_verbose)
    447 						device_printf(sc->sc_dev,
    448 						    "load error %d: %s\n",
    449 						    error,
    450 						    lua_tostring(s->K->L, -1));
    451 					klua_unlock(s->K);
    452 					return EINVAL;
    453 				}
    454 				if (lua_max_instr > 0)
    455 					lua_sethook(s->K->L, lua_maxcount,
    456 					    LUA_MASKCOUNT, lua_max_instr);
    457 				error = lua_pcall(s->K->L, 0, LUA_MULTRET, 0);
    458 				if (error) {
    459 					if (lua_verbose) {
    460 						device_printf(sc->sc_dev,
    461 						    "execution error: %s\n",
    462 						    lua_tostring(s->K->L, -1));
    463 					}
    464 					klua_unlock(s->K);
    465 					return EINVAL;
    466 				}
    467 				klua_unlock(s->K);
    468 				return 0;
    469 			}
    470 		return ENXIO;
    471 	}
    472 	return 0;
    473 }
    474 
    475 static int
    476 lua_require(lua_State *L)
    477 {
    478 	struct lua_state *s;
    479 	struct lua_module *m, *md;
    480 	const char *module;
    481 	char name[MAXPATHLEN];
    482 
    483 	module = lua_tostring(L, -1);
    484 	md = NULL;
    485 	LIST_FOREACH(m, &lua_modules, mod_next)
    486 		if (!strcmp(m->mod_name, module)) {
    487 			md = m;
    488 			break;
    489 		}
    490 
    491 	if (md == NULL && lua_autoload_on && strchr(module, '/') == NULL) {
    492 		snprintf(name, sizeof name, "lua%s", module);
    493 		if (lua_verbose)
    494 			device_printf(sc_self, "autoload %s\n", name);
    495 		module_autoload(name, MODULE_CLASS_MISC);
    496 		LIST_FOREACH(m, &lua_modules, mod_next)
    497 			if (!strcmp(m->mod_name, module)) {
    498 				md = m;
    499 				break;
    500 			}
    501 	}
    502 
    503 	if (md != NULL)
    504 		LIST_FOREACH(s, &lua_states, lua_next)
    505 			if (s->K->L == L) {
    506 				if (lua_verbose)
    507 					device_printf(sc_self,
    508 					    "require module %s\n",
    509 					    md->mod_name);
    510 				md->open(L);
    511 				md->refcount++;
    512 				LIST_INSERT_HEAD(&s->lua_modules, md, mod_next);
    513 				return 1;
    514 			}
    515 
    516 	lua_pushstring(L, "module not found");
    517 	return lua_error(L);
    518 }
    519 
    520 typedef struct {
    521 	size_t size;
    522 } __packed alloc_header_t;
    523 
    524 static void *
    525 lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
    526 {
    527 	void *nptr = NULL;
    528 
    529 	const size_t hdr_size = sizeof(alloc_header_t);
    530 	alloc_header_t *hdr = (alloc_header_t *) ((char *) ptr - hdr_size);
    531 
    532 	if (nsize == 0) { /* freeing */
    533 		if (ptr != NULL)
    534 			kmem_intr_free(hdr, hdr->size);
    535 	} else if (ptr != NULL && nsize <= hdr->size - hdr_size) /* shrinking */
    536 		return ptr; /* don't need to reallocate */
    537 	else { /* creating or expanding */
    538 		km_flag_t sleep = cpu_intr_p() || cpu_softintr_p() ?
    539 			KM_NOSLEEP : KM_SLEEP;
    540 
    541 		size_t alloc_size = nsize + hdr_size;
    542 		alloc_header_t *nhdr = kmem_intr_alloc(alloc_size, sleep);
    543 		if (nhdr == NULL) /* failed to allocate */
    544 			return NULL;
    545 
    546 		nhdr->size = alloc_size;
    547 		nptr = (void *) ((char *) nhdr + hdr_size);
    548 
    549 		if (ptr != NULL) { /* expanding */
    550 			memcpy(nptr, ptr, osize);
    551 			kmem_intr_free(hdr, hdr->size);
    552 		}
    553 	}
    554 	return nptr;
    555 }
    556 
    557 static const char *
    558 lua_reader(lua_State *L, void *data, size_t *size)
    559 {
    560 	struct lua_loadstate *ls;
    561 	static char buf[1024];
    562 	size_t rsiz;
    563 
    564 	ls = data;
    565 	if (ls->size < sizeof(buf))
    566 		rsiz = ls->size;
    567 	else
    568 		rsiz = sizeof(buf);
    569 	vn_rdwr(UIO_READ, ls->vp, buf, rsiz, ls->off, UIO_SYSSPACE,
    570 	    0, curlwp->l_cred, NULL, curlwp);
    571 	if (ls->off == 0L && lua_bytecode_on == false && buf[0] == 0x1b) {
    572 		*size = 0L;
    573 		lua_pushstring(L, "loading of bytecode is not allowed");
    574 		lua_error(L);
    575 		return NULL;
    576 	} else {
    577 		*size = rsiz;
    578 		ls->off += *size;
    579 		ls->size -= *size;
    580 	}
    581 	return buf;
    582 }
    583 
    584 static void
    585 lua_maxcount(lua_State *L, lua_Debug *d)
    586 {
    587 	lua_pushstring(L, "maximum instruction count exceeded");
    588 	lua_error(L);
    589 }
    590 
    591 int
    592 klua_mod_register(const char *name, lua_CFunction open)
    593 {
    594 	struct lua_module *m;
    595 
    596 	LIST_FOREACH(m, &lua_modules, mod_next)
    597 		if (!strcmp(m->mod_name, name))
    598 			return EBUSY;
    599 	m = kmem_zalloc(sizeof(struct lua_module), KM_SLEEP);
    600 	strlcpy(m->mod_name, name, LUA_MAX_MODNAME);
    601 	m->open = open;
    602 	m->refcount = 0;
    603 	LIST_INSERT_HEAD(&lua_modules, m, mod_next);
    604 	if (lua_verbose)
    605 		device_printf(sc_self, "registered lua module %s\n", name);
    606 	return 0;
    607 }
    608 
    609 int
    610 klua_mod_unregister(const char *name)
    611 {
    612 	struct lua_module *m;
    613 
    614 	LIST_FOREACH(m, &lua_modules, mod_next)
    615 		if (!strcmp(m->mod_name, name)) {
    616 			if (m->refcount == 0) {
    617 				LIST_REMOVE(m, mod_next);
    618 				kmem_free(m, sizeof(struct lua_module));
    619 				if (lua_verbose)
    620 					device_printf(sc_self,
    621 					    "unregistered lua module %s\n",
    622 					    name);
    623 				return 0;
    624 			} else
    625 				return EBUSY;
    626 		}
    627 	return 0;
    628 }
    629 
    630 klua_State *
    631 klua_newstate(lua_Alloc f, void *ud, const char *name, const char *desc,
    632     int ipl)
    633 {
    634 	klua_State *K;
    635 	struct lua_state *s;
    636 	struct lua_softc *sc;
    637 	int error = 0;
    638 
    639 	s = kmem_zalloc(sizeof(struct lua_state), KM_SLEEP);
    640 	sc = device_private(sc_self);
    641 	mutex_enter(&sc->sc_state_lock);
    642 	while (sc->sc_state == true) {
    643 		error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock);
    644 		if (error)
    645 			break;
    646 	}
    647 	if (!error)
    648 		sc->sc_state = true;
    649 	mutex_exit(&sc->sc_state_lock);
    650 
    651 	if (error)
    652 		return NULL;
    653 
    654 	K = kmem_zalloc(sizeof(klua_State), KM_SLEEP);
    655 	K->L = lua_newstate(f, ud);
    656 	K->ks_user = false;
    657 	if (K->L == NULL) {
    658 		kmem_free(K, sizeof(klua_State));
    659 		K = NULL;
    660 		goto finish;
    661 	}
    662 
    663 	strlcpy(s->lua_name, name, MAX_LUA_NAME);
    664 	strlcpy(s->lua_desc, desc, MAX_LUA_DESC);
    665 	s->K = K;
    666 
    667 	if (lua_require_on || lua_autoload_on) {
    668 		lua_pushcfunction(K->L, lua_require);
    669 		lua_setglobal(K->L, "require");
    670 	}
    671 	LIST_INSERT_HEAD(&lua_states, s, lua_next);
    672 
    673 	mutex_init(&K->ks_lock, MUTEX_DEFAULT, ipl);
    674 
    675 finish:
    676 	mutex_enter(&sc->sc_state_lock);
    677 	sc->sc_state = false;
    678 	cv_signal(&sc->sc_state_cv);
    679 	mutex_exit(&sc->sc_state_lock);
    680 	return K;
    681 }
    682 
    683 inline klua_State *
    684 kluaL_newstate(const char *name, const char *desc, int ipl)
    685 {
    686 	return klua_newstate(lua_alloc, NULL, name, desc, ipl);
    687 }
    688 
    689 void
    690 klua_close(klua_State *K)
    691 {
    692 	struct lua_state *s;
    693 	struct lua_softc *sc;
    694 	struct lua_module *m;
    695 	int error = 0;
    696 
    697 	/* XXX consider registering a handler instead of a fixed name. */
    698 	lua_getglobal(K->L, "onClose");
    699 	if (lua_isfunction(K->L, -1))
    700 		lua_pcall(K->L, -1, 0, 0);
    701 
    702 	sc = device_private(sc_self);
    703 	mutex_enter(&sc->sc_state_lock);
    704 	while (sc->sc_state == true) {
    705 		error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock);
    706 		if (error)
    707 			break;
    708 	}
    709 	if (!error)
    710 		sc->sc_state = true;
    711 	mutex_exit(&sc->sc_state_lock);
    712 
    713 	if (error)
    714 		return;		/* Nothing we can do... */
    715 
    716 	LIST_FOREACH(s, &lua_states, lua_next)
    717 		if (s->K == K) {
    718 			LIST_REMOVE(s, lua_next);
    719 			LIST_FOREACH(m, &s->lua_modules, mod_next)
    720 				m->refcount--;
    721 			kmem_free(s, sizeof(struct lua_state));
    722 		}
    723 
    724 	lua_close(K->L);
    725 	mutex_destroy(&K->ks_lock);
    726 	kmem_free(K, sizeof(klua_State));
    727 
    728 	mutex_enter(&sc->sc_state_lock);
    729 	sc->sc_state = false;
    730 	cv_signal(&sc->sc_state_cv);
    731 	mutex_exit(&sc->sc_state_lock);
    732 }
    733 
    734 static klua_State *
    735 klua_find(const char *name)
    736 {
    737 	struct lua_state *s;
    738 	struct lua_softc *sc;
    739 	klua_State *K;
    740 	int error = 0;
    741 
    742 	K = NULL;
    743 	sc = device_private(sc_self);
    744 	mutex_enter(&sc->sc_state_lock);
    745 	while (sc->sc_state == true) {
    746 		error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock);
    747 		if (error)
    748 			break;
    749 	}
    750 	if (!error)
    751 		sc->sc_state = true;
    752 	mutex_exit(&sc->sc_state_lock);
    753 
    754 	if (error)
    755 		return NULL;
    756 
    757 	LIST_FOREACH(s, &lua_states, lua_next)
    758 		if (!strcmp(s->lua_name, name)) {
    759 			K = s->K;
    760 			break;
    761 		}
    762 
    763 	mutex_enter(&sc->sc_state_lock);
    764 	sc->sc_state = false;
    765 	cv_signal(&sc->sc_state_cv);
    766 	mutex_exit(&sc->sc_state_lock);
    767 	return K;
    768 }
    769 
    770 inline void
    771 klua_lock(klua_State *K)
    772 {
    773 	mutex_enter(&K->ks_lock);
    774 }
    775 
    776 inline void
    777 klua_unlock(klua_State *K)
    778 {
    779 	mutex_exit(&K->ks_lock);
    780 }
    781 
    782 MODULE(MODULE_CLASS_MISC, lua, NULL);
    783 
    784 #ifdef _MODULE
    785 static const struct cfiattrdata luabus_iattrdata = {
    786 	"luabus", 0, { { NULL, NULL, 0 },}
    787 };
    788 
    789 static const struct cfiattrdata *const lua_attrs[] = {
    790 	&luabus_iattrdata, NULL
    791 };
    792 
    793 CFDRIVER_DECL(lua, DV_DULL, lua_attrs);
    794 extern struct cfattach lua_ca;
    795 static int lualoc[] = {
    796 	-1,
    797 	-1,
    798 	-1
    799 };
    800 
    801 static struct cfdata lua_cfdata[] = {
    802 	{
    803 		.cf_name = "lua",
    804 		.cf_atname = "lua",
    805 		.cf_unit = 0,
    806 		.cf_fstate = FSTATE_STAR,
    807 		.cf_loc = lualoc,
    808 		.cf_flags = 0,
    809 		.cf_pspec = NULL,
    810 	},
    811 	{ NULL, NULL, 0, FSTATE_NOTFOUND, NULL, 0, NULL }
    812 };
    813 #endif
    814 
    815 static int
    816 lua_modcmd(modcmd_t cmd, void *opaque)
    817 {
    818 #ifdef _MODULE
    819 	devmajor_t cmajor, bmajor;
    820 	int error = 0;
    821 
    822 	cmajor = bmajor = NODEVMAJOR;
    823 #endif
    824 	switch (cmd) {
    825 	case MODULE_CMD_INIT:
    826 #ifdef _MODULE
    827 		error = config_cfdriver_attach(&lua_cd);
    828 		if (error)
    829 			return error;
    830 
    831 		error = config_cfattach_attach(lua_cd.cd_name,
    832 		    &lua_ca);
    833 		if (error) {
    834 			config_cfdriver_detach(&lua_cd);
    835 			aprint_error("%s: unable to register cfattach\n",
    836 			    lua_cd.cd_name);
    837 			return error;
    838 		}
    839 		error = config_cfdata_attach(lua_cfdata, 1);
    840 		if (error) {
    841 			config_cfattach_detach(lua_cd.cd_name,
    842 			    &lua_ca);
    843 			config_cfdriver_detach(&lua_cd);
    844 			aprint_error("%s: unable to register cfdata\n",
    845 			    lua_cd.cd_name);
    846 			return error;
    847 		}
    848 		error = devsw_attach(lua_cd.cd_name, NULL, &bmajor,
    849 		    &lua_cdevsw, &cmajor);
    850 		if (error) {
    851 			aprint_error("%s: unable to register devsw\n",
    852 			    lua_cd.cd_name);
    853 			config_cfattach_detach(lua_cd.cd_name, &lua_ca);
    854 			config_cfdriver_detach(&lua_cd);
    855 			return error;
    856 		}
    857 		config_attach_pseudo(lua_cfdata);
    858 #endif
    859 		return 0;
    860 	case MODULE_CMD_FINI:
    861 #ifdef _MODULE
    862 		error = config_cfdata_detach(lua_cfdata);
    863 		if (error)
    864 			return error;
    865 
    866 		config_cfattach_detach(lua_cd.cd_name, &lua_ca);
    867 		config_cfdriver_detach(&lua_cd);
    868 		devsw_detach(NULL, &lua_cdevsw);
    869 #endif
    870 		return 0;
    871 	case MODULE_CMD_AUTOUNLOAD:
    872 		/* no auto-unload */
    873 		return EBUSY;
    874 	default:
    875 		return ENOTTY;
    876 	}
    877 }
    878