Annotation of src/sys/kern/kern_module.c, Revision 1.131
1.131 ! chs 1: /* $NetBSD: kern_module.c,v 1.130 2017/12/14 22:28:59 pgoyette Exp $ */
1.1 ad 2:
3: /*-
4: * Copyright (c) 2008 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
1.25 ad 7: * This code is derived from software developed for The NetBSD Foundation
8: * by Andrew Doran.
9: *
1.1 ad 10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29: * POSSIBILITY OF SUCH DAMAGE.
30: */
31:
32: /*
1.2 ad 33: * Kernel module support.
1.1 ad 34: */
35:
36: #include <sys/cdefs.h>
1.131 ! chs 37: __KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.130 2017/12/14 22:28:59 pgoyette Exp $");
1.54 pooka 38:
39: #define _MODULE_INTERNAL
1.30 ad 40:
41: #ifdef _KERNEL_OPT
42: #include "opt_ddb.h"
1.42 apb 43: #include "opt_modular.h"
1.30 ad 44: #endif
1.1 ad 45:
46: #include <sys/param.h>
47: #include <sys/systm.h>
1.26 ad 48: #include <sys/kernel.h>
1.1 ad 49: #include <sys/proc.h>
50: #include <sys/kauth.h>
51: #include <sys/kobj.h>
52: #include <sys/kmem.h>
53: #include <sys/module.h>
1.26 ad 54: #include <sys/kthread.h>
1.34 ad 55: #include <sys/sysctl.h>
1.46 jnemeth 56: #include <sys/lock.h>
1.1 ad 57:
58: #include <uvm/uvm_extern.h>
59:
1.25 ad 60: struct vm_map *module_map;
1.106 matt 61: const char *module_machine;
1.54 pooka 62: char module_base[MODULE_BASE_SIZE];
1.2 ad 63:
1.59 pooka 64: struct modlist module_list = TAILQ_HEAD_INITIALIZER(module_list);
65: struct modlist module_builtins = TAILQ_HEAD_INITIALIZER(module_builtins);
66: static struct modlist module_bootlist = TAILQ_HEAD_INITIALIZER(module_bootlist);
67:
1.131 ! chs 68: struct module_callbacks {
! 69: TAILQ_ENTRY(module_callbacks) modcb_list;
! 70: void (*modcb_load)(struct module *);
! 71: void (*modcb_unload)(struct module *);
! 72: };
! 73: TAILQ_HEAD(modcblist, module_callbacks);
! 74: static struct modcblist modcblist;
! 75:
! 76: static module_t *module_netbsd;
! 77: static const modinfo_t module_netbsd_modinfo = {
! 78: .mi_version = __NetBSD_Version__,
! 79: .mi_class = MODULE_CLASS_MISC,
! 80: .mi_name = "netbsd"
! 81: };
! 82:
1.12 ad 83: static module_t *module_active;
1.114 pgoyette 84: bool module_verbose_on;
1.99 nonaka 85: #ifdef MODULAR_DEFAULT_AUTOLOAD
1.114 pgoyette 86: bool module_autoload_on = true;
1.98 jnemeth 87: #else
1.114 pgoyette 88: bool module_autoload_on = false;
1.98 jnemeth 89: #endif
1.1 ad 90: u_int module_count;
1.59 pooka 91: u_int module_builtinlist;
1.26 ad 92: u_int module_autotime = 10;
93: u_int module_gen = 1;
94: static kcondvar_t module_thread_cv;
95: static kmutex_t module_thread_lock;
96: static int module_thread_ticks;
1.68 pgoyette 97: int (*module_load_vfs_vec)(const char *, int, bool, module_t *,
1.115 msaitoh 98: prop_dictionary_t *) = (void *)eopnotsupp;
1.1 ad 99:
1.51 elad 100: static kauth_listener_t module_listener;
101:
1.131 ! chs 102: static specificdata_domain_t module_specificdata_domain;
! 103:
1.1 ad 104: /* Ensure that the kernel's link set isn't empty. */
105: static modinfo_t module_dummy;
106: __link_set_add_rodata(modules, module_dummy);
107:
1.70 pgoyette 108: static module_t *module_newmodule(modsrc_t);
1.131 ! chs 109: static void module_free(module_t *);
1.70 pgoyette 110: static void module_require_force(module_t *);
1.9 jmmv 111: static int module_do_load(const char *, bool, int, prop_dictionary_t,
1.100 matt 112: module_t **, modclass_t modclass, bool);
1.70 pgoyette 113: static int module_do_unload(const char *, bool);
1.116 christos 114: static int module_do_builtin(const module_t *, const char *, module_t **,
115: prop_dictionary_t);
1.11 ad 116: static int module_fetch_info(module_t *);
1.26 ad 117: static void module_thread(void *);
1.54 pooka 118:
1.60 pooka 119: static module_t *module_lookup(const char *);
120: static void module_enqueue(module_t *);
121:
1.47 jnemeth 122: static bool module_merge_dicts(prop_dictionary_t, const prop_dictionary_t);
1.1 ad 123:
1.69 pooka 124: static void sysctl_module_setup(void);
1.94 pgoyette 125: static int sysctl_module_autotime(SYSCTLFN_PROTO);
126:
1.131 ! chs 127: static void module_callback_load(struct module *);
! 128: static void module_callback_unload(struct module *);
! 129:
1.100 matt 130: #define MODULE_CLASS_MATCH(mi, modclass) \
131: ((modclass) == MODULE_CLASS_ANY || (modclass) == (mi)->mi_class)
1.88 christos 132:
133: static void
1.100 matt 134: module_incompat(const modinfo_t *mi, int modclass)
1.88 christos 135: {
136: module_error("incompatible module class for `%s' (%d != %d)",
1.100 matt 137: mi->mi_name, modclass, mi->mi_class);
1.88 christos 138: }
1.69 pooka 139:
1.131 ! chs 140: struct module *
! 141: module_kernel(void)
! 142: {
! 143:
! 144: return module_netbsd;
! 145: }
! 146:
1.1 ad 147: /*
148: * module_error:
149: *
150: * Utility function: log an error.
151: */
1.54 pooka 152: void
1.1 ad 153: module_error(const char *fmt, ...)
154: {
155: va_list ap;
156:
157: va_start(ap, fmt);
158: printf("WARNING: module error: ");
159: vprintf(fmt, ap);
160: printf("\n");
161: va_end(ap);
162: }
163:
164: /*
1.34 ad 165: * module_print:
166: *
167: * Utility function: log verbose output.
168: */
1.54 pooka 169: void
1.34 ad 170: module_print(const char *fmt, ...)
171: {
172: va_list ap;
173:
174: if (module_verbose_on) {
175: va_start(ap, fmt);
176: printf("DEBUG: module: ");
177: vprintf(fmt, ap);
178: printf("\n");
179: va_end(ap);
180: }
181: }
182:
1.131 ! chs 183: /*
! 184: * module_name:
! 185: *
! 186: * Utility function: return the module's name.
! 187: */
! 188: const char *
! 189: module_name(struct module *mod)
! 190: {
! 191:
! 192: return mod->mod_info->mi_name;
! 193: }
! 194:
! 195: /*
! 196: * module_source:
! 197: *
! 198: * Utility function: return the module's source.
! 199: */
! 200: modsrc_t
! 201: module_source(struct module *mod)
! 202: {
! 203:
! 204: return mod->mod_source;
! 205: }
! 206:
1.55 elad 207: static int
208: module_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
209: void *arg0, void *arg1, void *arg2, void *arg3)
210: {
211: int result;
212:
213: result = KAUTH_RESULT_DEFER;
214:
215: if (action != KAUTH_SYSTEM_MODULE)
216: return result;
217:
218: if ((uintptr_t)arg2 != 0) /* autoload */
219: result = KAUTH_RESULT_ALLOW;
220:
221: return result;
222: }
223:
1.34 ad 224: /*
1.70 pgoyette 225: * Allocate a new module_t
226: */
227: static module_t *
228: module_newmodule(modsrc_t source)
229: {
230: module_t *mod;
231:
232: mod = kmem_zalloc(sizeof(*mod), KM_SLEEP);
1.125 chs 233: mod->mod_source = source;
1.131 ! chs 234: specificdata_init(module_specificdata_domain, &mod->mod_sdref);
1.70 pgoyette 235: return mod;
236: }
237:
238: /*
1.131 ! chs 239: * Free a module_t
! 240: */
! 241: static void
! 242: module_free(module_t *mod)
! 243: {
! 244:
! 245: specificdata_fini(module_specificdata_domain, &mod->mod_sdref);
! 246: kmem_free(mod, sizeof(*mod));
! 247: }
! 248:
! 249: /*
1.70 pgoyette 250: * Require the -f (force) flag to load a module
251: */
252: static void
253: module_require_force(struct module *mod)
254: {
255: mod->mod_flags |= MODFLG_MUST_FORCE;
256: }
257:
258: /*
1.59 pooka 259: * Add modules to the builtin list. This can done at boottime or
260: * at runtime if the module is linked into the kernel with an
261: * external linker. All or none of the input will be handled.
262: * Optionally, the modules can be initialized. If they are not
263: * initialized, module_init_class() or module_load() can be used
264: * later, but these are not guaranteed to give atomic results.
265: */
266: int
267: module_builtin_add(modinfo_t *const *mip, size_t nmodinfo, bool init)
268: {
269: struct module **modp = NULL, *mod_iter;
270: int rv = 0, i, mipskip;
271:
272: if (init) {
273: rv = kauth_authorize_system(kauth_cred_get(),
274: KAUTH_SYSTEM_MODULE, 0, (void *)(uintptr_t)MODCTL_LOAD,
275: (void *)(uintptr_t)1, NULL);
276: if (rv) {
277: return rv;
278: }
279: }
280:
281: for (i = 0, mipskip = 0; i < nmodinfo; i++) {
282: if (mip[i] == &module_dummy) {
283: KASSERT(nmodinfo > 0);
284: nmodinfo--;
285: }
286: }
287: if (nmodinfo == 0)
288: return 0;
289:
290: modp = kmem_zalloc(sizeof(*modp) * nmodinfo, KM_SLEEP);
291: for (i = 0, mipskip = 0; i < nmodinfo; i++) {
292: if (mip[i+mipskip] == &module_dummy) {
293: mipskip++;
294: continue;
295: }
1.70 pgoyette 296: modp[i] = module_newmodule(MODULE_SOURCE_KERNEL);
1.59 pooka 297: modp[i]->mod_info = mip[i+mipskip];
298: }
1.72 pgoyette 299: kernconfig_lock();
1.59 pooka 300:
301: /* do this in three stages for error recovery and atomicity */
302:
303: /* first check for presence */
304: for (i = 0; i < nmodinfo; i++) {
305: TAILQ_FOREACH(mod_iter, &module_builtins, mod_chain) {
306: if (strcmp(mod_iter->mod_info->mi_name,
307: modp[i]->mod_info->mi_name) == 0)
308: break;
309: }
310: if (mod_iter) {
311: rv = EEXIST;
312: goto out;
313: }
314:
315: if (module_lookup(modp[i]->mod_info->mi_name) != NULL) {
316: rv = EEXIST;
317: goto out;
318: }
319: }
320:
321: /* then add to list */
322: for (i = 0; i < nmodinfo; i++) {
323: TAILQ_INSERT_TAIL(&module_builtins, modp[i], mod_chain);
324: module_builtinlist++;
325: }
326:
327: /* finally, init (if required) */
328: if (init) {
329: for (i = 0; i < nmodinfo; i++) {
1.116 christos 330: rv = module_do_builtin(modp[i],
331: modp[i]->mod_info->mi_name, NULL, NULL);
1.59 pooka 332: /* throw in the towel, recovery hard & not worth it */
333: if (rv)
1.117 christos 334: panic("%s: builtin module \"%s\" init failed:"
335: " %d", __func__,
1.59 pooka 336: modp[i]->mod_info->mi_name, rv);
337: }
338: }
339:
340: out:
1.72 pgoyette 341: kernconfig_unlock();
1.59 pooka 342: if (rv != 0) {
343: for (i = 0; i < nmodinfo; i++) {
344: if (modp[i])
1.131 ! chs 345: module_free(modp[i]);
1.59 pooka 346: }
347: }
348: kmem_free(modp, sizeof(*modp) * nmodinfo);
349: return rv;
350: }
351:
352: /*
353: * Optionally fini and remove builtin module from the kernel.
354: * Note: the module will now be unreachable except via mi && builtin_add.
355: */
356: int
357: module_builtin_remove(modinfo_t *mi, bool fini)
358: {
359: struct module *mod;
360: int rv = 0;
361:
362: if (fini) {
363: rv = kauth_authorize_system(kauth_cred_get(),
364: KAUTH_SYSTEM_MODULE, 0, (void *)(uintptr_t)MODCTL_UNLOAD,
365: NULL, NULL);
366: if (rv)
367: return rv;
368:
1.72 pgoyette 369: kernconfig_lock();
1.70 pgoyette 370: rv = module_do_unload(mi->mi_name, true);
1.59 pooka 371: if (rv) {
372: goto out;
373: }
374: } else {
1.72 pgoyette 375: kernconfig_lock();
1.59 pooka 376: }
377: TAILQ_FOREACH(mod, &module_builtins, mod_chain) {
378: if (strcmp(mod->mod_info->mi_name, mi->mi_name) == 0)
379: break;
380: }
381: if (mod) {
382: TAILQ_REMOVE(&module_builtins, mod, mod_chain);
383: module_builtinlist--;
384: } else {
385: KASSERT(fini == false);
386: rv = ENOENT;
387: }
388:
389: out:
1.72 pgoyette 390: kernconfig_unlock();
1.59 pooka 391: return rv;
392: }
393:
394: /*
1.1 ad 395: * module_init:
396: *
397: * Initialize the module subsystem.
398: */
399: void
400: module_init(void)
401: {
1.59 pooka 402: __link_set_decl(modules, modinfo_t);
1.25 ad 403: extern struct vm_map *module_map;
1.59 pooka 404: modinfo_t *const *mip;
405: int rv;
1.1 ad 406:
1.25 ad 407: if (module_map == NULL) {
408: module_map = kernel_map;
409: }
1.71 pgoyette 410: cv_init(&module_thread_cv, "mod_unld");
1.26 ad 411: mutex_init(&module_thread_lock, MUTEX_DEFAULT, IPL_NONE);
1.131 ! chs 412: TAILQ_INIT(&modcblist);
1.66 pgoyette 413:
1.13 ad 414: #ifdef MODULAR /* XXX */
1.11 ad 415: module_init_md();
1.12 ad 416: #endif
1.16 ad 417:
1.78 mrg 418: if (!module_machine)
419: module_machine = machine;
1.16 ad 420: #if __NetBSD_Version__ / 1000000 % 100 == 99 /* -current */
1.41 rmind 421: snprintf(module_base, sizeof(module_base), "/stand/%s/%s/modules",
1.78 mrg 422: module_machine, osrelease);
1.16 ad 423: #else /* release */
1.41 rmind 424: snprintf(module_base, sizeof(module_base), "/stand/%s/%d.%d/modules",
1.78 mrg 425: module_machine, __NetBSD_Version__ / 100000000,
1.16 ad 426: __NetBSD_Version__ / 1000000 % 100);
427: #endif
1.50 elad 428:
1.55 elad 429: module_listener = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
430: module_listener_cb, NULL);
1.59 pooka 431:
432: __link_set_foreach(mip, modules) {
1.77 mbalmer 433: if ((rv = module_builtin_add(mip, 1, false)) != 0)
1.59 pooka 434: module_error("builtin %s failed: %d\n",
435: (*mip)->mi_name, rv);
436: }
1.69 pooka 437:
438: sysctl_module_setup();
1.131 ! chs 439: module_specificdata_domain = specificdata_domain_create();
! 440:
! 441: module_netbsd = module_newmodule(MODULE_SOURCE_KERNEL);
! 442: module_netbsd->mod_refcnt = 1;
! 443: module_netbsd->mod_info = &module_netbsd_modinfo;
1.51 elad 444: }
445:
1.50 elad 446: /*
1.70 pgoyette 447: * module_start_unload_thread:
1.50 elad 448: *
449: * Start the auto unload kthread.
450: */
451: void
1.70 pgoyette 452: module_start_unload_thread(void)
1.50 elad 453: {
454: int error;
1.26 ad 455:
456: error = kthread_create(PRI_VM, KTHREAD_MPSAFE, NULL, module_thread,
457: NULL, NULL, "modunload");
458: if (error != 0)
1.117 christos 459: panic("%s: %d", __func__, error);
1.1 ad 460: }
461:
1.70 pgoyette 462: /*
463: * module_builtin_require_force
464: *
465: * Require MODCTL_MUST_FORCE to load any built-in modules that have
466: * not yet been initialized
467: */
468: void
469: module_builtin_require_force(void)
470: {
471: module_t *mod;
472:
1.72 pgoyette 473: kernconfig_lock();
1.70 pgoyette 474: TAILQ_FOREACH(mod, &module_builtins, mod_chain) {
475: module_require_force(mod);
476: }
1.72 pgoyette 477: kernconfig_unlock();
1.70 pgoyette 478: }
479:
1.69 pooka 480: static struct sysctllog *module_sysctllog;
481:
1.94 pgoyette 482: static int
483: sysctl_module_autotime(SYSCTLFN_ARGS)
484: {
485: struct sysctlnode node;
486: int t, error;
487:
488: t = *(int *)rnode->sysctl_data;
489:
490: node = *rnode;
491: node.sysctl_data = &t;
492: error = sysctl_lookup(SYSCTLFN_CALL(&node));
493: if (error || newp == NULL)
494: return (error);
495:
496: if (t < 0)
497: return (EINVAL);
498:
499: *(int *)rnode->sysctl_data = t;
500: return (0);
501: }
502:
1.69 pooka 503: static void
504: sysctl_module_setup(void)
1.34 ad 505: {
506: const struct sysctlnode *node = NULL;
507:
1.69 pooka 508: sysctl_createv(&module_sysctllog, 0, NULL, &node,
1.34 ad 509: CTLFLAG_PERMANENT,
510: CTLTYPE_NODE, "module",
511: SYSCTL_DESCR("Module options"),
512: NULL, 0, NULL, 0,
513: CTL_KERN, CTL_CREATE, CTL_EOL);
514:
515: if (node == NULL)
516: return;
517:
1.69 pooka 518: sysctl_createv(&module_sysctllog, 0, &node, NULL,
1.34 ad 519: CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
1.64 jruoho 520: CTLTYPE_BOOL, "autoload",
1.34 ad 521: SYSCTL_DESCR("Enable automatic load of modules"),
522: NULL, 0, &module_autoload_on, 0,
523: CTL_CREATE, CTL_EOL);
1.69 pooka 524: sysctl_createv(&module_sysctllog, 0, &node, NULL,
1.34 ad 525: CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
1.64 jruoho 526: CTLTYPE_BOOL, "verbose",
1.34 ad 527: SYSCTL_DESCR("Enable verbose output"),
528: NULL, 0, &module_verbose_on, 0,
529: CTL_CREATE, CTL_EOL);
1.94 pgoyette 530: sysctl_createv(&module_sysctllog, 0, &node, NULL,
1.97 jnemeth 531: CTLFLAG_PERMANENT | CTLFLAG_READONLY,
532: CTLTYPE_STRING, "path",
533: SYSCTL_DESCR("Default module load path"),
534: NULL, 0, module_base, 0,
535: CTL_CREATE, CTL_EOL);
536: sysctl_createv(&module_sysctllog, 0, &node, NULL,
1.94 pgoyette 537: CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
538: CTLTYPE_INT, "autotime",
539: SYSCTL_DESCR("Auto-unload delay"),
540: sysctl_module_autotime, 0, &module_autotime, 0,
541: CTL_CREATE, CTL_EOL);
1.34 ad 542: }
543:
1.1 ad 544: /*
545: * module_init_class:
546: *
547: * Initialize all built-in and pre-loaded modules of the
548: * specified class.
549: */
550: void
1.100 matt 551: module_init_class(modclass_t modclass)
1.1 ad 552: {
1.63 pooka 553: TAILQ_HEAD(, module) bi_fail = TAILQ_HEAD_INITIALIZER(bi_fail);
1.59 pooka 554: module_t *mod;
555: modinfo_t *mi;
1.1 ad 556:
1.72 pgoyette 557: kernconfig_lock();
1.1 ad 558: /*
1.59 pooka 559: * Builtins first. These will not depend on pre-loaded modules
560: * (because the kernel would not link).
1.1 ad 561: */
1.59 pooka 562: do {
563: TAILQ_FOREACH(mod, &module_builtins, mod_chain) {
564: mi = mod->mod_info;
1.100 matt 565: if (!MODULE_CLASS_MATCH(mi, modclass))
1.59 pooka 566: continue;
1.63 pooka 567: /*
568: * If initializing a builtin module fails, don't try
569: * to load it again. But keep it around and queue it
1.70 pgoyette 570: * on the builtins list after we're done with module
571: * init. Don't set it to MODFLG_MUST_FORCE in case a
572: * future attempt to initialize can be successful.
573: * (If the module has previously been set to
574: * MODFLG_MUST_FORCE, don't try to override that!)
1.63 pooka 575: */
1.100 matt 576: if ((mod->mod_flags & MODFLG_MUST_FORCE) ||
1.116 christos 577: module_do_builtin(mod, mi->mi_name, NULL,
578: NULL) != 0) {
1.63 pooka 579: TAILQ_REMOVE(&module_builtins, mod, mod_chain);
580: TAILQ_INSERT_TAIL(&bi_fail, mod, mod_chain);
581: }
1.59 pooka 582: break;
1.1 ad 583: }
1.59 pooka 584: } while (mod != NULL);
585:
1.1 ad 586: /*
587: * Now preloaded modules. These will be pulled off the
588: * list as we call module_do_load();
589: */
1.11 ad 590: do {
1.59 pooka 591: TAILQ_FOREACH(mod, &module_bootlist, mod_chain) {
1.11 ad 592: mi = mod->mod_info;
1.100 matt 593: if (!MODULE_CLASS_MATCH(mi, modclass))
1.11 ad 594: continue;
1.18 ad 595: module_do_load(mi->mi_name, false, 0, NULL, NULL,
1.100 matt 596: modclass, false);
1.11 ad 597: break;
598: }
599: } while (mod != NULL);
1.63 pooka 600:
1.70 pgoyette 601: /* return failed builtin modules to builtin list */
1.63 pooka 602: while ((mod = TAILQ_FIRST(&bi_fail)) != NULL) {
603: TAILQ_REMOVE(&bi_fail, mod, mod_chain);
604: TAILQ_INSERT_TAIL(&module_builtins, mod, mod_chain);
605: }
606:
1.72 pgoyette 607: kernconfig_unlock();
1.1 ad 608: }
609:
610: /*
1.21 ad 611: * module_compatible:
1.1 ad 612: *
1.21 ad 613: * Return true if the two supplied kernel versions are said to
614: * have the same binary interface for kernel code. The entire
615: * version is signficant for the development tree (-current),
616: * major and minor versions are significant for official
617: * releases of the system.
1.1 ad 618: */
1.22 pooka 619: bool
1.21 ad 620: module_compatible(int v1, int v2)
1.1 ad 621: {
622:
1.21 ad 623: #if __NetBSD_Version__ / 1000000 % 100 == 99 /* -current */
624: return v1 == v2;
625: #else /* release */
626: return abs(v1 - v2) < 10000;
627: #endif
1.1 ad 628: }
629:
630: /*
631: * module_load:
632: *
1.9 jmmv 633: * Load a single module from the file system.
1.1 ad 634: */
635: int
1.18 ad 636: module_load(const char *filename, int flags, prop_dictionary_t props,
1.100 matt 637: modclass_t modclass)
1.1 ad 638: {
1.120 maya 639: module_t *mod;
1.1 ad 640: int error;
641:
1.120 maya 642: /* Test if we already have the module loaded before
643: * authorizing so we have the opportunity to return EEXIST. */
644: kernconfig_lock();
645: mod = module_lookup(filename);
646: if (mod != NULL) {
647: module_print("%s module `%s' already loaded",
648: "requested", filename);
649: error = EEXIST;
650: goto out;
651: }
652:
1.18 ad 653: /* Authorize. */
654: error = kauth_authorize_system(kauth_cred_get(), KAUTH_SYSTEM_MODULE,
655: 0, (void *)(uintptr_t)MODCTL_LOAD, NULL, NULL);
1.120 maya 656: if (error != 0)
657: goto out;
1.18 ad 658:
1.100 matt 659: error = module_do_load(filename, false, flags, props, NULL, modclass,
1.23 ad 660: false);
1.120 maya 661:
662: out:
1.119 maya 663: kernconfig_unlock();
1.1 ad 664: return error;
665: }
666:
667: /*
1.23 ad 668: * module_autoload:
669: *
670: * Load a single module from the file system, system initiated.
671: */
672: int
1.100 matt 673: module_autoload(const char *filename, modclass_t modclass)
1.23 ad 674: {
675: int error;
676:
1.72 pgoyette 677: kernconfig_lock();
1.23 ad 678:
1.34 ad 679: /* Nothing if the user has disabled it. */
680: if (!module_autoload_on) {
1.72 pgoyette 681: kernconfig_unlock();
1.34 ad 682: return EPERM;
683: }
684:
1.56 dholland 685: /* Disallow path separators and magic symlinks. */
1.29 ad 686: if (strchr(filename, '/') != NULL || strchr(filename, '@') != NULL ||
687: strchr(filename, '.') != NULL) {
1.72 pgoyette 688: kernconfig_unlock();
1.29 ad 689: return EPERM;
690: }
691:
1.23 ad 692: /* Authorize. */
693: error = kauth_authorize_system(kauth_cred_get(), KAUTH_SYSTEM_MODULE,
694: 0, (void *)(uintptr_t)MODCTL_LOAD, (void *)(uintptr_t)1, NULL);
695:
1.72 pgoyette 696: if (error == 0)
1.100 matt 697: error = module_do_load(filename, false, 0, NULL, NULL, modclass,
1.72 pgoyette 698: true);
699:
700: kernconfig_unlock();
701: return error;
1.23 ad 702: }
703:
704: /*
1.1 ad 705: * module_unload:
706: *
707: * Find and unload a module by name.
708: */
709: int
710: module_unload(const char *name)
711: {
712: int error;
713:
1.18 ad 714: /* Authorize. */
715: error = kauth_authorize_system(kauth_cred_get(), KAUTH_SYSTEM_MODULE,
716: 0, (void *)(uintptr_t)MODCTL_UNLOAD, NULL, NULL);
717: if (error != 0) {
718: return error;
719: }
720:
1.72 pgoyette 721: kernconfig_lock();
1.70 pgoyette 722: error = module_do_unload(name, true);
1.72 pgoyette 723: kernconfig_unlock();
1.1 ad 724:
725: return error;
726: }
727:
728: /*
729: * module_lookup:
730: *
731: * Look up a module by name.
732: */
733: module_t *
734: module_lookup(const char *name)
735: {
736: module_t *mod;
737:
1.72 pgoyette 738: KASSERT(kernconfig_is_held());
1.1 ad 739:
740: TAILQ_FOREACH(mod, &module_list, mod_chain) {
741: if (strcmp(mod->mod_info->mi_name, name) == 0) {
742: break;
743: }
744: }
745:
746: return mod;
747: }
748:
749: /*
750: * module_hold:
751: *
752: * Add a single reference to a module. It's the caller's
753: * responsibility to ensure that the reference is dropped
754: * later.
755: */
1.131 ! chs 756: void
! 757: module_hold(module_t *mod)
1.1 ad 758: {
759:
1.72 pgoyette 760: kernconfig_lock();
1.1 ad 761: mod->mod_refcnt++;
1.72 pgoyette 762: kernconfig_unlock();
1.1 ad 763: }
764:
765: /*
766: * module_rele:
767: *
768: * Release a reference acquired with module_hold().
769: */
770: void
1.131 ! chs 771: module_rele(module_t *mod)
1.1 ad 772: {
773:
1.72 pgoyette 774: kernconfig_lock();
1.131 ! chs 775: KASSERT(mod->mod_refcnt > 0);
1.1 ad 776: mod->mod_refcnt--;
1.72 pgoyette 777: kernconfig_unlock();
1.1 ad 778: }
779:
780: /*
1.27 ad 781: * module_enqueue:
782: *
783: * Put a module onto the global list and update counters.
784: */
1.53 pooka 785: void
1.27 ad 786: module_enqueue(module_t *mod)
787: {
788: int i;
789:
1.72 pgoyette 790: KASSERT(kernconfig_is_held());
1.53 pooka 791:
1.27 ad 792: /*
1.113 pgoyette 793: * Put new entry at the head of the queue so autounload can unload
794: * requisite modules with only one pass through the queue.
1.27 ad 795: */
1.113 pgoyette 796: TAILQ_INSERT_HEAD(&module_list, mod, mod_chain);
1.27 ad 797: if (mod->mod_nrequired) {
798:
799: /* Add references to the requisite modules. */
800: for (i = 0; i < mod->mod_nrequired; i++) {
801: KASSERT(mod->mod_required[i] != NULL);
802: mod->mod_required[i]->mod_refcnt++;
803: }
804: }
805: module_count++;
806: module_gen++;
807: }
808:
809: /*
1.1 ad 810: * module_do_builtin:
811: *
1.59 pooka 812: * Initialize a module from the list of modules that are
813: * already linked into the kernel.
1.1 ad 814: */
815: static int
1.116 christos 816: module_do_builtin(const module_t *pmod, const char *name, module_t **modp,
817: prop_dictionary_t props)
1.1 ad 818: {
819: const char *p, *s;
820: char buf[MAXMODNAME];
1.59 pooka 821: modinfo_t *mi = NULL;
1.72 pgoyette 822: module_t *mod, *mod2, *mod_loaded, *prev_active;
1.1 ad 823: size_t len;
1.27 ad 824: int error;
1.1 ad 825:
1.72 pgoyette 826: KASSERT(kernconfig_is_held());
1.1 ad 827:
828: /*
1.59 pooka 829: * Search the list to see if we have a module by this name.
1.1 ad 830: */
1.59 pooka 831: TAILQ_FOREACH(mod, &module_builtins, mod_chain) {
832: if (strcmp(mod->mod_info->mi_name, name) == 0) {
833: mi = mod->mod_info;
834: break;
1.1 ad 835: }
836: }
837:
838: /*
1.59 pooka 839: * Check to see if already loaded. This might happen if we
840: * were already loaded as a dependency.
1.1 ad 841: */
1.59 pooka 842: if ((mod_loaded = module_lookup(name)) != NULL) {
843: KASSERT(mod == NULL);
844: if (modp)
845: *modp = mod_loaded;
846: return 0;
1.1 ad 847: }
1.59 pooka 848:
849: /* Note! This is from TAILQ, not immediate above */
1.65 pooka 850: if (mi == NULL) {
851: /*
852: * XXX: We'd like to panic here, but currently in some
853: * cases (such as nfsserver + nfs), the dependee can be
854: * succesfully linked without the dependencies.
855: */
1.116 christos 856: module_error("%s: can't find builtin dependency `%s'",
857: pmod->mod_info->mi_name, name);
1.65 pooka 858: return ENOENT;
859: }
1.1 ad 860:
861: /*
862: * Initialize pre-requisites.
863: */
864: if (mi->mi_required != NULL) {
865: for (s = mi->mi_required; *s != '\0'; s = p) {
866: if (*s == ',')
867: s++;
868: p = s;
869: while (*p != '\0' && *p != ',')
870: p++;
871: len = min(p - s + 1, sizeof(buf));
872: strlcpy(buf, s, len);
873: if (buf[0] == '\0')
874: break;
875: if (mod->mod_nrequired == MAXMODDEPS - 1) {
1.116 christos 876: module_error("%s: too many required modules "
877: "%d >= %d", pmod->mod_info->mi_name,
878: mod->mod_nrequired, MAXMODDEPS - 1);
1.1 ad 879: return EINVAL;
880: }
1.116 christos 881: error = module_do_builtin(mod, buf, &mod2, NULL);
1.1 ad 882: if (error != 0) {
883: return error;
884: }
885: mod->mod_required[mod->mod_nrequired++] = mod2;
886: }
887: }
888:
889: /*
890: * Try to initialize the module.
891: */
1.72 pgoyette 892: prev_active = module_active;
1.12 ad 893: module_active = mod;
1.74 pooka 894: error = (*mi->mi_modcmd)(MODULE_CMD_INIT, props);
1.72 pgoyette 895: module_active = prev_active;
1.1 ad 896: if (error != 0) {
897: module_error("builtin module `%s' "
1.90 christos 898: "failed to init, error %d", mi->mi_name, error);
1.1 ad 899: return error;
900: }
1.59 pooka 901:
902: /* load always succeeds after this point */
903:
904: TAILQ_REMOVE(&module_builtins, mod, mod_chain);
905: module_builtinlist--;
906: if (modp != NULL) {
907: *modp = mod;
908: }
1.27 ad 909: module_enqueue(mod);
1.1 ad 910: return 0;
911: }
912:
913: /*
914: * module_do_load:
915: *
916: * Helper routine: load a module from the file system, or one
917: * pushed by the boot loader.
918: */
919: static int
1.27 ad 920: module_do_load(const char *name, bool isdep, int flags,
1.100 matt 921: prop_dictionary_t props, module_t **modp, modclass_t modclass,
1.20 ad 922: bool autoload)
1.1 ad 923: {
1.72 pgoyette 924: #define MODULE_MAX_DEPTH 6
925:
926: TAILQ_HEAD(pending_t, module);
927: static int depth = 0;
928: static struct pending_t *pending_lists[MODULE_MAX_DEPTH];
929: struct pending_t *pending;
930: struct pending_t new_pending = TAILQ_HEAD_INITIALIZER(new_pending);
1.1 ad 931: modinfo_t *mi;
1.72 pgoyette 932: module_t *mod, *mod2, *prev_active;
1.46 jnemeth 933: prop_dictionary_t filedict;
1.54 pooka 934: char buf[MAXMODNAME];
1.1 ad 935: const char *s, *p;
936: int error;
1.54 pooka 937: size_t len;
1.1 ad 938:
1.72 pgoyette 939: KASSERT(kernconfig_is_held());
1.1 ad 940:
1.46 jnemeth 941: filedict = NULL;
1.1 ad 942: error = 0;
943:
944: /*
945: * Avoid recursing too far.
946: */
1.72 pgoyette 947: if (++depth > MODULE_MAX_DEPTH) {
1.90 christos 948: module_error("recursion too deep for `%s' %d > %d", name,
949: depth, MODULE_MAX_DEPTH);
1.1 ad 950: depth--;
951: return EMLINK;
952: }
953:
954: /*
1.72 pgoyette 955: * Set up the pending list for this depth. If this is a
956: * recursive entry, then use same list as for outer call,
957: * else use the locally allocated list. In either case,
958: * remember which one we're using.
959: */
960: if (isdep) {
961: KASSERT(depth > 1);
962: pending = pending_lists[depth - 2];
963: } else
964: pending = &new_pending;
965: pending_lists[depth - 1] = pending;
966:
967: /*
1.59 pooka 968: * Search the list of disabled builtins first.
969: */
970: TAILQ_FOREACH(mod, &module_builtins, mod_chain) {
971: if (strcmp(mod->mod_info->mi_name, name) == 0) {
972: break;
973: }
974: }
975: if (mod) {
1.70 pgoyette 976: if ((mod->mod_flags & MODFLG_MUST_FORCE) &&
977: (flags & MODCTL_LOAD_FORCE) == 0) {
1.62 pooka 978: if (!autoload) {
979: module_error("use -f to reinstate "
1.90 christos 980: "builtin module `%s'", name);
1.62 pooka 981: }
1.59 pooka 982: depth--;
983: return EPERM;
984: } else {
1.116 christos 985: error = module_do_builtin(mod, name, modp, props);
1.59 pooka 986: depth--;
987: return error;
988: }
989: }
990:
991: /*
1.1 ad 992: * Load the module and link. Before going to the file system,
1.57 pooka 993: * scan the list of modules loaded by the boot loader.
1.1 ad 994: */
995: TAILQ_FOREACH(mod, &module_bootlist, mod_chain) {
1.27 ad 996: if (strcmp(mod->mod_info->mi_name, name) == 0) {
1.1 ad 997: TAILQ_REMOVE(&module_bootlist, mod, mod_chain);
998: break;
999: }
1000: }
1.14 rumble 1001: if (mod != NULL) {
1.72 pgoyette 1002: TAILQ_INSERT_TAIL(pending, mod, mod_chain);
1.14 rumble 1003: } else {
1.27 ad 1004: /*
1.110 pgoyette 1005: * Check to see if module is already present.
1.27 ad 1006: */
1.110 pgoyette 1007: mod = module_lookup(name);
1008: if (mod != NULL) {
1009: if (modp != NULL) {
1010: *modp = mod;
1.27 ad 1011: }
1.110 pgoyette 1012: module_print("%s module `%s' already loaded",
1013: isdep ? "dependent" : "requested", name);
1014: depth--;
1015: return EEXIST;
1.109 maxv 1016: }
1.110 pgoyette 1017:
1.70 pgoyette 1018: mod = module_newmodule(MODULE_SOURCE_FILESYS);
1.1 ad 1019: if (mod == NULL) {
1.38 christos 1020: module_error("out of memory for `%s'", name);
1.1 ad 1021: depth--;
1022: return ENOMEM;
1023: }
1.54 pooka 1024:
1.67 pgoyette 1025: error = module_load_vfs_vec(name, flags, autoload, mod,
1026: &filedict);
1.1 ad 1027: if (error != 0) {
1.91 christos 1028: #ifdef DEBUG
1.92 christos 1029: /*
1030: * The exec class of modules contains a list of
1031: * modules that is the union of all the modules
1032: * available for each architecture, so we don't
1033: * print an error if they are missing.
1034: */
1.104 christos 1035: if ((modclass != MODULE_CLASS_EXEC || error != ENOENT)
1.105 christos 1036: && root_device != NULL)
1.92 christos 1037: module_error("vfs load failed for `%s', "
1038: "error %d", name, error);
1.91 christos 1039: #endif
1.131 ! chs 1040: module_free(mod);
1.1 ad 1041: depth--;
1.8 rumble 1042: return error;
1.7 rumble 1043: }
1.72 pgoyette 1044: TAILQ_INSERT_TAIL(pending, mod, mod_chain);
1.54 pooka 1045:
1.11 ad 1046: error = module_fetch_info(mod);
1047: if (error != 0) {
1.90 christos 1048: module_error("cannot fetch info for `%s', error %d",
1049: name, error);
1.11 ad 1050: goto fail;
1051: }
1.1 ad 1052: }
1053:
1054: /*
1.11 ad 1055: * Check compatibility.
1.1 ad 1056: */
1057: mi = mod->mod_info;
1.3 rumble 1058: if (strlen(mi->mi_name) >= MAXMODNAME) {
1059: error = EINVAL;
1.90 christos 1060: module_error("module name `%s' longer than %d", mi->mi_name,
1061: MAXMODNAME);
1.3 rumble 1062: goto fail;
1063: }
1.21 ad 1064: if (!module_compatible(mi->mi_version, __NetBSD_Version__)) {
1.87 christos 1065: module_error("module `%s' built for `%d', system `%d'",
1066: mi->mi_name, mi->mi_version, __NetBSD_Version__);
1.24 ad 1067: if ((flags & MODCTL_LOAD_FORCE) != 0) {
1068: module_error("forced load, system may be unstable");
1069: } else {
1070: error = EPROGMISMATCH;
1071: goto fail;
1072: }
1.21 ad 1073: }
1.3 rumble 1074:
1.1 ad 1075: /*
1.18 ad 1076: * If a specific kind of module was requested, ensure that we have
1077: * a match.
1078: */
1.100 matt 1079: if (!MODULE_CLASS_MATCH(mi, modclass)) {
1080: module_incompat(mi, modclass);
1.18 ad 1081: error = ENOENT;
1082: goto fail;
1083: }
1084:
1085: /*
1.27 ad 1086: * If loading a dependency, `name' is a plain module name.
1.1 ad 1087: * The name must match.
1088: */
1.27 ad 1089: if (isdep && strcmp(mi->mi_name, name) != 0) {
1.32 christos 1090: module_error("dependency name mismatch (`%s' != `%s')",
1091: name, mi->mi_name);
1.1 ad 1092: error = ENOENT;
1093: goto fail;
1094: }
1095:
1096: /*
1.126 pgoyette 1097: * If we loaded a module from the filesystem, check the actual
1098: * module name (from the modinfo_t) to ensure another module
1099: * with the same name doesn't already exist. (There's no
1100: * guarantee the filename will match the module name, and the
1101: * dup-symbols check may not be sufficient.)
1102: */
1103: if (mod->mod_source == MODULE_SOURCE_FILESYS) {
1104: mod2 = module_lookup(mod->mod_info->mi_name);
1.130 pgoyette 1105: if ( mod2 && mod2 != mod) {
1.126 pgoyette 1106: module_error("module with name `%s' already loaded",
1107: mod2->mod_info->mi_name);
1108: error = EEXIST;
1109: goto fail;
1110: }
1111: }
1112:
1113: /*
1.3 rumble 1114: * Block circular dependencies.
1115: */
1.72 pgoyette 1116: TAILQ_FOREACH(mod2, pending, mod_chain) {
1.1 ad 1117: if (mod == mod2) {
1118: continue;
1119: }
1120: if (strcmp(mod2->mod_info->mi_name, mi->mi_name) == 0) {
1.109 maxv 1121: error = EDEADLK;
1.32 christos 1122: module_error("circular dependency detected for `%s'",
1123: mi->mi_name);
1.109 maxv 1124: goto fail;
1.1 ad 1125: }
1126: }
1127:
1128: /*
1129: * Now try to load any requisite modules.
1130: */
1131: if (mi->mi_required != NULL) {
1132: for (s = mi->mi_required; *s != '\0'; s = p) {
1133: if (*s == ',')
1134: s++;
1135: p = s;
1136: while (*p != '\0' && *p != ',')
1137: p++;
1.3 rumble 1138: len = p - s + 1;
1139: if (len >= MAXMODNAME) {
1140: error = EINVAL;
1.90 christos 1141: module_error("required module name `%s' "
1142: "longer than %d", mi->mi_required,
1143: MAXMODNAME);
1.3 rumble 1144: goto fail;
1145: }
1.1 ad 1146: strlcpy(buf, s, len);
1147: if (buf[0] == '\0')
1148: break;
1149: if (mod->mod_nrequired == MAXMODDEPS - 1) {
1150: error = EINVAL;
1.90 christos 1151: module_error("too many required modules "
1152: "%d >= %d", mod->mod_nrequired,
1153: MAXMODDEPS - 1);
1.1 ad 1154: goto fail;
1155: }
1.6 rumble 1156: if (strcmp(buf, mi->mi_name) == 0) {
1157: error = EDEADLK;
1.32 christos 1158: module_error("self-dependency detected for "
1159: "`%s'", mi->mi_name);
1.6 rumble 1160: goto fail;
1161: }
1.9 jmmv 1162: error = module_do_load(buf, true, flags, NULL,
1.81 christos 1163: &mod2, MODULE_CLASS_ANY, true);
1.110 pgoyette 1164: if (error != 0 && error != EEXIST) {
1.96 maxv 1165: module_error("recursive load failed for `%s' "
1166: "(`%s' required), error %d", mi->mi_name,
1167: buf, error);
1.1 ad 1168: goto fail;
1.88 christos 1169: }
1.81 christos 1170: mod->mod_required[mod->mod_nrequired++] = mod2;
1.1 ad 1171: }
1172: }
1173:
1174: /*
1.15 ad 1175: * We loaded all needed modules successfully: perform global
1176: * relocations and initialize.
1.1 ad 1177: */
1.15 ad 1178: error = kobj_affix(mod->mod_kobj, mi->mi_name);
1179: if (error != 0) {
1.36 ad 1180: /* Cannot touch 'mi' as the module is now gone. */
1.90 christos 1181: module_error("unable to affix module `%s', error %d", name,
1182: error);
1.15 ad 1183: goto fail2;
1184: }
1185:
1.54 pooka 1186: if (filedict) {
1187: if (!module_merge_dicts(filedict, props)) {
1.90 christos 1188: module_error("module properties failed for %s", name);
1.54 pooka 1189: error = EINVAL;
1.46 jnemeth 1190: goto fail;
1191: }
1192: }
1.72 pgoyette 1193: prev_active = module_active;
1.12 ad 1194: module_active = mod;
1.54 pooka 1195: error = (*mi->mi_modcmd)(MODULE_CMD_INIT, filedict ? filedict : props);
1.72 pgoyette 1196: module_active = prev_active;
1.54 pooka 1197: if (filedict) {
1.46 jnemeth 1198: prop_object_release(filedict);
1.54 pooka 1199: filedict = NULL;
1.46 jnemeth 1200: }
1.1 ad 1201: if (error != 0) {
1.90 christos 1202: module_error("modcmd function failed for `%s', error %d",
1203: mi->mi_name, error);
1.1 ad 1204: goto fail;
1205: }
1.54 pooka 1206:
1.1 ad 1207: /*
1.130 pgoyette 1208: * If a recursive load already added a module with the same
1209: * name, abort.
1210: */
1211: mod2 = module_lookup(mi->mi_name);
1212: if (mod2 && mod2 != mod) {
1213: module_error("recursive load causes duplicate module `%s'",
1214: mi->mi_name);
1215: error = EEXIST;
1216: goto fail1;
1217: }
1218:
1219: /*
1.1 ad 1220: * Good, the module loaded successfully. Put it onto the
1221: * list and add references to its requisite modules.
1222: */
1.72 pgoyette 1223: TAILQ_REMOVE(pending, mod, mod_chain);
1.27 ad 1224: module_enqueue(mod);
1.1 ad 1225: if (modp != NULL) {
1226: *modp = mod;
1227: }
1.94 pgoyette 1228: if (autoload && module_autotime > 0) {
1.26 ad 1229: /*
1230: * Arrange to try unloading the module after
1.94 pgoyette 1231: * a short delay unless auto-unload is disabled.
1.26 ad 1232: */
1233: mod->mod_autotime = time_second + module_autotime;
1.83 jmcneill 1234: mod->mod_flags |= MODFLG_AUTO_LOADED;
1.26 ad 1235: module_thread_kick();
1236: }
1.1 ad 1237: depth--;
1.107 pgoyette 1238: module_print("module `%s' loaded successfully", mi->mi_name);
1.131 ! chs 1239: module_callback_load(mod);
1.1 ad 1240: return 0;
1.7 rumble 1241:
1.130 pgoyette 1242: fail1:
1243: (*mi->mi_modcmd)(MODULE_CMD_FINI, NULL);
1.1 ad 1244: fail:
1.15 ad 1245: kobj_unload(mod->mod_kobj);
1246: fail2:
1.54 pooka 1247: if (filedict != NULL) {
1248: prop_object_release(filedict);
1249: filedict = NULL;
1250: }
1.72 pgoyette 1251: TAILQ_REMOVE(pending, mod, mod_chain);
1.131 ! chs 1252: module_free(mod);
1.1 ad 1253: depth--;
1254: return error;
1255: }
1256:
1257: /*
1258: * module_do_unload:
1259: *
1260: * Helper routine: do the dirty work of unloading a module.
1261: */
1262: static int
1.70 pgoyette 1263: module_do_unload(const char *name, bool load_requires_force)
1.1 ad 1264: {
1.72 pgoyette 1265: module_t *mod, *prev_active;
1.1 ad 1266: int error;
1267: u_int i;
1268:
1.72 pgoyette 1269: KASSERT(kernconfig_is_held());
1.85 jnemeth 1270: KASSERT(name != NULL);
1.1 ad 1271:
1.107 pgoyette 1272: module_print("unload requested for '%s' (%s)", name,
1.117 christos 1273: load_requires_force ? "TRUE" : "FALSE");
1.1 ad 1274: mod = module_lookup(name);
1275: if (mod == NULL) {
1.32 christos 1276: module_error("module `%s' not found", name);
1.1 ad 1277: return ENOENT;
1278: }
1.59 pooka 1279: if (mod->mod_refcnt != 0) {
1.107 pgoyette 1280: module_print("module `%s' busy (%d refs)", name,
1.108 pgoyette 1281: mod->mod_refcnt);
1.1 ad 1282: return EBUSY;
1283: }
1.76 pooka 1284:
1285: /*
1286: * Builtin secmodels are there to stay.
1287: */
1288: if (mod->mod_source == MODULE_SOURCE_KERNEL &&
1289: mod->mod_info->mi_class == MODULE_CLASS_SECMODEL) {
1.107 pgoyette 1290: module_print("cannot unload built-in secmodel module `%s'",
1291: name);
1.76 pooka 1292: return EPERM;
1293: }
1294:
1.72 pgoyette 1295: prev_active = module_active;
1.12 ad 1296: module_active = mod;
1.131 ! chs 1297: module_callback_unload(mod);
1.1 ad 1298: error = (*mod->mod_info->mi_modcmd)(MODULE_CMD_FINI, NULL);
1.72 pgoyette 1299: module_active = prev_active;
1.1 ad 1300: if (error != 0) {
1.34 ad 1301: module_print("cannot unload module `%s' error=%d", name,
1.33 ad 1302: error);
1.1 ad 1303: return error;
1304: }
1305: module_count--;
1306: TAILQ_REMOVE(&module_list, mod, mod_chain);
1307: for (i = 0; i < mod->mod_nrequired; i++) {
1308: mod->mod_required[i]->mod_refcnt--;
1309: }
1.85 jnemeth 1310: module_print("unloaded module `%s'", name);
1.1 ad 1311: if (mod->mod_kobj != NULL) {
1312: kobj_unload(mod->mod_kobj);
1313: }
1.59 pooka 1314: if (mod->mod_source == MODULE_SOURCE_KERNEL) {
1315: mod->mod_nrequired = 0; /* will be re-parsed */
1.70 pgoyette 1316: if (load_requires_force)
1317: module_require_force(mod);
1.59 pooka 1318: TAILQ_INSERT_TAIL(&module_builtins, mod, mod_chain);
1319: module_builtinlist++;
1320: } else {
1.131 ! chs 1321: module_free(mod);
1.59 pooka 1322: }
1.26 ad 1323: module_gen++;
1.1 ad 1324:
1325: return 0;
1326: }
1327:
1328: /*
1329: * module_prime:
1330: *
1331: * Push a module loaded by the bootloader onto our internal
1332: * list.
1333: */
1334: int
1.80 christos 1335: module_prime(const char *name, void *base, size_t size)
1.1 ad 1336: {
1.111 pgoyette 1337: __link_set_decl(modules, modinfo_t);
1338: modinfo_t *const *mip;
1.1 ad 1339: module_t *mod;
1340: int error;
1341:
1.112 pgoyette 1342: /* Check for module name same as a built-in module */
1.111 pgoyette 1343:
1344: __link_set_foreach(mip, modules) {
1345: if (*mip == &module_dummy)
1346: continue;
1347: if (strcmp((*mip)->mi_name, name) == 0) {
1348: module_error("module `%s' pushed by boot loader "
1349: "already exists", name);
1350: return EEXIST;
1351: }
1352: }
1.112 pgoyette 1353:
1354: /* Also eliminate duplicate boolist entries */
1355:
1356: TAILQ_FOREACH(mod, &module_bootlist, mod_chain) {
1357: if (strcmp(mod->mod_info->mi_name, name) == 0) {
1358: module_error("duplicate bootlist entry for module "
1359: "`%s'", name);
1360: return EEXIST;
1361: }
1362: }
1363:
1364: mod = module_newmodule(MODULE_SOURCE_BOOT);
1365: if (mod == NULL) {
1366: return ENOMEM;
1367: }
1368:
1.80 christos 1369: error = kobj_load_mem(&mod->mod_kobj, name, base, size);
1.1 ad 1370: if (error != 0) {
1.131 ! chs 1371: module_free(mod);
1.90 christos 1372: module_error("unable to load `%s' pushed by boot loader, "
1373: "error %d", name, error);
1.11 ad 1374: return error;
1375: }
1376: error = module_fetch_info(mod);
1377: if (error != 0) {
1378: kobj_unload(mod->mod_kobj);
1.131 ! chs 1379: module_free(mod);
1.111 pgoyette 1380: module_error("unable to fetch_info for `%s' pushed by boot "
1381: "loader, error %d", name, error);
1.1 ad 1382: return error;
1383: }
1.11 ad 1384:
1.1 ad 1385: TAILQ_INSERT_TAIL(&module_bootlist, mod, mod_chain);
1386:
1387: return 0;
1388: }
1.11 ad 1389:
1390: /*
1391: * module_fetch_into:
1392: *
1393: * Fetch modinfo record from a loaded module.
1394: */
1395: static int
1396: module_fetch_info(module_t *mod)
1397: {
1398: int error;
1399: void *addr;
1400: size_t size;
1401:
1402: /*
1403: * Find module info record and check compatibility.
1404: */
1405: error = kobj_find_section(mod->mod_kobj, "link_set_modules",
1406: &addr, &size);
1407: if (error != 0) {
1.90 christos 1408: module_error("`link_set_modules' section not present, "
1409: "error %d", error);
1.11 ad 1410: return error;
1411: }
1412: if (size != sizeof(modinfo_t **)) {
1.90 christos 1413: module_error("`link_set_modules' section wrong size %zu != %zu",
1414: size, sizeof(modinfo_t **));
1.84 tron 1415: return ENOEXEC;
1.11 ad 1416: }
1417: mod->mod_info = *(modinfo_t **)addr;
1418:
1419: return 0;
1420: }
1.12 ad 1421:
1422: /*
1423: * module_find_section:
1424: *
1425: * Allows a module that is being initialized to look up a section
1426: * within its ELF object.
1427: */
1428: int
1429: module_find_section(const char *name, void **addr, size_t *size)
1430: {
1431:
1.72 pgoyette 1432: KASSERT(kernconfig_is_held());
1.12 ad 1433: KASSERT(module_active != NULL);
1434:
1435: return kobj_find_section(module_active->mod_kobj, name, addr, size);
1436: }
1.26 ad 1437:
1438: /*
1439: * module_thread:
1440: *
1441: * Automatically unload modules. We try once to unload autoloaded
1442: * modules after module_autotime seconds. If the system is under
1.94 pgoyette 1443: * severe memory pressure, we'll try unloading all modules, else if
1444: * module_autotime is zero, we don't try to unload, even if the
1445: * module was previously scheduled for unload.
1.26 ad 1446: */
1447: static void
1448: module_thread(void *cookie)
1449: {
1450: module_t *mod, *next;
1.28 ad 1451: modinfo_t *mi;
1452: int error;
1.26 ad 1453:
1454: for (;;) {
1.72 pgoyette 1455: kernconfig_lock();
1.26 ad 1456: for (mod = TAILQ_FIRST(&module_list); mod != NULL; mod = next) {
1457: next = TAILQ_NEXT(mod, mod_chain);
1.83 jmcneill 1458:
1459: /* skip built-in modules */
1.61 pooka 1460: if (mod->mod_source == MODULE_SOURCE_KERNEL)
1461: continue;
1.83 jmcneill 1462: /* skip modules that weren't auto-loaded */
1463: if ((mod->mod_flags & MODFLG_AUTO_LOADED) == 0)
1464: continue;
1465:
1.37 ad 1466: if (uvmexp.free < uvmexp.freemin) {
1.26 ad 1467: module_thread_ticks = hz;
1.94 pgoyette 1468: } else if (module_autotime == 0 ||
1469: mod->mod_autotime == 0) {
1.26 ad 1470: continue;
1471: } else if (time_second < mod->mod_autotime) {
1472: module_thread_ticks = hz;
1473: continue;
1.37 ad 1474: } else {
1.26 ad 1475: mod->mod_autotime = 0;
1.37 ad 1476: }
1.83 jmcneill 1477:
1.28 ad 1478: /*
1479: * If this module wants to avoid autounload then
1480: * skip it. Some modules can ping-pong in and out
1481: * because their use is transient but often.
1482: * Example: exec_script.
1483: */
1484: mi = mod->mod_info;
1485: error = (*mi->mi_modcmd)(MODULE_CMD_AUTOUNLOAD, NULL);
1486: if (error == 0 || error == ENOTTY) {
1.70 pgoyette 1487: (void)module_do_unload(mi->mi_name, false);
1.107 pgoyette 1488: } else
1489: module_print("module `%s' declined to be "
1490: "auto-unloaded error=%d", mi->mi_name,
1491: error);
1.26 ad 1492: }
1.72 pgoyette 1493: kernconfig_unlock();
1.26 ad 1494:
1495: mutex_enter(&module_thread_lock);
1496: (void)cv_timedwait(&module_thread_cv, &module_thread_lock,
1497: module_thread_ticks);
1498: module_thread_ticks = 0;
1499: mutex_exit(&module_thread_lock);
1500: }
1501: }
1502:
1503: /*
1504: * module_thread:
1505: *
1506: * Kick the module thread into action, perhaps because the
1507: * system is low on memory.
1508: */
1509: void
1510: module_thread_kick(void)
1511: {
1512:
1513: mutex_enter(&module_thread_lock);
1514: module_thread_ticks = hz;
1515: cv_broadcast(&module_thread_cv);
1516: mutex_exit(&module_thread_lock);
1517: }
1.30 ad 1518:
1519: #ifdef DDB
1520: /*
1521: * module_whatis:
1522: *
1523: * Helper routine for DDB.
1524: */
1525: void
1526: module_whatis(uintptr_t addr, void (*pr)(const char *, ...))
1527: {
1528: module_t *mod;
1529: size_t msize;
1530: vaddr_t maddr;
1531:
1532: TAILQ_FOREACH(mod, &module_list, mod_chain) {
1.43 ad 1533: if (mod->mod_kobj == NULL) {
1534: continue;
1535: }
1.49 dyoung 1536: if (kobj_stat(mod->mod_kobj, &maddr, &msize) != 0)
1537: continue;
1.30 ad 1538: if (addr < maddr || addr >= maddr + msize) {
1539: continue;
1540: }
1541: (*pr)("%p is %p+%zu, in kernel module `%s'\n",
1542: (void *)addr, (void *)maddr,
1543: (size_t)(addr - maddr), mod->mod_info->mi_name);
1544: }
1545: }
1546:
1547: /*
1548: * module_print_list:
1549: *
1550: * Helper routine for DDB.
1551: */
1552: void
1553: module_print_list(void (*pr)(const char *, ...))
1554: {
1555: const char *src;
1556: module_t *mod;
1557: size_t msize;
1558: vaddr_t maddr;
1559:
1560: (*pr)("%16s %16s %8s %8s\n", "NAME", "TEXT/DATA", "SIZE", "SOURCE");
1561:
1562: TAILQ_FOREACH(mod, &module_list, mod_chain) {
1563: switch (mod->mod_source) {
1564: case MODULE_SOURCE_KERNEL:
1565: src = "builtin";
1566: break;
1567: case MODULE_SOURCE_FILESYS:
1568: src = "filesys";
1569: break;
1570: case MODULE_SOURCE_BOOT:
1571: src = "boot";
1572: break;
1573: default:
1574: src = "unknown";
1575: break;
1576: }
1.49 dyoung 1577: if (mod->mod_kobj == NULL) {
1.43 ad 1578: maddr = 0;
1579: msize = 0;
1.49 dyoung 1580: } else if (kobj_stat(mod->mod_kobj, &maddr, &msize) != 0)
1581: continue;
1.31 ad 1582: (*pr)("%16s %16lx %8ld %8s\n", mod->mod_info->mi_name,
1.30 ad 1583: (long)maddr, (long)msize, src);
1584: }
1585: }
1586: #endif /* DDB */
1.46 jnemeth 1587:
1.47 jnemeth 1588: static bool
1589: module_merge_dicts(prop_dictionary_t existing_dict,
1590: const prop_dictionary_t new_dict)
1591: {
1592: prop_dictionary_keysym_t props_keysym;
1593: prop_object_iterator_t props_iter;
1594: prop_object_t props_obj;
1595: const char *props_key;
1596: bool error;
1597:
1.52 jnemeth 1598: if (new_dict == NULL) { /* nothing to merge */
1599: return true;
1600: }
1601:
1.47 jnemeth 1602: error = false;
1603: props_iter = prop_dictionary_iterator(new_dict);
1604: if (props_iter == NULL) {
1605: return false;
1606: }
1607:
1608: while ((props_obj = prop_object_iterator_next(props_iter)) != NULL) {
1609: props_keysym = (prop_dictionary_keysym_t)props_obj;
1610: props_key = prop_dictionary_keysym_cstring_nocopy(props_keysym);
1611: props_obj = prop_dictionary_get_keysym(new_dict, props_keysym);
1612: if ((props_obj == NULL) || !prop_dictionary_set(existing_dict,
1613: props_key, props_obj)) {
1614: error = true;
1615: goto out;
1616: }
1617: }
1618: error = false;
1619:
1620: out:
1621: prop_object_iterator_release(props_iter);
1622:
1623: return !error;
1624: }
1.131 ! chs 1625:
! 1626: /*
! 1627: * module_specific_key_create:
! 1628: *
! 1629: * Create a key for subsystem module-specific data.
! 1630: */
! 1631: specificdata_key_t
! 1632: module_specific_key_create(specificdata_key_t *keyp, specificdata_dtor_t dtor)
! 1633: {
! 1634:
! 1635: return specificdata_key_create(module_specificdata_domain, keyp, dtor);
! 1636: }
! 1637:
! 1638: /*
! 1639: * module_specific_key_delete:
! 1640: *
! 1641: * Delete a key for subsystem module-specific data.
! 1642: */
! 1643: void
! 1644: module_specific_key_delete(specificdata_key_t key)
! 1645: {
! 1646:
! 1647: return specificdata_key_delete(module_specificdata_domain, key);
! 1648: }
! 1649:
! 1650: /*
! 1651: * module_getspecific:
! 1652: *
! 1653: * Return module-specific data corresponding to the specified key.
! 1654: */
! 1655: void *
! 1656: module_getspecific(module_t *mod, specificdata_key_t key)
! 1657: {
! 1658:
! 1659: return specificdata_getspecific(module_specificdata_domain,
! 1660: &mod->mod_sdref, key);
! 1661: }
! 1662:
! 1663: /*
! 1664: * module_setspecific:
! 1665: *
! 1666: * Set module-specific data corresponding to the specified key.
! 1667: */
! 1668: void
! 1669: module_setspecific(module_t *mod, specificdata_key_t key, void *data)
! 1670: {
! 1671:
! 1672: specificdata_setspecific(module_specificdata_domain,
! 1673: &mod->mod_sdref, key, data);
! 1674: }
! 1675:
! 1676: /*
! 1677: * module_register_callbacks:
! 1678: *
! 1679: * Register a new set of callbacks to be called on module load/unload.
! 1680: * Call the load callback on each existing module.
! 1681: * Return an opaque handle for unregistering these later.
! 1682: */
! 1683: void *
! 1684: module_register_callbacks(void (*load)(struct module *),
! 1685: void (*unload)(struct module *))
! 1686: {
! 1687: struct module_callbacks *modcb;
! 1688: struct module *mod;
! 1689:
! 1690: modcb = kmem_alloc(sizeof(*modcb), KM_SLEEP);
! 1691: modcb->modcb_load = load;
! 1692: modcb->modcb_unload = unload;
! 1693:
! 1694: kernconfig_lock();
! 1695: TAILQ_INSERT_TAIL(&modcblist, modcb, modcb_list);
! 1696: TAILQ_FOREACH(mod, &module_list, mod_chain)
! 1697: load(mod);
! 1698: kernconfig_unlock();
! 1699:
! 1700: return modcb;
! 1701: }
! 1702:
! 1703: /*
! 1704: * module_unregister_callbacks:
! 1705: *
! 1706: * Unregister a previously-registered set of module load/unload callbacks.
! 1707: * Call the unload callback on each existing module.
! 1708: */
! 1709: void
! 1710: module_unregister_callbacks(void *opaque)
! 1711: {
! 1712: struct module_callbacks *modcb;
! 1713: struct module *mod;
! 1714:
! 1715: modcb = opaque;
! 1716: kernconfig_lock();
! 1717: TAILQ_FOREACH(mod, &module_list, mod_chain)
! 1718: modcb->modcb_unload(mod);
! 1719: TAILQ_REMOVE(&modcblist, modcb, modcb_list);
! 1720: kernconfig_unlock();
! 1721: kmem_free(modcb, sizeof(*modcb));
! 1722: }
! 1723:
! 1724: /*
! 1725: * module_callback_load:
! 1726: *
! 1727: * Helper routine: call all load callbacks on a module being loaded.
! 1728: */
! 1729: static void
! 1730: module_callback_load(struct module *mod)
! 1731: {
! 1732: struct module_callbacks *modcb;
! 1733:
! 1734: TAILQ_FOREACH(modcb, &modcblist, modcb_list) {
! 1735: modcb->modcb_load(mod);
! 1736: }
! 1737: }
! 1738:
! 1739: /*
! 1740: * module_callback_unload:
! 1741: *
! 1742: * Helper routine: call all unload callbacks on a module being unloaded.
! 1743: */
! 1744: static void
! 1745: module_callback_unload(struct module *mod)
! 1746: {
! 1747: struct module_callbacks *modcb;
! 1748:
! 1749: TAILQ_FOREACH(modcb, &modcblist, modcb_list) {
! 1750: modcb->modcb_unload(mod);
! 1751: }
! 1752: }
CVSweb <webmaster@jp.NetBSD.org>