Index: sbin/kldload/kldload.8 =================================================================== --- sbin/kldload/kldload.8 (revision 193292) +++ sbin/kldload/kldload.8 (working copy) @@ -50,10 +50,22 @@ .Nm . It does not hurt to specify it though. .Pp +If a bare filename is requested it will only be loaded if it is found within +the module path as defined by the sysctl +.Va kern.module_path . +To load a module from the current directory it must be specified as a full or +relative path. +The +.Nm +utility will warn if a module is requested as a bare filename and is present +in the current directory. +.Pp The following option is available: .Bl -tag -width indent .It Fl v Be more verbose. +.It Fl q +Silence any extraneous warnings. .El .Sh FILES .Bl -tag -width /boot/kernel -compact @@ -64,6 +76,26 @@ .El .Sh EXIT STATUS .Ex -std +.Sh EXAMPLES +To load by module name: +.Bd -literal -offset indent +\*[Gt] kldload foo +.Ed +.Pp +To load by file name within the module path: +.Bd -literal -offset indent +\*[Gt] kldload foo.ko +.Ed +.Pp +To load by relative path: +.Bd -literal -offset indent +\*[Gt] kldload ./foo.ko +.Ed +.Pp +To load by full path: +.Bd -literal -offset indent +\*[Gt] kldload /boot/kernel/foo.ko +.Ed .Sh AUTOMATICALLY LOADING MODULES Some modules (pf, ipfw, ipf, etc.) may be automatically loaded at boot time when the corresponding Index: sbin/kldload/kldload.c =================================================================== --- sbin/kldload/kldload.c (revision 193292) +++ sbin/kldload/kldload.c (working copy) @@ -30,10 +30,99 @@ #include #include #include +#include #include #include #include +#include +#include +#include +#define PATHCTL "kern.module_path" + +/* + * Check to see if the requested module is specified as a filename with no + * path. If so and if a file by the same name exists in the module path, + * warn the user that the module in the path will be used in preference. + */ +static int +path_check(const char *kldname, int quiet) +{ + int mib[5], found; + size_t miblen, pathlen; + char kldpath[MAXPATHLEN]; + char *path, *tmppath, *element; + struct stat sb; + dev_t dev; + ino_t ino; + + if (strchr(kldname, '/') != NULL) { + return (0); + } + if (strstr(kldname, ".ko") == NULL) { + return (0); + } + if (stat(kldname, &sb) != 0) { + return (0); + } + + found = 0; + dev = sb.st_dev; + ino = sb.st_ino; + + miblen = sizeof(mib) / sizeof(mib[0]); + if (sysctlnametomib(PATHCTL, mib, &miblen) != 0) { + err(1, "sysctlnametomib(%s)", PATHCTL); + } + if (sysctl(mib, miblen, NULL, &pathlen, NULL, 0) == -1) { + err(1, "getting path: sysctl(%s) - size only", PATHCTL); + } + path = malloc(pathlen + 1); + if (path == NULL) { + err(1, "allocating %lu bytes for the path", + (unsigned long)pathlen + 1); + } + if (sysctl(mib, miblen, path, &pathlen, NULL, 0) == -1) { + err(1, "getting path: sysctl(%s)", PATHCTL); + } + tmppath = path; + + while ((element = strsep(&tmppath, ";")) != NULL) { + strlcpy(kldpath, element, MAXPATHLEN); + if (kldpath[strlen(kldpath) - 1] != '/') { + strlcat(kldpath, "/", MAXPATHLEN); + } + strlcat(kldpath, kldname, MAXPATHLEN); + + if (stat(kldpath, &sb) == -1) { + continue; + } + + found = 1; + + if (sb.st_dev != dev || sb.st_ino != ino) { + if (!quiet) { + warnx("%s will be loaded from %s, not the " + "current directory", kldname, element); + } + break; + } else if (sb.st_dev == dev && sb.st_ino == ino) { + return (0); + } + } + + free(path); + + if (!found) { + if (!quiet) { + warnx("%s is not in the module path", kldname); + } + return (-1); + } + + return (0); +} + static void usage(void) { @@ -48,14 +137,21 @@ int errors; int fileid; int verbose; + int quiet; errors = 0; verbose = 0; - - while ((c = getopt(argc, argv, "v")) != -1) + quiet = 0; + + while ((c = getopt(argc, argv, "qv")) != -1) switch (c) { + case 'q': + quiet = 1; + verbose = 0; + break; case 'v': verbose = 1; + quiet = 0; break; default: usage(); @@ -67,13 +163,17 @@ usage(); while (argc-- != 0) { - fileid = kldload(argv[0]); - if (fileid < 0) { - warn("can't load %s", argv[0]); - errors++; - } else - if (verbose) - printf("Loaded %s, id=%d\n", argv[0], fileid); + if (path_check(argv[0], quiet) == 0) { + fileid = kldload(argv[0]); + if (fileid < 0) { + warn("can't load %s", argv[0]); + errors++; + } else + if (verbose) + printf("Loaded %s, id=%d\n", argv[0], fileid); + } else { + errors++; + } argv++; }