33#include <sys/kernel.h>
35#include <sys/eventhandler.h>
36#include <sys/malloc.h>
37#include <sys/sysproto.h>
38#include <sys/sysent.h>
42#include <sys/reboot.h>
44#include <sys/module.h>
45#include <sys/linker.h>
52 struct linker_file *file;
56 modeventhand_t handler;
61#define MOD_EVENT(mod, type) (mod)->handler((mod), (type), (mod)->arg)
69modevent_nop(module_t mod,
int what,
void *arg)
86 sx_init(&modules_sx,
"module subsystem sx lock");
89 SHUTDOWN_PRI_DEFAULT);
103 TAILQ_FOREACH_REVERSE(mod, &modules, modulelist, link)
112 const moduledata_t *
data = (
const moduledata_t *)arg;
120 panic(
"module_register_init: module named %s not found\n",
129 printf(
"module_register_init: MOD_LOAD (%s, %p, %p) error"
143 TAILQ_REMOVE(&mod->file->modules, mod, flink);
144 TAILQ_INSERT_HEAD(&mod->file->modules, mod, flink);
159 if (newmod != NULL) {
161 printf(
"%s: cannot register %s from %s; already loaded from %s\n",
162 __func__,
data->name, container->filename, newmod->file->filename);
165 namelen = strlen(
data->name) + 1;
166 newmod =
malloc(
sizeof(
struct module) + namelen, M_MODULE, M_WAITOK);
168 newmod->id = nextid++;
169 newmod->name = (
char *)(newmod + 1);
170 strcpy(newmod->name,
data->name);
171 newmod->handler =
data->evhand ?
data->evhand : modevent_nop;
172 newmod->arg =
data->priv;
173 bzero(&newmod->data,
sizeof(newmod->data));
174 TAILQ_INSERT_TAIL(&modules, newmod, link);
177 TAILQ_INSERT_TAIL(&container->modules, newmod, flink);
178 newmod->file = container;
189 MOD_DPF(REFS, (
"module_reference: before, refs=%d\n", mod->refs));
200 panic(
"module_release: bad reference count");
202 MOD_DPF(REFS, (
"module_release: before, refs=%d\n", mod->refs));
205 if (mod->refs == 0) {
206 TAILQ_REMOVE(&modules, mod, link);
208 TAILQ_REMOVE(&mod->file->modules, mod, flink);
221 TAILQ_FOREACH(mod, &modules, link) {
222 err = strcmp(mod->name,
name);
236 TAILQ_FOREACH(mod, &modules, link)
237 if (mod->id == modid)
250 if (error == EOPNOTSUPP || error == EINVAL)
279 return (TAILQ_NEXT(mod, flink));
314 td->td_retval[0] = -1;
317 if (uap->modid == 0) {
318 mod = TAILQ_FIRST(&modules);
320 td->td_retval[0] = mod->id;
330 if (TAILQ_NEXT(mod, link))
331 td->td_retval[0] = TAILQ_NEXT(mod, link)->id;
333 td->td_retval[0] = 0;
345 td->td_retval[0] = -1;
353 if (TAILQ_NEXT(mod, flink))
354 td->td_retval[0] = TAILQ_NEXT(mod, flink)->id;
356 td->td_retval[0] = 0;
383 int id, namelen, refs, version;
384 struct module_stat *stat;
405 if ((error = copyin(&stat->version, &
version,
sizeof(
version))) != 0)
409 if (!is_v1v2 &&
version !=
sizeof(
struct module_stat))
411 namelen = strlen(mod->name) + 1;
412 if (is_v1v2 && namelen > MAXMODNAMEV1V2)
413 namelen = MAXMODNAMEV1V2;
414 else if (namelen > MAXMODNAMEV3)
415 namelen = MAXMODNAMEV3;
416 if ((error = copyout(
name, &stat->name[0], namelen)) != 0)
422 if ((error = copyout(&
refs, &stat_v2->
refs,
sizeof(
int))) != 0)
424 if ((error = copyout(&
id, &stat_v2->
id,
sizeof(
int))) != 0)
427 if ((error = copyout(&
refs, &stat->refs,
sizeof(
int))) != 0)
429 if ((error = copyout(&
id, &stat->id,
sizeof(
int))) != 0)
437 if ((error = copyout(&
data, &stat_v2->
data,
440 }
else if (
version ==
sizeof(
struct module_stat)) {
441 if ((error = copyout(&
data, &stat->data,
445 td->td_retval[0] = 0;
453 char name[MAXMODNAMEV3];
456 if ((error = copyinstr(uap->name,
name,
sizeof name, 0)) != 0)
471#ifdef COMPAT_FREEBSD32
472#include <sys/mount.h>
473#include <sys/socket.h>
474#include <compat/freebsd32/freebsd32_util.h>
475#include <compat/freebsd32/freebsd32.h>
476#include <compat/freebsd32/freebsd32_proto.h>
478typedef union modspecific32 {
485struct module_stat32_v2 {
487 char name[MAXMODNAMEV1V2];
490 modspecific32_t
data;
493struct module_stat32 {
495 char name[MAXMODNAME];
498 modspecific32_t
data;
502freebsd32_modstat(
struct thread *td,
struct freebsd32_modstat_args *uap)
505 modspecific32_t data32;
507 int id, namelen, refs, version;
508 struct module_stat32 *stat32;
509 struct module_stat32_v2 *stat32_v2;
523 CP(mod->data, data32, intval);
524 CP(mod->data, data32, uintval);
525 CP(mod->data, data32, longval);
526 CP(mod->data, data32, ulongval);
530 if ((error = copyin(&stat32->version, &version,
sizeof(version))) != 0)
533 version ==
sizeof(
struct module_stat32_v2));
534 if (!is_v1v2 && version !=
sizeof(
struct module_stat32))
536 namelen = strlen(mod->name) + 1;
537 if (is_v1v2 && namelen > MAXMODNAMEV1V2)
538 namelen = MAXMODNAMEV1V2;
539 else if (namelen > MAXMODNAMEV3)
540 namelen = MAXMODNAMEV3;
541 if ((error = copyout(
name, &stat32->name[0], namelen)) != 0)
546 stat32_v2 = (
struct module_stat32_v2 *)stat32;
547 if ((error = copyout(&refs, &stat32_v2->refs,
sizeof(
int))) != 0)
549 if ((error = copyout(&
id, &stat32_v2->id,
sizeof(
int))) != 0)
552 if ((error = copyout(&refs, &stat32->refs,
sizeof(
int))) != 0)
554 if ((error = copyout(&
id, &stat32->id,
sizeof(
int))) != 0)
561 if (version ==
sizeof(
struct module_stat32_v2)) {
562 if ((error = copyout(&data32, &stat32_v2->data,
563 sizeof(data32))) != 0)
565 }
else if (version ==
sizeof(
struct module_stat32)) {
566 if ((error = copyout(&data32, &stat32->data,
567 sizeof(data32))) != 0)
570 td->td_retval[0] = 0;
void *() malloc(size_t size, struct malloc_type *mtp, int flags)
void free(void *addr, struct malloc_type *mtp)
int module_register(const moduledata_t *data, linker_file_t container)
MODULE_VERSION(kernel, __FreeBSD_version)
SYSINIT(module, SI_SUB_KLD, SI_ORDER_FIRST, module_init, NULL)
int sys_modnext(struct thread *td, struct modnext_args *uap)
void module_register_init(const void *arg)
int module_getid(module_t mod)
int module_quiesce(module_t mod)
void module_release(module_t mod)
#define MOD_EVENT(mod, type)
static MALLOC_DEFINE(M_MODULE, "module", "module data structures")
linker_file_t module_file(module_t mod)
static void module_shutdown(void *arg1, int arg2)
int sys_modfnext(struct thread *td, struct modfnext_args *uap)
module_t module_lookupbyname(const char *name)
module_t module_lookupbyid(int modid)
static void module_init(void *arg)
void module_reference(module_t mod)
static TAILQ_HEAD(modulelist, module)
int module_unload(module_t mod)
int sys_modstat(struct thread *td, struct modstat_args *uap)
int sys_modfind(struct thread *td, struct modfind_args *uap)
const char * module_getname(module_t mod)
void module_setspecific(module_t mod, modspecific_t *datap)
module_t module_getfnext(module_t mod)
struct mtx __exclusive_cache_line Giant
void panic(const char *fmt,...)
char name[MAXMODNAMEV1V2]
char name[MAXMODNAMEV1V2]
int printf(const char *fmt,...)