Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Mar 2012 07:26:17 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r233342 - head/sys/geom/part
Message-ID:  <201203230726.q2N7QH06062581@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Fri Mar 23 07:26:17 2012
New Revision: 233342
URL: http://svn.freebsd.org/changeset/base/233342

Log:
  Check that scheme is not already registered. This may happens when a
  KLD is preloaded with loader(8) and leads to infinity loops.
  
  Also do not return EEXIST error code from MOD_LOAD handler, because
  we have undocumented(?) ability replace kernel's module with preloaded one.
  And if we have so, then preloaded module will be initialized first.
  Thus error in MOD_LOAD handler will be triggered for the kernel.
  
  PR:		kern/165573
  MFC after:	3 weeks

Modified:
  head/sys/geom/part/g_part.c

Modified: head/sys/geom/part/g_part.c
==============================================================================
--- head/sys/geom/part/g_part.c	Fri Mar 23 06:57:04 2012	(r233341)
+++ head/sys/geom/part/g_part.c	Fri Mar 23 07:26:17 2012	(r233342)
@@ -2211,23 +2211,32 @@ g_part_unload_event(void *arg, int flag)
 int
 g_part_modevent(module_t mod, int type, struct g_part_scheme *scheme)
 {
+	struct g_part_scheme *iter;
 	uintptr_t arg;
 	int error;
 
+	error = 0;
 	switch (type) {
 	case MOD_LOAD:
-		TAILQ_INSERT_TAIL(&g_part_schemes, scheme, scheme_list);
-
-		error = g_retaste(&g_part_class);
-		if (error)
-			TAILQ_REMOVE(&g_part_schemes, scheme, scheme_list);
+		TAILQ_FOREACH(iter, &g_part_schemes, scheme_list) {
+			if (scheme == iter) {
+				printf("GEOM_PART: scheme %s is already "
+				    "registered!\n", scheme->name);
+				break;
+			}
+		}
+		if (iter == NULL) {
+			TAILQ_INSERT_TAIL(&g_part_schemes, scheme,
+			    scheme_list);
+			g_retaste(&g_part_class);
+		}
 		break;
 	case MOD_UNLOAD:
 		arg = (uintptr_t)scheme;
 		error = g_waitfor_event(g_part_unload_event, &arg, M_WAITOK,
 		    NULL);
-		if (!error)
-			error = (arg == (uintptr_t)scheme) ? EDOOFUS : arg;
+		if (error == 0)
+			error = arg;
 		break;
 	default:
 		error = EOPNOTSUPP;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203230726.q2N7QH06062581>