cvs commit: src/sys/dev/md md.c

Peter Edwards peadar at freebsd.org
Sat Aug 28 14:13:09 PDT 2004


Ken Smith wrote:

>On Sat, Aug 28, 2004 at 07:54:50PM +0000, Ken Smith wrote:
>  
>
>>kensmith    2004-08-28 19:54:50 UTC
>>
>>  FreeBSD src repository
>>
>>  Modified files:        (Branch: RELENG_5)
>>    sys/dev/md           md.c 
>>  Log:
>>  Back out the MFC done as rev 1.127.2.1.  It seems to fix the problem of
>>  mdconfig returning before the device's name appears in /dev but it seems
>>  to cause a worse problem.  When booting the installation media (CD or
>>  boot floppies) the system hangs after the device probes, at the point
>>  it should be trying to mount a MD-based filesystem as its root filesystem.
>>  Backing out this patch solves that problem, allowing it to proceed to
>>  the sysinstall menu.
>>  
>>  Approved by:    re (rwatson)
>>  
>>  Revision   Changes    Path
>>  1.127.2.2  +0 -1      src/sys/dev/md/md.c
>>    
>>
>
>At this point I don't intend to touch HEAD.  I still would like to
>see the original problem fixed and I'm guessing that the original
>change is on the right pathway to fixing it.  Just a little more
>care or something?
>
>Colin/Poul-Henning, do you mind checking into why the call to
>g_waitidle() seems to cause problems using an md device as a root
>filesystem during install?
>
>Thanks...
>
>  
>
I stumbled on this some time ago. The problem, I think, is that the GEOM 
event thread, although created by g_init() , isn't making progress 
during the boot process (might be a bit early for the scheduler, I 
suppose).  So, you can queue events to it, but can't expect a response 
that early on.

I originally had the problem because /dev/mdctl gets created by the 
g_md_init() routine, which is also called via the event thread: the 
kldload() from mdconfig can return without /dev/mdctl actually being 
created; I suppose this is a little different from the tasting problem 
fixed by md.c 1.128. The fix for my particular problem was to get GEOM 
to wait for the event to be acknowledged before returning from the 
MOD_LOAD modevent. Working-but-evil hack attached.
-------------- next part --------------
Index: geom/geom_int.h
===================================================================
RCS file: /usr/cvs/FreeBSD-CVS/src/sys/geom/geom_int.h,v
retrieving revision 1.28
diff -u -r1.28 geom_int.h
--- geom/geom_int.h	8 Jul 2004 16:17:14 -0000	1.28
+++ geom/geom_int.h	17 Jul 2004 12:37:28 -0000
@@ -83,6 +83,7 @@
 /* geom_kern.c / geom_kernsim.c */
 void g_init(void);
 extern int g_shutdown;
+extern int g_boot;
 
 /* geom_ctl.c */
 void g_ctl_init(void);
Index: geom/geom_kern.c
===================================================================
RCS file: /usr/cvs/FreeBSD-CVS/src/sys/geom/geom_kern.c,v
retrieving revision 1.34
diff -u -r1.34 geom_kern.c
--- geom/geom_kern.c	10 Feb 2004 10:54:19 -0000	1.34
+++ geom/geom_kern.c	12 May 2004 23:24:22 -0000
@@ -61,6 +61,7 @@
 int g_debugflags;
 int g_collectstats = 1;
 int g_shutdown;
+int g_boot = 1;
 
 /*
  * G_UP and G_DOWN are the two threads which push I/O through the
@@ -130,6 +131,7 @@
 
 	mtx_assert(&Giant, MA_NOTOWNED);
 	tp->td_base_pri = PRIBIO;
+	g_boot = 0;
 	for(;;) {
 		g_run_events();
 		tsleep(&g_wait_event, PRIBIO, "-", hz/10);
Index: geom/geom_subr.c
===================================================================
RCS file: /usr/cvs/FreeBSD-CVS/src/sys/geom/geom_subr.c,v
retrieving revision 1.81
diff -u -r1.81 geom_subr.c
--- geom/geom_subr.c	8 Aug 2004 08:34:46 -0000	1.81
+++ geom/geom_subr.c	17 Aug 2004 23:05:05 -0000
@@ -60,6 +60,7 @@
 struct g_hh00 {
 	struct g_class	*mp;
 	int		error;
+	int		boot;
 };
 
 /*
@@ -81,7 +82,8 @@
 
 	hh = arg;
 	mp = hh->mp;
-	g_free(hh);
+	if (hh->boot)
+		g_free(hh);
 	g_trace(G_T_TOPOLOGY, "g_load_class(%s)", mp->name);
 	KASSERT(mp->name != NULL && *mp->name != '\0',
 	    ("GEOM class has no name"));
@@ -195,8 +197,27 @@
 	switch (type) {
 	case MOD_LOAD:
 		g_trace(G_T_TOPOLOGY, "g_modevent(%s, LOAD)", hh->mp->name);
-		g_post_event(g_load_class, hh, M_WAITOK, NULL);
-		error = 0;
+		hh->boot = g_boot;
+		if (hh->boot) {
+			/*
+			 * Before GEOM is fully up, we can't rely on
+			 * the event thread to be alive, and need to
+			 * avoid deadlock.
+			 */
+			g_post_event(g_load_class, hh, M_WAITOK, NULL);
+			error = 0;
+		} else {
+			/*
+			 * Once booted, its best to ensure that a
+			 * userland return from kldload(2) means that
+			 * the module is actually loaded.
+			 */
+			error = g_waitfor_event(g_load_class, hh, M_WAITOK,
+			    NULL);
+			if (error == 0)
+				error = hh->error;
+			g_free(hh);
+		}
 		break;
 	case MOD_UNLOAD:
 		g_trace(G_T_TOPOLOGY, "g_modevent(%s, UNLOAD)", hh->mp->name);


More information about the cvs-all mailing list