Skip site navigation (1)Skip section navigation (2)
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>