modprobe-small: preparatory patch for modprobe.dep.bb creation patches,
authorDenis Vlasenko <vda.linux@googlemail.com>
Wed, 9 Jul 2008 15:30:57 +0000 (15:30 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Wed, 9 Jul 2008 15:30:57 +0000 (15:30 -0000)
 Code size impact ~0.

modutils/modprobe-small.c

index 1096ba7ae2112b5801e4c9810287d6d25a76d5c8..72209610a726bdc5bb24fa77b914822b8549d4df 100644 (file)
 #include <sys/utsname.h> /* uname() */
 #include <fnmatch.h>
 
+extern int init_module(void *module, unsigned long len, const char *options);
+extern int delete_module(const char *module, unsigned flags);
+extern int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret);
+
+
 #define dbg1_error_msg(...) ((void)0)
 #define dbg2_error_msg(...) ((void)0)
 //#define dbg1_error_msg(...) bb_error_msg(__VA_ARGS__)
 //#define dbg2_error_msg(...) bb_error_msg(__VA_ARGS__)
 
-extern int init_module(void *module, unsigned long len, const char *options);
-extern int delete_module(const char *module, unsigned flags);
-extern int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret);
+#define DEPFILE_BB CONFIG_DEFAULT_DEPMOD_FILE".bb"
 
 enum {
        OPT_q = (1 << 0), /* be quiet */
@@ -63,6 +66,12 @@ static void appendc(char c)
                stringbuf[stringbuf_idx++] = c;
 }
 
+static void bksp(void)
+{
+       if (stringbuf_idx)
+               stringbuf_idx--;
+}
+
 static void append(const char *s)
 {
        size_t len = strlen(s);
@@ -115,6 +124,19 @@ static void replace(char *s, char what, char with)
        }
 }
 
+/* Take "word word", return malloced "word",NUL,"word",NUL,NUL */
+static char* str_2_list(const char *str)
+{
+       int len = strlen(str) + 1;
+       char *dst = xmalloc(len + 1);
+
+       dst[len] = '\0';
+       memcpy(dst, str, len);
+//TODO: protect against 2+ spaces: "word  word"
+       replace(dst, ' ', '\0');
+       return dst;
+}
+
 #if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED
 static char *xmalloc_open_zipped_read_close(const char *fname, size_t *sizep)
 {
@@ -187,13 +209,13 @@ static int load_module(const char *fname, const char *options)
 #endif
 }
 
-static char* parse_module(const char *pathname, const char *name)
+static char* parse_module(const char *pathname)
 {
        char *module_image;
        char *ptr;
        size_t len;
        size_t pos;
-       dbg1_error_msg("parse_module('%s','%s')", pathname, name);
+       dbg1_error_msg("parse_module('%s')", pathname);
 
        /* Read (possibly compressed) module */
        len = 64 * 1024 * 1024; /* 64 Mb at most */
@@ -202,11 +224,7 @@ static char* parse_module(const char *pathname, const char *name)
        reset_stringbuf();
 
        /* First desc line's format is
-        * "modname alias1 symbol:sym1 alias2 symbol:sym2 " (note trailing ' ')
-        */
-       append(name);
-       appendc(' ');
-       /* Aliases */
+        * "alias1 symbol:sym1 alias2 symbol:sym2" */
        pos = 0;
        while (1) {
                ptr = find_keyword(module_image + pos, len - pos, "alias=");
@@ -217,19 +235,20 @@ static char* parse_module(const char *pathname, const char *name)
                        /* DOCME: __ksymtab_gpl and __ksymtab_strings occur
                         * in many modules. What do they mean? */
                        if (strcmp(ptr, "gpl") != 0 && strcmp(ptr, "strings") != 0) {
-                               dbg2_error_msg("alias: 'symbol:%s'", ptr);
+                               dbg2_error_msg("alias:'symbol:%s'", ptr);
                                append("symbol:");
                        }
                } else {
-                       dbg2_error_msg("alias: '%s'", ptr);
+                       dbg2_error_msg("alias:'%s'", ptr);
                }
                append(ptr);
                appendc(' ');
                pos = (ptr - module_image);
        }
+       bksp(); /* remove last ' ' */
        appendc('\0');
 
-       /* Second line: "dependency1 depandency2 " (note trailing ' ') */
+       /* Second line: "dependency1 depandency2" */
        ptr = find_keyword(module_image, len, "depends=");
        if (ptr && *ptr) {
                replace(ptr, ',', ' ');
@@ -237,28 +256,31 @@ static char* parse_module(const char *pathname, const char *name)
                dbg2_error_msg("dep:'%s'", ptr);
                append(ptr);
        }
-       appendc(' '); appendc('\0');
+       appendc('\0');
 
        free(module_image);
        return copy_stringbuf();
 }
 
-static char* pathname_2_modname(const char *pathname)
+static int pathname_matches_modname(const char *pathname, const char *modname)
 {
        const char *fname = bb_get_last_path_component_nostrip(pathname);
        const char *suffix = strrstr(fname, ".ko");
+//TODO: can do without malloc?
        char *name = xstrndup(fname, suffix - fname);
+       int r;
        replace(name, '-', '_');
-       return name;
+       r = (strcmp(name, modname) == 0);
+       free(name);
+       return r;
 }
 
 static FAST_FUNC int fileAction(const char *pathname,
                struct stat *sb UNUSED_PARAM,
-               void *data,
+               void *modname_to_match,
                int depth UNUSED_PARAM)
 {
        int cur;
-       char *name;
        const char *fname;
 
        pathname += 2; /* skip "./" */
@@ -270,21 +292,20 @@ static FAST_FUNC int fileAction(const char *pathname,
 
        cur = module_count++;
        modinfo = xrealloc_vector(modinfo, 12, cur);
+//TODO: use zeroing version of xrealloc_vector?
        modinfo[cur].pathname = xstrdup(pathname);
        modinfo[cur].desc = NULL;
        modinfo[cur+1].pathname = NULL;
        modinfo[cur+1].desc = NULL;
 
-       name = pathname_2_modname(fname);
-       if (strcmp(name, data) != 0) {
-               free(name);
+       if (!pathname_matches_modname(fname, modname_to_match)) {
                dbg1_error_msg("'%s' module name doesn't match", pathname);
                return TRUE; /* module name doesn't match, continue search */
        }
 
        dbg1_error_msg("'%s' module name matches", pathname);
        module_found_idx = cur;
-       modinfo[cur].desc = parse_module(pathname, name);
+       modinfo[cur].desc = parse_module(pathname);
 
        if (!(option_mask32 & OPT_r)) {
                if (load_module(pathname, module_load_options) == 0) {
@@ -292,11 +313,9 @@ static FAST_FUNC int fileAction(const char *pathname,
                         * This can happen ONLY for "top-level" module load,
                         * not a dep, because deps dont do dirscan. */
                        exit(EXIT_SUCCESS);
-                       /*free(name);return RECURSE_RESULT_ABORT;*/
                }
        }
 
-       free(name);
        return TRUE;
 }
 
@@ -308,16 +327,13 @@ static module_info* find_alias(const char *alias)
        /* First try to find by name (cheaper) */
        i = 0;
        while (modinfo[i].pathname) {
-               char *name = pathname_2_modname(modinfo[i].pathname);
-               if (strcmp(name, alias) == 0) {
+               if (pathname_matches_modname(modinfo[i].pathname, alias)) {
                        dbg1_error_msg("found '%s' in module '%s'",
                                        alias, modinfo[i].pathname);
                        if (!modinfo[i].desc)
-                               modinfo[i].desc = parse_module(modinfo[i].pathname, name);
-                       free(name);
+                               modinfo[i].desc = parse_module(modinfo[i].pathname);
                        return &modinfo[i];
                }
-               free(name);
                i++;
        }
 
@@ -326,16 +342,13 @@ static module_info* find_alias(const char *alias)
        while (modinfo[i].pathname) {
                char *desc, *s;
                if (!modinfo[i].desc) {
-                       char *name = pathname_2_modname(modinfo[i].pathname);
-                       modinfo[i].desc = parse_module(modinfo[i].pathname, name);
-                       free(name);
+                       modinfo[i].desc = parse_module(modinfo[i].pathname);
                }
-               /* "modname alias1 symbol:sym1 alias2 symbol:sym2 " */
-               desc = xstrdup(modinfo[i].desc);
+               /* "alias1 symbol:sym1 alias2 symbol:sym2" */
+               desc = str_2_list(modinfo[i].desc);
                /* Does matching substring exist? */
-               replace(desc, ' ', '\0');
                for (s = desc; *s; s += strlen(s) + 1) {
-                       /* aliases in module bodies can be defined with
+                       /* Aliases in module bodies can be defined with
                         * shell patterns. Example:
                         * "pci:v000010DEd000000D9sv*sd*bc*sc*i*".
                         * Plain strcmp() won't catch that */
@@ -463,10 +476,8 @@ static void process_module(char *name, const char *cmdline_options)
        }
 
        /* Second line of desc contains dependencies */
-       deps = xstrdup(info->desc + strlen(info->desc) + 1);
+       deps = str_2_list(info->desc + strlen(info->desc) + 1);
 
-       /* Transform deps to string list */
-       replace(deps, ' ', '\0');
        /* Iterate thru dependencies, trying to (un)load them */
        for (s = deps; *s; s += strlen(s) + 1) {
                //if (strcmp(name, s) != 0) // N.B. do loops exist?
@@ -481,12 +492,12 @@ static void process_module(char *name, const char *cmdline_options)
                errno = 0;
                if (load_module(info->pathname, options) != 0) {
                        if (EEXIST != errno) {
-                               bb_error_msg("insert '%s' %s: %s",
-                                               info->pathname, options,
+                               bb_error_msg("'%s': %s",
+                                               info->pathname,
                                                moderror(errno));
                        } else {
-                               dbg1_error_msg("insert '%s' %s: %s",
-                                               info->pathname, options,
+                               dbg1_error_msg("'%s': %s",
+                                               info->pathname,
                                                moderror(errno));
                        }
                }