mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
Drop the global kernel linker lock while executing the sysinit's for a
freshly-loaded kernel module. To avoid various unload races, hide linker files whose sysinit's are being run from userland so that they can't be kldunloaded until after all the sysinit's have finished. Tested by: gallatin
This commit is contained in:
parent
0024ec11a6
commit
498eccc919
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=166921
@ -403,8 +403,10 @@ linker_load_file(const char *filename, linker_file_t *result)
|
||||
linker_file_unload(lf, LINKER_UNLOAD_FORCE);
|
||||
return (error);
|
||||
}
|
||||
KLD_UNLOCK();
|
||||
linker_file_register_sysctls(lf);
|
||||
linker_file_sysinit(lf);
|
||||
KLD_LOCK();
|
||||
lf->flags |= LINKER_FILE_LINKED;
|
||||
*result = lf;
|
||||
return (0);
|
||||
@ -502,7 +504,7 @@ linker_find_file_by_id(int fileid)
|
||||
|
||||
KLD_LOCK_ASSERT();
|
||||
TAILQ_FOREACH(lf, &linker_files, link)
|
||||
if (lf->id == fileid)
|
||||
if (lf->id == fileid && lf->flags & LINKER_FILE_LINKED)
|
||||
break;
|
||||
return (lf);
|
||||
}
|
||||
@ -1033,21 +1035,25 @@ kldnext(struct thread *td, struct kldnext_args *uap)
|
||||
#endif
|
||||
|
||||
KLD_LOCK();
|
||||
if (uap->fileid == 0) {
|
||||
if (TAILQ_FIRST(&linker_files))
|
||||
td->td_retval[0] = TAILQ_FIRST(&linker_files)->id;
|
||||
else
|
||||
td->td_retval[0] = 0;
|
||||
goto out;
|
||||
if (uap->fileid == 0)
|
||||
lf = TAILQ_FIRST(&linker_files);
|
||||
else {
|
||||
lf = linker_find_file_by_id(uap->fileid);
|
||||
if (lf == NULL) {
|
||||
error = ENOENT;
|
||||
goto out;
|
||||
}
|
||||
lf = TAILQ_NEXT(lf, link);
|
||||
}
|
||||
lf = linker_find_file_by_id(uap->fileid);
|
||||
if (lf) {
|
||||
if (TAILQ_NEXT(lf, link))
|
||||
td->td_retval[0] = TAILQ_NEXT(lf, link)->id;
|
||||
else
|
||||
td->td_retval[0] = 0;
|
||||
} else
|
||||
error = ENOENT;
|
||||
|
||||
/* Skip partially loaded files. */
|
||||
while (lf != NULL && !(lf->flags & LINKER_FILE_LINKED))
|
||||
lf = TAILQ_NEXT(lf, link);
|
||||
|
||||
if (lf)
|
||||
td->td_retval[0] = lf->id;
|
||||
else
|
||||
td->td_retval[0] = 0;
|
||||
out:
|
||||
KLD_UNLOCK();
|
||||
return (error);
|
||||
|
Loading…
Reference in New Issue
Block a user