From c1df4ef16b06586579dce59eb1b46c692f438db2 Mon Sep 17 00:00:00 2001 From: pgoyette Date: Sat, 6 Feb 2016 22:48:07 +0000 Subject: [PATCH] In module_do_load(), consolidate checking for a pre-existing module, and return a single error value EEXIST. When making a recursive call (to load required modules), treat a pre-existing module as success. Without this change, when a module was loaded by specific request (as opposed to being loaded as a requirement of some other module), we would always load the module from the file-system, and then after making various sanity/compatability checks we would destroy the new copy if there was a pre-existing copy. Fixes PR kern/40764 XXX Note that if the module exists, we bypass all of the various XXX "compatability" checks, including whether or not the existing XXX module is of any particular class! (In the previous code, we XXX checked to see if the newly-loaded copy had the correct class, XXX but not the pre-existing copy, which could have been loaded XXX from a different path/filename.) --- sys/kern/kern_module.c | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c index 580e5a84fa66..a371c0d98fb1 100644 --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_module.c,v 1.109 2015/12/09 16:26:16 maxv Exp $ */ +/* $NetBSD: kern_module.c,v 1.110 2016/02/06 22:48:07 pgoyette Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.109 2015/12/09 16:26:16 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.110 2016/02/06 22:48:07 pgoyette Exp $"); #define _MODULE_INTERNAL @@ -936,21 +936,19 @@ module_do_load(const char *name, bool isdep, int flags, TAILQ_INSERT_TAIL(pending, mod, mod_chain); } else { /* - * If a requisite module, check to see if it is - * already present. + * Check to see if module is already present. */ - if (isdep) { - mod = module_lookup(name); - if (mod != NULL) { - if (modp != NULL) { - *modp = mod; - } - module_print("dependent module `%s' already " - "loaded", name); - depth--; - return 0; + mod = module_lookup(name); + if (mod != NULL) { + if (modp != NULL) { + *modp = mod; } + module_print("%s module `%s' already loaded", + isdep ? "dependent" : "requested", name); + depth--; + return EEXIST; } + mod = module_newmodule(MODULE_SOURCE_FILESYS); if (mod == NULL) { module_error("out of memory for `%s'", name); @@ -1029,19 +1027,6 @@ module_do_load(const char *name, bool isdep, int flags, goto fail; } - /* - * Check to see if the module is already loaded. If so, we may - * have been recursively called to handle a dependency, so be sure - * to set modp. - */ - if ((mod2 = module_lookup(mi->mi_name)) != NULL) { - if (modp != NULL) - *modp = mod2; - module_print("module `%s' already loaded", mi->mi_name); - error = EEXIST; - goto fail; - } - /* * Block circular dependencies. */ @@ -1093,7 +1078,7 @@ module_do_load(const char *name, bool isdep, int flags, } error = module_do_load(buf, true, flags, NULL, &mod2, MODULE_CLASS_ANY, true); - if (error != 0) { + if (error != 0 && error != EEXIST) { module_error("recursive load failed for `%s' " "(`%s' required), error %d", mi->mi_name, buf, error);