[PATCH] Re: modprobe documentation discrepancy (modules.dep support)
From: Andrej Krutak <hidden>
Date: 2014-02-26 16:19:42
Subsystem:
the rest · Maintainer:
Linus Torvalds
Hi again, below is a patch to (re-)add support for modules.dep (in addition to modules.dep.bin), in a very dirty way. Basically I just took parts of the original code from module-init-tools... Also, it fixes the CHECK_ERR_AND_FINISH macro. However, this doesn't fix the whole "problem" - 'modprobe nonexistingmodule' is called, no error is printed, because of the faulty processing of subsequent non-existent files (like modules.builtin.bin etc. - which depmod.pl doesn't generate). To fully fix this, one would have to also add support for the other legacy files. Well, at least a support to handle the missing files gracefully. Fixing this is important for when you want to cross-compile the kernel in a non-linux environment. I didn't find find any other tool than depmod.pl that could generate all the files required by modprobe (but depmod.pl, as mentioned before, doesn't generate other .bin files) - and kmod/module-init-tools can't be cross-compiled for cygwin/mingw32... Best regards, Andrej Krutak SYSGO --- libkmod/libkmod-module.c | 4 +- libkmod/libkmod.c | 107 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 107 insertions(+), 4 deletions(-)
diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
index 3d3325f..e737d30 100644
--- a/libkmod/libkmod-module.c
+++ b/libkmod/libkmod-module.c@@ -473,7 +473,7 @@ KMOD_EXPORT struct kmod_module *kmod_module_ref(struct kmod_module *mod) if ((_err) < 0) \ goto _label_err; \ if (*(_list) != NULL) \ - goto finish; \ + goto label_finish; \ } while (0) /**
@@ -553,7 +553,7 @@ finish: DBG(ctx, "lookup %s=%d, list=%p\n", alias, err, *list); return err; fail: - DBG(ctx, "Failed to lookup %s\n", alias); + DBG(ctx, "Failed to lookup %s (%d)\n", alias, err); kmod_module_unref_list(*list); *list = NULL; return err;
diff --git a/libkmod/libkmod.c b/libkmod/libkmod.c
index ef83e31..4a60416 100644
--- a/libkmod/libkmod.c
+++ b/libkmod/libkmod.c@@ -533,11 +533,106 @@ finish: return err; } +/** + * modname_equal - compare module names (up to len), with '_' and '-' equal + * + * @a: first module name + * @b: second module name + * @len: length to compare + * + */ +static int modname_equal(const char *a, const char *b, unsigned int len) +{ + unsigned int i; + + if (strlen(b) != len) + return 0; + + for (i = 0; i < len; i++) { + if ((a[i] == '_' || a[i] == '-') + && (b[i] == '_' || b[i] == '-')) + continue; + if (a[i] != b[i]) + return 0; + } + return 1; +} + +static char *my_basename(const char *path) +{ + const char *base = strrchr(path, '/'); + if (base) + return (char *) base + 1; + return (char *) path; +} + + +/** + * add_modules_dep_line - parse a dep line from the module.dep[.bin] file + * + * @line: input file line + * @name: module name + * + * Add dependency information if this line of the dep file matches mod name + */ +static int is_module_line(char *line, + const char *name) +{ + char *ptr; + int len; + char *modname; + int rv; + + line = strdup(line); + + /* Ignore lines without : or which start with a # */ + ptr = strchr(line, ':'); + if (ptr == NULL || line[strspn(line, "\t ")] == '#') { + free(line); + return 0; + } + + /* Is this the module we are looking for? */ + *ptr = '\0'; + modname = my_basename(line); + + len = strlen(modname); + if (strchr(modname, '.')) + len = strchr(modname, '.') - modname; + + rv = modname_equal(modname, name, len); + + free(line); + return rv; +} + +static char *kmod_search_moddep_legacy(struct kmod_ctx *ctx, const char
*name, const char *fn)
+{
+ char *line;
+ FILE *modules_dep;
+
+ modules_dep = fopen(fn, "r");
+ if (!modules_dep)
+ return NULL;
+
+ /* Stop at first line, as we can have duplicates (eg. symlinks
+ from boot/ */
+ while ((line = getline_wrapped(modules_dep, NULL)) != NULL) {
+ if (is_module_line(line, name))
+ break;
+ free(line);
+ }
+ fclose(modules_dep);
+
+ return line;
+}
+
char *kmod_search_moddep(struct kmod_ctx *ctx, const char *name)
{
struct index_file *idx;
char fn[PATH_MAX];
char *line;
+
if (ctx->indexes[KMOD_INDEX_MODULES_DEP]) {
DBG(ctx, "use mmaped index '%s' modname=%s\n",@@ -553,8 +648,16 @@ char *kmod_search_moddep(struct kmod_ctx *ctx, const char *name)
idx = index_file_open(fn);
if (idx == NULL) {
- DBG(ctx, "could not open moddep file '%s'\n", fn);
- return NULL;
+ struct stat st;
+
+ snprintf(fn, sizeof(fn), "%s/%s", ctx->dirname,
+ index_files[KMOD_INDEX_MODULES_DEP].fn);
+ if (stat(fn, &st) != 0) {
+ DBG(ctx, "could not open moddep file '%s[.bin]'\n", fn);
+ return NULL;
+ }
+
+ return kmod_search_moddep_legacy(ctx, name, fn);
}
line = index_search(idx, name);
--
1.7.9.5