summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/modules.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/modules.c')
-rw-r--r--mdk-stage1/modules.c221
1 files changed, 96 insertions, 125 deletions
diff --git a/mdk-stage1/modules.c b/mdk-stage1/modules.c
index 5f02d2a6d..76177302e 100644
--- a/mdk-stage1/modules.c
+++ b/mdk-stage1/modules.c
@@ -1,5 +1,5 @@
/*
- * Guillaume Cottenceau (gc@mandriva.com)
+ * Guillaume Cottenceau (gc)
*
* Copyright 2000 Mandriva
*
@@ -30,7 +30,9 @@
#include <string.h>
#include <stdio.h>
#include <errno.h>
+#include <time.h>
#include <sys/utsname.h>
+#include <libkmod.h>
#include "log.h"
#include "utils.h"
#include "frontend.h"
@@ -39,16 +41,11 @@
#include "modules.h"
-#define UEVENT_HELPER_FILE "/sys/kernel/uevent_helper"
-#define UEVENT_HELPER_VALUE "/sbin/hotplug"
-
static char modules_directory[100];
-static struct module_deps_elem * modules_deps = NULL;
static struct module_descr_elem * modules_descr = NULL;
extern long init_module(void *, unsigned long, const char *);
-
static const char *moderror(int err)
{
switch (err) {
@@ -89,7 +86,7 @@ int insmod_local_file(char * path, char * options)
static char *kernel_module_extension(void)
{
- return ".ko.gz";
+ return ".ko.xz";
}
@@ -123,76 +120,6 @@ static void find_modules_directory(void)
sprintf(modules_directory , "%s/%s", prefix, release);
}
-static int load_modules_dependencies(void)
-{
- char * deps_file = asprintf_("%s/%s", modules_directory, "modules.dep");
- char * buf, * ptr, * start, * end;
- struct stat s;
- int line, i;
-
- log_message("loading modules dependencies");
- buf = cat_file(deps_file, &s);
- if (!buf)
- return -1;
- line = line_counts(buf);
- modules_deps = malloc(sizeof(*modules_deps) * (line+1));
-
- start = buf;
- line = 0;
- while (start < (buf+s.st_size) && *start) {
- char * tmp_deps[50];
-
- end = strchr(start, '\n');
- *end = '\0';
-
- ptr = strchr(start, ':');
- if (!ptr) {
- start = end + 1;
- continue;
- }
- *ptr = '\0';
- ptr++;
-
- while (*ptr && (*ptr == ' ')) ptr++;
-
- /* sort of a good line */
- modules_deps[line].filename = start[0] == '/' ? strdup(start) : asprintf_("%s/%s", modules_directory, start);
- modules_deps[line].modname = filename2modname(start);
-
- start = ptr;
- i = 0;
- while (start && *start && i < sizeof(tmp_deps)/sizeof(char *)) {
- ptr = strchr(start, ' ');
- if (ptr) *ptr = '\0';
- tmp_deps[i++] = filename2modname(start);
- if (ptr)
- start = ptr + 1;
- else
- start = NULL;
- while (start && *start && *start == ' ')
- start++;
- }
- if(i >= sizeof(tmp_deps)/sizeof(char *)-1) {
- log_message("warning, more than %zu dependencies for module %s",
- sizeof(tmp_deps)/sizeof(char *)-1,
- modules_deps[line].modname);
- i = sizeof(tmp_deps)/sizeof(char *)-1;
- }
- tmp_deps[i++] = NULL;
-
- modules_deps[line].deps = memdup(tmp_deps, sizeof(char *) * i);
-
- line++;
- start = end + 1;
- }
- modules_deps[line].modname = NULL;
-
- free(buf);
-
- return 0;
-}
-
-
static int load_modules_descriptions(void)
{
char * descr_file = asprintf_("%s/%s", modules_directory, "modules.description");
@@ -235,23 +162,9 @@ static int load_modules_descriptions(void)
return 0;
}
-void init_firmware_loader(void)
-{
- int fd = open(UEVENT_HELPER_FILE, O_WRONLY|O_TRUNC, 0666);
- if (!fd) {
- log_message("warning, unable to set firmware loader");
- return;
- }
- write(fd, UEVENT_HELPER_VALUE, strlen(UEVENT_HELPER_VALUE));
- close(fd);
-}
-
void init_modules_insmoding(void)
{
find_modules_directory();
- if (load_modules_dependencies()) {
- fatal_error("warning, error initing modules stuff, modules loading disabled");
- }
if (load_modules_descriptions()) {
log_message("warning, error initing modules stuff");
}
@@ -287,6 +200,8 @@ static void add_modules_conf(char * str)
int module_already_present(const char * name)
{
FILE * f;
+ struct stat sb;
+ char *path;
int answ = 0;
if ((f = fopen("/proc/modules", "rb"))) {
@@ -298,52 +213,109 @@ int module_already_present(const char * name)
}
fclose(f);
}
+
+ /* built-in module case. try to find them through sysfs */
+ if (!answ) {
+ asprintf(&path, "/sys/module/%s", name);
+ if (!stat(path, &sb))
+ answ = 1;
+ free(path);
+ }
+ if (!answ) {
+ asprintf(&path, "/sys/fs/%s", name);
+ if (!stat(path, &sb))
+ answ = 1;
+ free(path);
+ }
return answ;
}
#ifndef ENABLE_NETWORK_STANDALONE
-static enum insmod_return insmod_with_deps(const char * mod_name, char * options, int allow_modules_floppy)
-{
- struct module_deps_elem * dep;
- const char * filename;
-
- dep = modules_deps;
- while (dep && dep->modname && strcmp(dep->modname, mod_name)) dep++;
-
- if (dep && dep->modname && dep->deps) {
- char ** one_dep;
- one_dep = dep->deps;
- while (*one_dep) {
- /* here, we can fail but we don't care, if the error is
- * important, the desired module will fail also */
- insmod_with_deps(*one_dep, NULL, allow_modules_floppy);
- one_dep++;
- }
+static enum insmod_return insmod_with_deps(const char * alias, char * options) {
+ struct kmod_ctx *ctx;
+ struct kmod_list *l, *list = NULL;
+ int err = 0, flags = 0;
+
+ if (!*modules_directory)
+ find_modules_directory();
+
+ ctx = kmod_new(modules_directory, NULL);
+ if (!ctx) {
+ fputs("Error: kmod_new() failed!\n", stderr);
+ goto exit;
}
-
- if (dep && dep->filename) {
- filename = dep->filename;
- } else {
- log_message("warning: unable to get module filename for %s", mod_name);
- filename = mod_name;
+ kmod_load_resources(ctx);
+
+ err = kmod_module_new_from_lookup(ctx, alias, &list);
+ if (err < 0)
+ goto exit;
+
+ // No module found...
+ if (list == NULL)
+ goto exit;
+
+ // filter through blacklist
+ struct kmod_list *filtered = NULL;
+ err = kmod_module_apply_filter(ctx, KMOD_FILTER_BLACKLIST, list, &filtered);
+ kmod_module_unref_list(list);
+ if (err < 0)
+ goto exit;
+ list = filtered;
+
+ kmod_list_foreach(l, list) {
+ struct kmod_module *mod = kmod_module_get_module(l);
+ err = kmod_module_probe_insert_module(mod, flags,
+ options, NULL, NULL, NULL);
+
+ if (err >= 0)
+ /* ignore flag return values such as a mod being blacklisted */
+ err = 0;
+ else {
+ switch (err) {
+ case -EEXIST:
+ fprintf(stderr, "could not insert '%s': Module already in kernel\n",
+ kmod_module_get_name(mod));
+ break;
+ case -ENOENT:
+ fprintf(stderr, "could not insert '%s': Unknown symbol in module, "
+ "or unknown parameter (see dmesg)\n",
+ kmod_module_get_name(mod));
+ break;
+ default:
+ fprintf(stderr, "could not insert '%s': %s\n",
+ kmod_module_get_name(mod),
+ strerror(-err));
+ break;
+ }
+ }
+
+ kmod_module_unref(mod);
+ if (err < 0)
+ break;
}
- if (module_already_present(mod_name))
- return INSMOD_OK;
+ kmod_module_unref_list(list);
- log_message("needs %s", filename);
- {
- return insmod_local_file((char *) filename, options);
+exit:
+ kmod_unref(ctx);
+
+ switch (err){
+ case 0:
+ return INSMOD_OK;
+ case -ENOENT:
+ return INSMOD_FAILED_FILE_NOT_FOUND;
+ default:
+ return INSMOD_FAILED;
}
}
#endif
#ifndef DISABLE_NETWORK
-enum insmod_return my_insmod(const char * mod_name, enum driver_type type, char * options, int allow_modules_floppy)
+enum insmod_return my_modprobe(const char * mod_name, enum driver_type type, char * options)
#else
-enum insmod_return my_insmod(const char * mod_name, enum driver_type type __attribute__ ((unused)), char * options, int allow_modules_floppy)
+enum insmod_return my_modprobe(const char * mod_name, enum driver_type type __attribute__ ((unused)), char * options)
#endif
{
int i;
@@ -369,7 +341,7 @@ enum insmod_return my_insmod(const char * mod_name, enum driver_type type __attr
i = system(cmd);
}
#else
- i = insmod_with_deps(mod_name, options, allow_modules_floppy);
+ i = insmod_with_deps(mod_name, options);
#endif
if (i == 0) {
log_message("\tsucceeded %s", mod_name);
@@ -387,7 +359,6 @@ enum insmod_return my_insmod(const char * mod_name, enum driver_type type __attr
sprintf(alias, "alias %s %s", *new_net_devices, mod_name);
add_modules_conf(alias);
log_message("NET: %s", alias);
- net_discovered_interface(*new_net_devices);
already_present:
new_net_devices++;
@@ -414,9 +385,9 @@ static enum return_type insmod_with_options(char * mod, enum driver_type type)
strcat(options, mod);
strcat(options, " ");
- strcat(options, answers[0]); // because my_insmod will eventually modify the string
+ strcat(options, answers[0]); // because my_modprobe will eventually modify the string
- if (my_insmod(mod, type, answers[0], 1) != INSMOD_OK) {
+ if (my_modprobe(mod, type, answers[0]) != INSMOD_OK) {
stg1_error_message("Insmod failed.");
return RETURN_ERROR;
}