Date: Mon, 5 Nov 2001 11:18:39 -0800 From: Luigi Rizzo <rizzo@aciri.org> To: stable@freebsd.org Subject: For review: preventing panics when unloading compiled-in modules Message-ID: <20011105111839.A75789@iguana.aciri.org>
next in thread | raw e-mail | index | archive | help
[I am Bcc-ing some developers who have been involved with this code in the past, hoping that they know a bit more than I do] There have been a few PR in the past about the module handling code when some module is already statically compiled-in: basically, if you try to load the module, the loader seems to ignore the error, marks the module as dynamically loaded and this causes a panic at kldunload time. See PR kern/24392 and its Audit-Trail. I am not sure what is the appropriate fix, because there are too many indirections in the code to follow what is going on. However, the attached patch seems to do at least part of the job, i.e. it passes up the error from module_register(), so that at least the kernel does not panic at unload time. See below an example where ipfw was already compiled into the kernel (the lines marked XX are produced on the console by the kernel). # kldload /ipfw.ko XX module_register: module ipfw already exists! XX linker_file_sysinit "ipfw.ko" failed to register! 17 kldload: can't load /ipfw.ko: File exists # kldstat Id Refs Address Size Name 1 2 0xc0000000 40000000 kernel 2 1 0xc38aa000 8000 ipfw.ko # kldunload ipfw.ko XX linkerunload: attempt to unload file that was loaded by the kernel kldunload: can't unload file: Device busy Technically, after the load, "ipfw.ko" is not a separate module, so maybe one would like not to see it in the list. On the other hand, the functionality associated with the module is present, so this is not too bad... cheers luigi Index: kern_linker.c =================================================================== RCS file: /home/xorpc/u2/freebsd/src/sys/kern/kern_linker.c,v retrieving revision 1.41.2.2 diff -u -r1.41.2.2 kern_linker.c --- kern_linker.c 2000/07/16 13:13:32 1.41.2.2 +++ kern_linker.c 2001/11/05 18:48:30 @@ -88,7 +88,7 @@ return 0; } -static void +static int linker_file_sysinit(linker_file_t lf) { struct linker_set* sysinits; @@ -106,16 +106,18 @@ KLD_DPF(FILE, ("linker_file_sysinit: SYSINITs %p\n", sysinits)); if (!sysinits) - return; + return 0 ; /* XXX is this correct ? No sysinit ? */ /* HACK ALERT! */ for (sipp = (struct sysinit **)sysinits->ls_items; *sipp; sipp++) { if ((*sipp)->func == module_register_init) { moddata = (*sipp)->udata; error = module_register(moddata, lf); - if (error) + if (error) { printf("linker_file_sysinit \"%s\" failed to register! %d\n", lf->filename, error); + return error ; + } } } @@ -150,6 +152,7 @@ /* Call function */ (*((*sipp)->func))((*sipp)->udata); } + return 0 ; /* no errors */ } static void @@ -282,10 +285,9 @@ foundfile = 1; if (lf) { linker_file_register_sysctls(lf); - linker_file_sysinit(lf); + error = linker_file_sysinit(lf); *result = lf; - error = 0; goto out; } } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011105111839.A75789>