kernel (in addition to any options listed in the configuration
file).
</para>
+ <para>
+ When loading modules, <replaceable>modulename</replaceable> can also
+ be a path to the module. If the path is relative, it must
+ explicitly start with "./". Note that this may fail when using a
+ path to a module with dependencies not matching the installed depmod
+ database.
+ </para>
</refsect1>
<refsect1><title>OPTIONS</title>
["test-modprobe/alias-to-none/lib/modules/4.4.4/kernel/"]="mod-simple.ko"
["test-modprobe/module-param-kcmdline/lib/modules/4.4.4/kernel/"]="mod-simple.ko"
["test-modprobe/external/lib/modules/external/"]="mod-simple.ko"
+ ["test-modprobe/module-from-abspath/home/foo/"]="mod-simple.ko"
+ ["test-modprobe/module-from-relpath/home/foo/"]="mod-simple.ko"
["test-depmod/modules-order-compressed/lib/modules/4.4.4/kernel/drivers/block/cciss.ko"]="mod-fake-cciss.ko"
["test-depmod/modules-order-compressed/lib/modules/4.4.4/kernel/drivers/scsi/hpsa.ko"]="mod-fake-hpsa.ko"
["test-depmod/modules-order-compressed/lib/modules/4.4.4/kernel/drivers/scsi/scsi_mod.ko"]="mod-fake-scsi-mod.ko"
--- /dev/null
+# Aliases extracted from modules themselves.
--- /dev/null
+/lib/modules/external/mod-simple.ko:
--- /dev/null
+# Soft dependencies extracted from modules themselves.
--- /dev/null
+# Aliases for symbols, used by symbol_request().
--- /dev/null
+# Aliases extracted from modules themselves.
--- /dev/null
+/lib/modules/external/mod-simple.ko:
--- /dev/null
+# Soft dependencies extracted from modules themselves.
--- /dev/null
+# Aliases for symbols, used by symbol_request().
.modules_loaded = "mod-simple",
);
+static noreturn int modprobe_module_from_abspath(const struct test *t)
+{
+ const char *progname = ABS_TOP_BUILDDIR "/tools/modprobe";
+ const char *const args[] = {
+ progname,
+ "/home/foo/mod-simple.ko",
+ NULL,
+ };
+
+ test_spawn_prog(progname, args);
+ exit(EXIT_FAILURE);
+}
+DEFINE_TEST(modprobe_module_from_abspath,
+ .description = "check modprobe able to load module given as an absolute path",
+ .config = {
+ [TC_UNAME_R] = "4.4.4",
+ [TC_ROOTFS] = TESTSUITE_ROOTFS "test-modprobe/module-from-abspath",
+ [TC_INIT_MODULE_RETCODES] = "",
+ },
+ .modules_loaded = "mod-simple",
+ );
+
+static noreturn int modprobe_module_from_relpath(const struct test *t)
+{
+ const char *progname = ABS_TOP_BUILDDIR "/tools/modprobe";
+ const char *const args[] = {
+ progname,
+ "./mod-simple.ko",
+ NULL,
+ };
+
+ if (chdir("/home/foo") != 0) {
+ perror("failed to change into /home/foo");
+ exit(EXIT_FAILURE);
+ }
+
+ test_spawn_prog(progname, args);
+ exit(EXIT_FAILURE);
+}
+DEFINE_TEST(modprobe_module_from_relpath,
+ .description = "check modprobe able to load module given as a relative path",
+ .config = {
+ [TC_UNAME_R] = "4.4.4",
+ [TC_ROOTFS] = TESTSUITE_ROOTFS "test-modprobe/module-from-relpath",
+ [TC_INIT_MODULE_RETCODES] = "",
+ },
+ .need_spawn = true,
+ .modules_loaded = "mod-simple",
+ );
+
TESTSUITE_MAIN();
const char *extra_options)
{
struct kmod_list *l, *list = NULL;
+ struct kmod_module *mod = NULL;
int err, flags = 0;
- err = kmod_module_new_from_lookup(ctx, alias, &list);
-
- if (list == NULL || err < 0) {
- LOG("Module %s not found in directory %s\n", alias,
- ctx ? kmod_get_dirname(ctx) : "(missing)");
- return -ENOENT;
+ if (strncmp(alias, "/", 1) == 0 || strncmp(alias, "./", 2) == 0) {
+ err = kmod_module_new_from_path(ctx, alias, &mod);
+ if (err < 0) {
+ LOG("Failed to get module from path %s: %s\n", alias,
+ strerror(-err));
+ return -ENOENT;
+ }
+ } else {
+ err = kmod_module_new_from_lookup(ctx, alias, &list);
+ if (list == NULL || err < 0) {
+ LOG("Module %s not found in directory %s\n", alias,
+ ctx ? kmod_get_dirname(ctx) : "(missing)");
+ return -ENOENT;
+ }
}
if (strip_modversion || force)
if (first_time)
flags |= KMOD_PROBE_FAIL_ON_LOADED;
- kmod_list_foreach(l, list) {
- struct kmod_module *mod = kmod_module_get_module(l);
+ /* If module is loaded from path */
+ if (mod != NULL) {
err = insmod_insert(mod, flags, extra_options);
kmod_module_unref(mod);
+ } else {
+ kmod_list_foreach(l, list) {
+ mod = kmod_module_get_module(l);
+ err = insmod_insert(mod, flags, extra_options);
+ kmod_module_unref(mod);
+ }
+ kmod_module_unref_list(list);
}
-
- kmod_module_unref_list(list);
return err;
}