diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-12-09 14:19:03 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-01-10 09:53:34 +0100 |
commit | 75b706fde4cbf82bcd41a1cec319778aa0f8eb2d (patch) | |
tree | ea39a351a1f6337b5a5dd6036314693adef5ffe6 /freebsd/sys/kern/kern_linker.c | |
parent | VMSTAT(8): Port to RTEMS (diff) | |
download | rtems-libbsd-75b706fde4cbf82bcd41a1cec319778aa0f8eb2d.tar.bz2 |
Update to FreeBSD head 2016-12-10
Git mirror commit 80c55f08a05ab3b26a73b226ccb56adc3122a55c.
Diffstat (limited to 'freebsd/sys/kern/kern_linker.c')
-rw-r--r-- | freebsd/sys/kern/kern_linker.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/freebsd/sys/kern/kern_linker.c b/freebsd/sys/kern/kern_linker.c index a115aa96..82a33023 100644 --- a/freebsd/sys/kern/kern_linker.c +++ b/freebsd/sys/kern/kern_linker.c @@ -1615,7 +1615,6 @@ restart: if (error) panic("cannot add dependency"); } - lf->userrefs++; /* so we can (try to) kldunload it */ error = linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop, NULL); if (!error) { @@ -1653,6 +1652,8 @@ restart: goto fail; } linker_file_register_modules(lf); + if (!TAILQ_EMPTY(&lf->modules)) + lf->flags |= LINKER_FILE_MODULES; if (linker_file_lookup_set(lf, "sysinit_set", &si_start, &si_stop, NULL) == 0) sysinit_add(si_start, si_stop); @@ -1670,6 +1671,41 @@ fail: SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0); /* + * Handle preload files that failed to load any modules. + */ +static void +linker_preload_finish(void *arg) +{ + linker_file_t lf, nlf; + + sx_xlock(&kld_sx); + TAILQ_FOREACH_SAFE(lf, &linker_files, link, nlf) { + /* + * If all of the modules in this file failed to load, unload + * the file and return an error of ENOEXEC. (Parity with + * linker_load_file.) + */ + if ((lf->flags & LINKER_FILE_MODULES) != 0 && + TAILQ_EMPTY(&lf->modules)) { + linker_file_unload(lf, LINKER_UNLOAD_FORCE); + continue; + } + + lf->flags &= ~LINKER_FILE_MODULES; + lf->userrefs++; /* so we can (try to) kldunload it */ + } + sx_xunlock(&kld_sx); +} + +/* + * Attempt to run after all DECLARE_MODULE SYSINITs. Unfortunately they can be + * scheduled at any subsystem and order, so run this as late as possible. init + * becomes runnable in SI_SUB_KTHREAD_INIT, so go slightly before that. + */ +SYSINIT(preload_finish, SI_SUB_KTHREAD_INIT - 100, SI_ORDER_MIDDLE, + linker_preload_finish, 0); + +/* * Search for a not-loaded module by name. * * Modules may be found in the following locations: |