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;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to