DF-2936 / boom.c
/* * DF-2936 — module lifecycle desync: module_register_init destroys the * module registry entry when MOD_LOAD fails, but the containing KLD load * is still reported as successful and the file stays resident. * * Expected (buggy) behavior when kldload(2)'ed as root: * 1. kldload returns SUCCESS (file id) even though MOD_LOAD failed. * 2. "boom MOD_LOAD -> deliberately failing" then * "boom MOD_UNLOAD dispatched" appear at LOAD time. * 3. The module is GONE from the module registry (kldstat -m boom: * no such module) while the file boom.ko remains loaded. * 4. kldunload boom succeeds WITHOUT dispatching MOD_UNLOAD again * (module already destroyed), but DOES run the module's SYSUNINIT * for the long-dead module. */ #include <sys/param.h> #include <sys/kernel.h> #include <sys/module.h> #include <sys/systm.h> static int boom_modevent(module_t mod, int what, void *arg) { switch (what) { case MOD_LOAD: kprintf("DF2936: boom MOD_LOAD -> deliberately failing (ret 5)\n"); return (5); /* deliberate MOD_LOAD failure */ case MOD_UNLOAD: kprintf("DF2936: boom MOD_UNLOAD dispatched\n"); return (0); case MOD_SHUTDOWN: return (0); default: return (EOPNOTSUPP); } } static moduledata_t boom_mod = { "boom", boom_modevent, NULL }; DECLARE_MODULE(boom, boom_mod, SI_SUB_DRIVERS, SI_ORDER_ANY); /* * Runs at kldunload time (linker_file_sysuninit) — i.e. AFTER the module * was already unregistered and freed at load-failure time. */ static void boom_sysuninit(void *unused) { kprintf("DF2936: boom SYSUNINIT running (module destroyed at load time!)\n"); } SYSUNINIT(boom_sysuninit, SI_SUB_DRIVERS, SI_ORDER_ANY, boom_sysuninit, NULL); |