summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/kldload/kldload.832
-rw-r--r--sbin/kldload/kldload.c119
2 files changed, 142 insertions, 9 deletions
diff --git a/sbin/kldload/kldload.8 b/sbin/kldload/kldload.8
index 474404f..e1f6757 100644
--- a/sbin/kldload/kldload.8
+++ b/sbin/kldload/kldload.8
@@ -50,10 +50,22 @@ using
.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 @@ Modules must have an extension of
.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
diff --git a/sbin/kldload/kldload.c b/sbin/kldload/kldload.c
index 0f4bbbb..dd4051b 100644
--- a/sbin/kldload/kldload.c
+++ b/sbin/kldload/kldload.c
@@ -27,15 +27,105 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/types.h>
#include <sys/param.h>
#include <sys/linker.h>
+#include <sys/sysctl.h>
+#include <sys/stat.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
+#define PATHCTL "kern.module_path"
+
+static int path_check(const char *, int);
static void usage(void);
+/*
+ * 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) {
+ break;
+ }
+ }
+
+ free(path);
+
+ if (!found) {
+ if (!quiet) {
+ warnx("%s is not in the module path", kldname);
+ }
+ return (-1);
+ }
+
+ return (0);
+}
+
static void
usage(void)
{
@@ -50,14 +140,21 @@ main(int argc, char** argv)
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();
@@ -70,14 +167,18 @@ main(int argc, char** argv)
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++;
}
OpenPOWER on IntegriCloud