In article <20190927125444.gb12...@pony.stderr.spb.ru>, Valery Ushakov <u...@stderr.spb.ru> wrote: > >May be we should take a look at how SNMP did tables in MIB, b/c we are >trying to create just such a table indexed by module name.
I think it is simpler than that. > >Also, I'm not that sure about autoload of compat stuff especially >since iirc it currently implies auto-unload too. I vaguely remember >when I was debugging something in sh3 kobj_machdep.c I had some >printfs there that made the autoloads visibile and (iirc) each vi >invocation would trigger an autoload of compat ioctl code (which >wouldn't recognize the ioctl, and that would be auto-unloaded a few >seconds later). > >-uwe Here's what I've implemented: kern.module.noautoload="compat_linux* compat_[0-4]?" This disables autoload for all compat_linux modules as well as compat_netbsd < NetBSD-5.0 Comments? christos Index: kern_exec.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_exec.c,v retrieving revision 1.481 diff -u -u -r1.481 kern_exec.c --- kern_exec.c 17 Sep 2019 15:19:27 -0000 1.481 +++ kern_exec.c 28 Sep 2019 01:27:00 -0000 @@ -626,6 +626,8 @@ "exec_ecoff", "compat_aoutm68k", "compat_netbsd32", + "compat_linux", + "compat_linux32", "compat_sunos", "compat_sunos32", "compat_ultrix", Index: kern_module.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_module.c,v retrieving revision 1.138 diff -u -u -r1.138 kern_module.c --- kern_module.c 8 Aug 2019 18:08:41 -0000 1.138 +++ kern_module.c 28 Sep 2019 01:27:00 -0000 @@ -53,10 +53,16 @@ #include <sys/module.h> #include <sys/kthread.h> #include <sys/sysctl.h> +#include <sys/queue.h> #include <sys/lock.h> #include <uvm/uvm_extern.h> +#ifndef MODULE_NOAUTOLOAD +// Disable compat_linux and compat_linux32 by default for now +#define MODULE_NOAUTOLOAD "compat_linux*" +#endif + struct vm_map *module_map; const char *module_machine; char module_base[MODULE_BASE_SIZE]; @@ -93,6 +99,7 @@ u_int module_gen = 1; static kcondvar_t module_thread_cv; static kmutex_t module_thread_lock; +static kmutex_t module_noautoload_lock; static int module_thread_ticks; int (*module_load_vfs_vec)(const char *, int, bool, module_t *, prop_dictionary_t *) = (void *)eopnotsupp; @@ -120,6 +127,8 @@ static void module_enqueue(module_t *); static bool module_merge_dicts(prop_dictionary_t, const prop_dictionary_t); +static bool module_allow_autoload(const char *); +static void module_noautoload_update(const char *); static void sysctl_module_setup(void); static int sysctl_module_autotime(SYSCTLFN_PROTO); @@ -412,6 +421,7 @@ } cv_init(&module_thread_cv, "mod_unld"); mutex_init(&module_thread_lock, MUTEX_DEFAULT, IPL_NONE); + mutex_init(&module_noautoload_lock, MUTEX_DEFAULT, IPL_NONE); TAILQ_INIT(&modcblist); #ifdef MODULAR /* XXX */ @@ -444,6 +454,8 @@ module_netbsd = module_newmodule(MODULE_SOURCE_KERNEL); module_netbsd->mod_refcnt = 1; module_netbsd->mod_info = &module_netbsd_modinfo; + + module_noautoload_update(MODULE_NOAUTOLOAD); } /* @@ -503,6 +515,100 @@ return (0); } +struct noautoload { + const char *name; + SLIST_ENTRY(noautoload) next; +}; + +static SLIST_HEAD(, noautoload) noautoload_list = + SLIST_HEAD_INITIALIZER(noautoload_list); + +static char noautoload_buf[1024]; +static char noautoload_nbuf[sizeof(noautoload_buf)]; + +static void +module_noautoload_update(const char *cbuf) +{ + static const char SEP[] = " \t\n,"; + struct noautoload *e, *te; + char buf[sizeof(noautoload_buf)]; + + strlcpy(buf, cbuf, sizeof(buf)); + + mutex_enter(&module_noautoload_lock); + + SLIST_FOREACH_SAFE(e, &noautoload_list, next, te) { + SLIST_REMOVE(&noautoload_list, e, noautoload, next); + kmem_free(e, sizeof(*e)); + } + + noautoload_nbuf[0] = noautoload_buf[0] = '\0'; + + size_t pos = 0; + char *p, *str = buf; + + while ((p = strsep(&str, SEP)) != NULL) { + size_t len = strlen(p); + if (len == 0) + break; + e = kmem_alloc(sizeof(*e), KM_SLEEP); + e->name = noautoload_nbuf + pos; + SLIST_INSERT_HEAD(&noautoload_list, e, next); + + memcpy(noautoload_buf + pos, p, len); + memcpy(noautoload_nbuf + pos, p, len); + pos += len; + noautoload_buf[pos] = ' '; + noautoload_nbuf[pos] = '\0'; + pos++; + } + + if (pos) + noautoload_buf[pos - 1] = '\0'; /* space to NUL */ + + mutex_exit(&module_noautoload_lock); +} + +static int +sysctl_module_noautoload(SYSCTLFN_ARGS) +{ + struct sysctlnode node; + int error; + char newbuf[sizeof(noautoload_buf)]; + + strlcpy(newbuf, noautoload_buf, sizeof(newbuf)); + + node = *rnode; + node.sysctl_data = newbuf; + node.sysctl_size = sizeof(noautoload_buf); + error = sysctl_lookup(SYSCTLFN_CALL(&node)); + if (error || newp == NULL || strcmp(newbuf, noautoload_buf) == 0) + return error; + + module_noautoload_update(newbuf); + + return 0; +} + + +static bool +module_allow_autoload(const char *name) +{ + struct noautoload *e; + + mutex_enter(&module_noautoload_lock); + SLIST_FOREACH(e, &noautoload_list, next) { + if (pmatch(name, e->name, NULL) > 0) { + mutex_exit(&module_noautoload_lock); + module_print("module `%s' matched `%s'" + " and will not autoload", name, e->name); + return false; + } + } + mutex_exit(&module_noautoload_lock); + return true; +} + static void sysctl_module_setup(void) { @@ -542,6 +648,12 @@ SYSCTL_DESCR("Auto-unload delay"), sysctl_module_autotime, 0, &module_autotime, 0, CTL_CREATE, CTL_EOL); + sysctl_createv(&module_sysctllog, 0, &node, NULL, + CTLFLAG_PERMANENT | CTLFLAG_READWRITE, + CTLTYPE_STRING, "noautoload", + SYSCTL_DESCR("List of module patterns not to be autoloaded"), + sysctl_module_noautoload, 0, NULL, sizeof(noautoload_buf), + CTL_CREATE, CTL_EOL); } /* @@ -677,6 +789,9 @@ { int error; + if (!module_allow_autoload(filename)) + return EACCES; + kernconfig_lock(); /* Nothing if the user has disabled it. */