Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_linker.c
Show First 20 Lines • Show All 282 Lines • ▼ Show 20 Lines | for (sipp = start; sipp < stop; sipp++) { | ||||
/* Call function */ | /* Call function */ | ||||
(*((*sipp)->func)) ((*sipp)->udata); | (*((*sipp)->func)) ((*sipp)->udata); | ||||
} | } | ||||
mtx_unlock(&Giant); | mtx_unlock(&Giant); | ||||
sx_xlock(&kld_sx); | sx_xlock(&kld_sx); | ||||
} | } | ||||
static void | static void | ||||
linker_file_register_sysctls(linker_file_t lf) | linker_file_register_sysctls(linker_file_t lf, bool enable) | ||||
{ | { | ||||
struct sysctl_oid **start, **stop, **oidp; | struct sysctl_oid **start, **stop, **oidp; | ||||
KLD_DPF(FILE, | KLD_DPF(FILE, | ||||
("linker_file_register_sysctls: registering SYSCTLs for %s\n", | ("linker_file_register_sysctls: registering SYSCTLs for %s\n", | ||||
lf->filename)); | lf->filename)); | ||||
sx_assert(&kld_sx, SA_XLOCKED); | sx_assert(&kld_sx, SA_XLOCKED); | ||||
if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0) | if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0) | ||||
return; | return; | ||||
sx_xunlock(&kld_sx); | sx_xunlock(&kld_sx); | ||||
sysctl_wlock(); | sysctl_wlock(); | ||||
for (oidp = start; oidp < stop; oidp++) | for (oidp = start; oidp < stop; oidp++) { | ||||
if (enable) | |||||
sysctl_register_oid(*oidp); | sysctl_register_oid(*oidp); | ||||
else | |||||
sysctl_register_disabled_oid(*oidp); | |||||
} | |||||
sysctl_wunlock(); | sysctl_wunlock(); | ||||
sx_xlock(&kld_sx); | sx_xlock(&kld_sx); | ||||
} | } | ||||
static void | static void | ||||
linker_file_enable_sysctls(linker_file_t lf) | |||||
{ | |||||
struct sysctl_oid **start, **stop, **oidp; | |||||
KLD_DPF(FILE, | |||||
("linker_file_enable_sysctls: enable SYSCTLs for %s\n", | |||||
lf->filename)); | |||||
sx_assert(&kld_sx, SA_XLOCKED); | |||||
if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0) | |||||
return; | |||||
sx_xunlock(&kld_sx); | |||||
sysctl_wlock(); | |||||
for (oidp = start; oidp < stop; oidp++) | |||||
sysctl_enable_oid(*oidp); | |||||
sysctl_wunlock(); | |||||
sx_xlock(&kld_sx); | |||||
} | |||||
static void | |||||
linker_file_unregister_sysctls(linker_file_t lf) | linker_file_unregister_sysctls(linker_file_t lf) | ||||
{ | { | ||||
struct sysctl_oid **start, **stop, **oidp; | struct sysctl_oid **start, **stop, **oidp; | ||||
KLD_DPF(FILE, ("linker_file_unregister_sysctls: unregistering SYSCTLs" | KLD_DPF(FILE, ("linker_file_unregister_sysctls: unregistering SYSCTLs" | ||||
" for %s\n", lf->filename)); | " for %s\n", lf->filename)); | ||||
sx_assert(&kld_sx, SA_XLOCKED); | sx_assert(&kld_sx, SA_XLOCKED); | ||||
▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | if (error != ENOENT) | ||||
foundfile = 1; | foundfile = 1; | ||||
if (lf) { | if (lf) { | ||||
error = linker_file_register_modules(lf); | error = linker_file_register_modules(lf); | ||||
if (error == EEXIST) { | if (error == EEXIST) { | ||||
linker_file_unload(lf, LINKER_UNLOAD_FORCE); | linker_file_unload(lf, LINKER_UNLOAD_FORCE); | ||||
return (error); | return (error); | ||||
} | } | ||||
modules = !TAILQ_EMPTY(&lf->modules); | modules = !TAILQ_EMPTY(&lf->modules); | ||||
linker_file_register_sysctls(lf); | linker_file_register_sysctls(lf, false); | ||||
linker_file_sysinit(lf); | linker_file_sysinit(lf); | ||||
lf->flags |= LINKER_FILE_LINKED; | lf->flags |= LINKER_FILE_LINKED; | ||||
/* | /* | ||||
* If all of the modules in this file failed | * If all of the modules in this file failed | ||||
* to load, unload the file and return an | * to load, unload the file and return an | ||||
* error of ENOEXEC. | * error of ENOEXEC. | ||||
*/ | */ | ||||
if (modules && TAILQ_EMPTY(&lf->modules)) { | if (modules && TAILQ_EMPTY(&lf->modules)) { | ||||
linker_file_unload(lf, LINKER_UNLOAD_FORCE); | linker_file_unload(lf, LINKER_UNLOAD_FORCE); | ||||
return (ENOEXEC); | return (ENOEXEC); | ||||
} | } | ||||
linker_file_enable_sysctls(lf); | |||||
EVENTHANDLER_INVOKE(kld_load, lf); | EVENTHANDLER_INVOKE(kld_load, lf); | ||||
*result = lf; | *result = lf; | ||||
return (0); | return (0); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Less than ideal, but tells the user whether it failed to load or | * Less than ideal, but tells the user whether it failed to load or | ||||
* the module was not found. | * the module was not found. | ||||
▲ Show 20 Lines • Show All 233 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
/* | /* | ||||
* Don't try to run SYSUNINITs if we are unloaded due to a | * Don't try to run SYSUNINITs if we are unloaded due to a | ||||
* link error. | * link error. | ||||
*/ | */ | ||||
if (file->flags & LINKER_FILE_LINKED) { | if (file->flags & LINKER_FILE_LINKED) { | ||||
file->flags &= ~LINKER_FILE_LINKED; | file->flags &= ~LINKER_FILE_LINKED; | ||||
linker_file_sysuninit(file); | |||||
linker_file_unregister_sysctls(file); | linker_file_unregister_sysctls(file); | ||||
linker_file_sysuninit(file); | |||||
} | } | ||||
TAILQ_REMOVE(&linker_files, file, link); | TAILQ_REMOVE(&linker_files, file, link); | ||||
if (file->deps) { | if (file->deps) { | ||||
for (i = 0; i < file->ndeps; i++) | for (i = 0; i < file->ndeps; i++) | ||||
linker_file_unload(file->deps[i], flags); | linker_file_unload(file->deps[i], flags); | ||||
free(file->deps, M_LINKER); | free(file->deps, M_LINKER); | ||||
file->deps = NULL; | file->deps = NULL; | ||||
▲ Show 20 Lines • Show All 932 Lines • ▼ Show 20 Lines | if (error) { | ||||
goto fail; | goto fail; | ||||
} | } | ||||
linker_file_register_modules(lf); | linker_file_register_modules(lf); | ||||
if (!TAILQ_EMPTY(&lf->modules)) | if (!TAILQ_EMPTY(&lf->modules)) | ||||
lf->flags |= LINKER_FILE_MODULES; | lf->flags |= LINKER_FILE_MODULES; | ||||
if (linker_file_lookup_set(lf, "sysinit_set", &si_start, | if (linker_file_lookup_set(lf, "sysinit_set", &si_start, | ||||
&si_stop, NULL) == 0) | &si_stop, NULL) == 0) | ||||
sysinit_add(si_start, si_stop); | sysinit_add(si_start, si_stop); | ||||
linker_file_register_sysctls(lf); | linker_file_register_sysctls(lf, true); | ||||
lf->flags |= LINKER_FILE_LINKED; | lf->flags |= LINKER_FILE_LINKED; | ||||
continue; | continue; | ||||
fail: | fail: | ||||
TAILQ_REMOVE(&depended_files, lf, loaded); | TAILQ_REMOVE(&depended_files, lf, loaded); | ||||
linker_file_unload(lf, LINKER_UNLOAD_FORCE); | linker_file_unload(lf, LINKER_UNLOAD_FORCE); | ||||
} | } | ||||
sx_xunlock(&kld_sx); | sx_xunlock(&kld_sx); | ||||
/* woohoo! we made it! */ | /* woohoo! we made it! */ | ||||
▲ Show 20 Lines • Show All 553 Lines • Show Last 20 Lines |