X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=kmodloader.c;h=db4574e27d25005228baf740cc81db53c9351945;hb=f309065fe99839f8e07ec9a2cc1d53ba62af8236;hp=98bda48b506357b66e3d0fef4aa06f52edfb0c20;hpb=16f0ad316f01520fe318e0855c0873a3915c3640;p=oweals%2Fubox.git diff --git a/kmodloader.c b/kmodloader.c index 98bda48..db4574e 100644 --- a/kmodloader.c +++ b/kmodloader.c @@ -55,6 +55,7 @@ struct module { char *name; char *depends; + char *opts; int size; int usage; @@ -84,7 +85,6 @@ static char* get_module_path(char *name) static char path[256]; struct utsname ver; struct stat s; - char *t; if (!stat(name, &s)) return name; @@ -92,18 +92,6 @@ static char* get_module_path(char *name) uname(&ver); snprintf(path, 256, "%s" DEF_MOD_PATH "%s.ko", prefix, ver.release, name); - if (!stat(path, &s)) - return path; - - t = name; - while (t && *t) { - if (*t == '_') - *t = '-'; - t++; - } - - snprintf(path, 256, "%s" DEF_MOD_PATH "%s.ko", prefix, ver.release, name); - if (!stat(path, &s)) return path; @@ -120,18 +108,11 @@ static char* get_module_name(char *path) t = strstr(name, ".ko"); if (t) *t = '\0'; - t = name; - while (t && *t) { - if (*t == '-') - *t = '_'; - t++; - } return name; } -#if __WORDSIZE == 64 -static int elf_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size) +static int elf64_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size) { const char *secnames; Elf64_Ehdr *e; @@ -152,8 +133,8 @@ static int elf_find_section(char *map, const char *section, unsigned int *offset return -1; } -#else -static int elf_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size) + +static int elf32_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size) { const char *secnames; Elf32_Ehdr *e; @@ -174,7 +155,20 @@ static int elf_find_section(char *map, const char *section, unsigned int *offset return -1; } -#endif + +static int elf_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size) +{ + int clazz = map[EI_CLASS]; + + if (clazz == ELFCLASS32) + return elf32_find_section(map, section, offset, size); + else if (clazz == ELFCLASS64) + return elf64_find_section(map, section, offset, size); + + LOG("unknown elf format %d\n", clazz); + + return -1; +} static struct module * alloc_module(const char *name, const char *depends, int size) @@ -184,17 +178,25 @@ alloc_module(const char *name, const char *depends, int size) m = calloc_a(sizeof(*m), &_name, strlen(name) + 1, - &_dep, depends ? strlen(depends) + 1 : 0); + &_dep, depends ? strlen(depends) + 2 : 0); if (!m) return NULL; m->avl.key = m->name = strcpy(_name, name); + m->opts = 0; - if (depends) + if (depends) { m->depends = strcpy(_dep, depends); + while (*_dep) { + if (*_dep == ',') + *_dep = '\0'; + _dep++; + } + } m->size = size; avl_insert(&modules, &m->avl); + return m; } @@ -296,8 +298,8 @@ static int scan_module_folder(void) int j; uname(&ver); - path = alloca(sizeof(DEF_MOD_PATH "*.ko") + strlen(ver.release) + 1); - sprintf(path, DEF_MOD_PATH "*.ko", ver.release); + path = alloca(sizeof(DEF_MOD_PATH "*.ko") + strlen(prefix) + strlen(ver.release) + 1); + sprintf(path, "%s" DEF_MOD_PATH "*.ko", prefix, ver.release); if (glob(path, gl_flags, NULL, &gl) < 0) return -1; @@ -376,33 +378,25 @@ static int print_modinfo(char *module) static int deps_available(struct module *m, int verbose) { - char *deps, *_deps; - char *comma; + char *dep; int err = 0; if (!strcmp(m->depends, "-") || !strcmp(m->depends, "")) return 0; - _deps = deps = strdup(m->depends); + dep = m->depends; - do { - comma = strstr(deps, ","); - if (comma) - *comma = '\0'; - - m = find_module(deps); + while (*dep) { + m = find_module(dep); if (verbose && !m) - LOG("missing dependency %s\n", deps); + LOG("missing dependency %s\n", dep); if (verbose && m && (m->state != LOADED)) - LOG("dependency not loaded %s\n", deps); + LOG("dependency not loaded %s\n", dep); if (!m || (m->state != LOADED)) err++; - if (comma) - deps = ++comma; - } while (comma); - - free(_deps); + dep += strlen(dep) + 1; + } return err; } @@ -438,47 +432,29 @@ static int insert_module(char *path, const char *options) static void load_moddeps(struct module *_m) { - char *deps, *_deps; + char *dep; struct module *m; - char *comma; if (!strcmp(_m->depends, "-") || !strcmp(_m->depends, "")) return; - _deps = deps = strdup(_m->depends); - - do { - char *t = deps; - - comma = strstr(deps, ","); - if (comma) - *comma = '\0'; + dep = _m->depends; - m = find_module(deps); - - if (!m) { - while (t && *t) { - if (*t == '-') - *t = '_'; - t++; - } - m = find_module(deps); - } + while (*dep) { + m = find_module(dep); if (!m) - LOG("failed to find dependency %s\n", deps); + LOG("failed to find dependency %s\n", dep); if (m && (m->state != LOADED)) { m->state = PROBE; load_moddeps(m); } - if (comma) - deps = ++comma; - } while (comma); - - free(_deps); + dep = dep + strlen(dep) + 1; + } } +static int iterations = 0; static int load_modprobe(void) { int loaded, todo; @@ -493,7 +469,7 @@ static int load_modprobe(void) todo = 0; avl_for_each_element(&modules, m, avl) { if ((m->state == PROBE) && (!deps_available(m, 0))) { - if (!insert_module(get_module_path(m->name), "")) { + if (!insert_module(get_module_path(m->name), (m->opts) ? (m->opts) : (""))) { m->state = LOADED; m->error = 0; loaded++; @@ -505,6 +481,7 @@ static int load_modprobe(void) if ((m->state == PROBE) || m->error) todo++; } + iterations++; } while (loaded); return todo; @@ -563,6 +540,11 @@ static int main_insmod(int argc, char **argv) cur += sprintf(cur, "%s", argv[i]); } + if (!get_module_path(name)) { + fprintf(stderr, "Failed to find %s. Maybe it is a built in module ?\n", name); + return -1; + } + ret = insert_module(get_module_path(name), options); free(options); @@ -590,13 +572,13 @@ static int main_rmmod(int argc, char **argv) LOG("module is not loaded\n"); return -1; } - free_modules(); - - ret = syscall(__NR_delete_module, name, 0); + ret = syscall(__NR_delete_module, m->name, 0); if (ret) LOG("unloading the module failed\n"); + free_modules(); + return ret; } @@ -620,18 +602,29 @@ static int main_lsmod(int argc, char **argv) static int main_modinfo(int argc, char **argv) { - char *module; + struct module *m; + char *name; if (argc != 2) return print_usage("modinfo"); - module = get_module_path(argv[1]); - if (!module) { + if (scan_module_folder()) + return -1; + + name = get_module_name(argv[1]); + m = find_module(name); + if (!m) { LOG("cannot find module - %s\n", argv[1]); return -1; } - print_modinfo(module); + name = get_module_path(m->name); + if (!name) { + LOG("cannot find path of module - %s\n", m->name); + return -1; + } + + print_modinfo(name); return 0; } @@ -735,6 +728,8 @@ static int main_loader(int argc, char **argv) if (!m || (m->state == LOADED)) continue; + if (opts) + m->opts = strdup(opts); m->state = PROBE; if (basename(gl.gl_pathv[j])[0] - '0' <= 9) load_modprobe(); @@ -745,6 +740,7 @@ static int main_loader(int argc, char **argv) } fail = load_modprobe(); + LOG("ran %d iterations\n", iterations); if (fail) { LOG("%d module%s could not be probed\n", @@ -762,11 +758,27 @@ out: return 0; } +static int avl_modcmp(const void *k1, const void *k2, void *ptr) +{ + const char *s1 = k1; + const char *s2 = k2; + + while (*s1 && ((*s1 == *s2) || + ((*s1 == '_') && (*s2 == '-')) || + ((*s1 == '-') && (*s2 == '_')))) + { + s1++; + s2++; + } + + return *(const unsigned char *)s1 - *(const unsigned char *)s2; +} + int main(int argc, char **argv) { char *exec = basename(*argv); - avl_init(&modules, avl_strcmp, false, NULL); + avl_init(&modules, avl_modcmp, false, NULL); if (!strcmp(exec, "insmod")) return main_insmod(argc, argv);