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


--
To unsubscribe from this list: send the line "unsubscribe linux-modules" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to