Use kern_kldload() and kern_kldunload() to load and unload modules when
we intend for the user to be able to unload them later via kldunload(2) instead of calling linker_load_module() and then directly adjusting the ref count on the linker file structure. This makes the resulting consumer code simpler and cleaner and better hides the linker internals making it possible to sanely lock the linker.
This commit is contained in:
parent
b21c9288ce
commit
edd32c2da2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=159590
@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/linker.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/malloc.h>
|
||||
@ -108,7 +109,7 @@ struct vfsconf *
|
||||
vfs_byname_kld(const char *fstype, struct thread *td, int *error)
|
||||
{
|
||||
struct vfsconf *vfsp;
|
||||
linker_file_t lf;
|
||||
int fileid;
|
||||
|
||||
vfsp = vfs_byname(fstype);
|
||||
if (vfsp != NULL)
|
||||
@ -121,17 +122,14 @@ vfs_byname_kld(const char *fstype, struct thread *td, int *error)
|
||||
*error = securelevel_gt(td->td_ucred, 0);
|
||||
if (*error)
|
||||
return (NULL);
|
||||
*error = linker_load_module(NULL, fstype, NULL, NULL, &lf);
|
||||
if (lf == NULL)
|
||||
*error = ENODEV;
|
||||
*error = kern_kldload(td, fstype, &fileid);
|
||||
if (*error)
|
||||
return (NULL);
|
||||
lf->userrefs++;
|
||||
|
||||
/* Look up again to see if the VFS was loaded. */
|
||||
vfsp = vfs_byname(fstype);
|
||||
if (vfsp == NULL) {
|
||||
lf->userrefs--;
|
||||
linker_file_unload(lf, LINKER_UNLOAD_FORCE);
|
||||
(void)kern_kldunload(td, fileid, LINKER_UNLOAD_FORCE);
|
||||
*error = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -310,14 +310,9 @@ ieee80211_notify_michael_failure(struct ieee80211com *ic,
|
||||
void
|
||||
ieee80211_load_module(const char *modname)
|
||||
{
|
||||
#ifdef notyet
|
||||
struct thread *td = curthread;
|
||||
|
||||
if (suser(td) == 0 && securelevel_gt(td->td_ucred, 0) == 0) {
|
||||
mtx_lock(&Giant);
|
||||
(void) linker_load_module(modname, NULL, NULL, NULL, NULL);
|
||||
mtx_unlock(&Giant);
|
||||
}
|
||||
#ifdef notyet
|
||||
(void)kern_kldload(curthread, modname, NULL);
|
||||
#else
|
||||
printf("%s: load the %s module by hand for now.\n", __func__, modname);
|
||||
#endif
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#ifdef NOTYET
|
||||
@ -271,24 +272,22 @@ ngc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
|
||||
|
||||
if ((type = ng_findtype(mkp->type)) == NULL) {
|
||||
char filename[NG_TYPESIZ + 3];
|
||||
linker_file_t lf;
|
||||
int fileid;
|
||||
|
||||
/* Not found, try to load it as a loadable module. */
|
||||
snprintf(filename, sizeof(filename), "ng_%s",
|
||||
mkp->type);
|
||||
mtx_lock(&Giant);
|
||||
error = linker_load_module(NULL, filename, NULL, NULL,
|
||||
&lf);
|
||||
mtx_unlock(&Giant);
|
||||
error = kern_kldload(curthread, filename, &fileid);
|
||||
if (error != 0) {
|
||||
FREE(msg, M_NETGRAPH_MSG);
|
||||
goto release;
|
||||
}
|
||||
lf->userrefs++;
|
||||
|
||||
/* See if type has been loaded successfully. */
|
||||
if ((type = ng_findtype(mkp->type)) == NULL) {
|
||||
FREE(msg, M_NETGRAPH_MSG);
|
||||
(void)kern_kldunload(curthread, fileid,
|
||||
LINKER_UNLOAD_NORMAL);
|
||||
error = ENXIO;
|
||||
goto release;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user