Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157828815
D57002.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D57002.diff
View Options
diff --git a/lib/libc/gen/exterr_cat_filenames.h b/lib/libc/gen/exterr_cat_filenames.h
--- a/lib/libc/gen/exterr_cat_filenames.h
+++ b/lib/libc/gen/exterr_cat_filenames.h
@@ -12,6 +12,7 @@
[EXTERR_CAT_FILEDESC] = "kern/kern_descrip.c",
[EXTERR_CAT_PROCEXIT] = "kern/kern_exit.c",
[EXTERR_CAT_FORK] = "kern/kern_fork.c",
+ [EXTERR_CAT_LINKER] = "kern/kern_linker.c",
[EXTERR_CAT_GENIO] = "kern/sys_generic.c",
[EXTERR_CAT_VFSBIO] = "kern/vfs_bio.c",
[EXTERR_CAT_INOTIFY] = "kern/vfs_inotify.c",
diff --git a/sbin/kldload/kldload.c b/sbin/kldload/kldload.c
--- a/sbin/kldload/kldload.c
+++ b/sbin/kldload/kldload.c
@@ -95,8 +95,9 @@
if (sb.st_dev != dev || sb.st_ino != ino) {
if (!quiet)
- warnx("%s will be loaded from %s, not the "
- "current directory", kldname, element);
+ warnx(
+"%s will be loaded from %s, not the current directory",
+ kldname, element);
break;
} else if (sb.st_dev == dev && sb.st_ino == ino)
break;
@@ -171,15 +172,13 @@
if (!quiet) {
switch (errno) {
case EEXIST:
- warnx("can't load %s: module "
- "already loaded or "
- "in kernel", argv[0]);
+ warnx(
+"can't load %s: module already loaded or in kernel", argv[0]);
break;
case ENOEXEC:
- warnx("an error occurred while "
- "loading module %s. "
- "Please check dmesg(8) for "
- "more details.", argv[0]);
+ warnx(
+"an error occurred while loading module %s. Please check dmesg(8) for more details.",
+ argv[0]);
break;
default:
warn("can't load %s", argv[0]);
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -32,10 +32,12 @@
#include "opt_hwpmc_hooks.h"
#include "opt_hwt_hooks.h"
+#define EXTERR_CATEGORY EXTERR_CAT_LINKER
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/boottrace.h>
#include <sys/eventhandler.h>
+#include <sys/exterrvar.h>
#include <sys/fcntl.h>
#include <sys/jail.h>
#include <sys/kernel.h>
@@ -455,13 +457,14 @@
/* Refuse to load modules if securelevel raised */
if (prison0.pr_securelevel > 0)
- return (EPERM);
+ return (EXTERROR(EPERM, "security level %jd",
+ prison0.pr_securelevel));
sx_assert(&kld_sx, SA_XLOCKED);
lf = linker_find_file_by_name(filename);
if (lf) {
- KLD_DPF(FILE, ("linker_load_file: file %s is already loaded,"
- " incrementing refs\n", filename));
+ KLD_DPF(FILE,
+("linker_load_file: file %s is already loaded, incrementing refs\n", filename));
*result = lf;
lf->refs++;
return (0);
@@ -508,7 +511,7 @@
*/
if (modules && TAILQ_EMPTY(&lf->modules)) {
linker_file_unload(lf, LINKER_UNLOAD_FORCE);
- return (ENOEXEC);
+ return (EXTERROR(ENOEXEC, "no modules loaded"));
}
linker_file_enable_sysctls(lf);
@@ -535,17 +538,19 @@
__func__, filename);
/*
- * Format not recognized or otherwise unloadable.
- * When loading a module that is statically built into
- * the kernel EEXIST percolates back up as the return
- * value. Preserve this so that apps like sysinstall
- * can recognize this special case and not post bogus
- * dialog boxes.
+ * Format not recognized, version incompatible, or
+ * otherwise unloadable. When loading a module that is
+ * statically built into the kernel EEXIST percolates
+ * back up as the return value. Preserve this so that
+ * apps like sysinstall can recognize this special case
+ * and not post bogus dialog boxes.
*/
if (error != EEXIST)
- error = ENOEXEC;
+ error = EXTERROR(ENOEXEC,
+ "module format or version error");
} else
- error = ENOENT; /* Nothing found */
+ error = EXTERROR(ENOENT, "kld file not found");
+ /* Nothing found */
return (error);
}
@@ -2249,6 +2254,7 @@
struct linker_file *parent, const struct mod_depend *verinfo,
struct linker_file **lfpp)
{
+ modlist_t mod;
linker_file_t lfdep;
const char *filename;
char *pathname;
@@ -2259,16 +2265,15 @@
/*
* We have to load KLD
*/
- KASSERT(verinfo == NULL, ("linker_load_module: verinfo"
- " is not NULL"));
+ MPASS(verinfo == NULL);
if (!linker_root_mounted())
- return (ENXIO);
+ return (EXTERROR(ENXIO, "root not yet mounted"));
pathname = linker_search_kld(kldname);
} else {
if (modlist_lookup2(modname, verinfo) != NULL)
- return (EEXIST);
+ return (EXTERROR(EEXIST, "module already loaded"));
if (!linker_root_mounted())
- return (ENXIO);
+ return (EXTERROR(ENXIO, "root not yet mounted"));
if (kldname != NULL)
pathname = strdup(kldname, M_LINKER);
else
@@ -2279,7 +2284,7 @@
strlen(modname), verinfo);
}
if (pathname == NULL)
- return (ENOENT);
+ return (EXTERROR(ENOENT, "kld file not found"));
/*
* Can't load more than one file with the same basename XXX:
@@ -2288,16 +2293,36 @@
* provide different versions of the same modules.
*/
filename = linker_basename(pathname);
- if (linker_find_file_by_name(filename))
- error = EEXIST;
- else do {
+ lfdep = linker_find_file_by_name(filename);
+ if (lfdep) {
+ mod = modlist_lookup(modname, 0);
+ MPASS(mod != NULL);
+
+ if (modname && verinfo &&
+ modlist_lookup2(modname, verinfo) == NULL) {
+ /*
+ * Desired module is already loaded, but the correct
+ * version does not exist.
+ */
+ error = EXTERROR(ENOEXEC,
+ "incompatible module version %jd already loaded",
+ mod->version);
+ } else {
+ error = EXTERROR(EEXIST,
+ "module version %jd already loaded",
+ mod->version);
+ }
+ } else do {
error = linker_load_file(pathname, &lfdep);
if (error)
break;
if (modname && verinfo &&
modlist_lookup2(modname, verinfo) == NULL) {
+ mod = modlist_lookup(modname, 0);
+ error = EXTERROR(ENOEXEC,
+ "incompatible module version %jd already loaded",
+ mod->version);
linker_file_unload(lfdep, LINKER_UNLOAD_FORCE);
- error = ENOENT;
break;
}
if (parent)
@@ -2343,10 +2368,11 @@
ver = ((const struct mod_version *)mp->md_data)->mv_version;
mod = modlist_lookup(modname, ver);
if (mod != NULL) {
- printf("interface %s.%d already present in the KLD"
- " '%s'!\n", modname, ver,
- mod->container->filename);
- return (EEXIST);
+ printf(
+"interface %s.%d already present in the KLD '%s'!\n",
+ modname, ver, mod->container->filename);
+ return (EXTERROR(EEXIST,
+ "module version %jd already loaded", ver));
}
}
@@ -2376,8 +2402,9 @@
}
error = linker_load_module(NULL, modname, lf, verinfo, NULL);
if (error) {
- printf("KLD %s: depends on %s - not available or"
- " version mismatch\n", lf->filename, modname);
+ printf(
+"KLD %s: depends on %s - not available or version mismatch\n",
+ lf->filename, modname);
break;
}
}
diff --git a/sys/sys/exterr_cat.h b/sys/sys/exterr_cat.h
--- a/sys/sys/exterr_cat.h
+++ b/sys/sys/exterr_cat.h
@@ -41,6 +41,7 @@
#define EXTERR_CAT_PROCEXIT 16
#define EXTERR_CAT_VMM 17
#define EXTERR_CAT_HWPMC_IBS 18
+#define EXTERR_CAT_LINKER 19
#endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, May 26, 4:22 PM (15 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33533022
Default Alt Text
D57002.diff (7 KB)
Attached To
Mode
D57002: Bug 295139 - kldload prints wrong error message to terminal upon attempt to load incorrect module version
Attached
Detach File
Event Timeline
Log In to Comment