--- trunk/mkinitrd-magellan/busybox/modutils/modprobe-small.c 2010/04/29 20:38:48 983 +++ trunk/mkinitrd-magellan/busybox/modutils/modprobe-small.c 2010/05/30 11:32:42 984 @@ -9,7 +9,7 @@ */ #include "libbb.h" - +/* After libbb.h, since it needs sys/types.h on some systems */ #include /* uname() */ #include @@ -44,11 +44,13 @@ char *module_load_options; smallint dep_bb_seen; smallint wrote_dep_bb_ok; - int module_count; + unsigned module_count; int module_found_idx; - int stringbuf_idx; - char stringbuf[32 * 1024]; /* some modules have lots of stuff */ + unsigned stringbuf_idx; + unsigned stringbuf_size; + char *stringbuf; /* some modules have lots of stuff */ /* for example, drivers/media/video/saa7134/saa7134.ko */ + /* therefore having a fixed biggish buffer is not wise */ }; #define G (*ptr_to_globals) #define modinfo (G.modinfo ) @@ -58,16 +60,29 @@ #define module_found_idx (G.module_found_idx ) #define module_load_options (G.module_load_options) #define stringbuf_idx (G.stringbuf_idx ) +#define stringbuf_size (G.stringbuf_size ) #define stringbuf (G.stringbuf ) #define INIT_G() do { \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ } while (0) +static void append(const char *s) +{ + unsigned len = strlen(s); + if (stringbuf_idx + len + 15 > stringbuf_size) { + stringbuf_size = stringbuf_idx + len + 127; + dbg2_error_msg("grow stringbuf to %u", stringbuf_size); + stringbuf = xrealloc(stringbuf, stringbuf_size); + } + memcpy(stringbuf + stringbuf_idx, s, len); + stringbuf_idx += len; +} static void appendc(char c) { - if (stringbuf_idx < sizeof(stringbuf)) - stringbuf[stringbuf_idx++] = c; + /* We appendc() only after append(), + 15 trick in append() + * makes it unnecessary to check for overflow here */ + stringbuf[stringbuf_idx++] = c; } static void bksp(void) @@ -76,15 +91,6 @@ stringbuf_idx--; } -static void append(const char *s) -{ - size_t len = strlen(s); - if (stringbuf_idx + len < sizeof(stringbuf)) { - memcpy(stringbuf + stringbuf_idx, s, len); - stringbuf_idx += len; - } -} - static void reset_stringbuf(void) { stringbuf_idx = 0; @@ -92,7 +98,7 @@ static char* copy_stringbuf(void) { - char *copy = xmalloc(stringbuf_idx); + char *copy = xzalloc(stringbuf_idx + 1); /* terminating NUL */ return memcpy(copy, stringbuf, stringbuf_idx); } @@ -216,8 +222,8 @@ pos = (ptr - module_image); } bksp(); /* remove last ' ' */ - appendc('\0'); info->aliases = copy_stringbuf(); + replace(info->aliases, '-', '_'); /* "dependency1 depandency2" */ reset_stringbuf(); @@ -228,7 +234,6 @@ dbg2_error_msg("dep:'%s'", ptr); append(ptr); } - appendc('\0'); info->deps = copy_stringbuf(); free(module_image); @@ -314,6 +319,7 @@ while ((line = xmalloc_fgetline(fp)) != NULL) { char* space; + char* linebuf; int cur; if (!line[0]) { @@ -328,7 +334,8 @@ if (*space) *space++ = '\0'; modinfo[cur].aliases = space; - modinfo[cur].deps = xmalloc_fgetline(fp) ? : xzalloc(1); + linebuf = xmalloc_fgetline(fp); + modinfo[cur].deps = linebuf ? linebuf : xzalloc(1); if (modinfo[cur].deps[0]) { /* deps are not "", so next line must be empty */ line = xmalloc_fgetline(fp); @@ -377,11 +384,7 @@ FILE *fp; /* We want good error reporting. fdprintf is not good enough. */ - fp = fdopen(fd, "w"); - if (!fp) { - close(fd); - goto err; - } + fp = xfdopen_for_write(fd); i = 0; while (modinfo[i].pathname) { fprintf(fp, "%s%s%s\n" "%s%s\n", @@ -566,6 +569,14 @@ info = find_alias(name); } +// Problem here: there can be more than one module +// for the given alias. For example, +// "pci:v00008086d00007010sv00000000sd00000000bc01sc01i80" matches +// ata_piix because it has an alias "pci:v00008086d00007010sv*sd*bc*sc*i*" +// and ata_generic, it has an alias "alias=pci:v*d*sv*sd*bc01sc01i*" +// Standard modprobe would load them both. +// In this code, find_alias() returns only the first matching module. + /* rmmod? unload it by name */ if (is_rmmod) { if (delete_module(name, O_NONBLOCK | O_EXCL) != 0 @@ -656,7 +667,7 @@ [-b basedirectory] [forced_version] depmod [-n -e -v -q -r -u] [-F kernelsyms] module1.ko module2.ko ... If no arguments (except options) are given, "depmod -a" is assumed. -depmod will output a dependancy list suitable for the modprobe utility. +depmod will output a dependency list suitable for the modprobe utility. Options: -a, --all Probe all modules -A, --quick Only does the work if there's a new module @@ -679,7 +690,7 @@ { struct utsname uts; char applet0 = applet_name[0]; - USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) + IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) /* are we lsmod? -> just dump /proc/modules */ if ('l' == applet0) { @@ -773,10 +784,10 @@ len = MAXINT(ssize_t); map = xmalloc_xopen_read_close(*argv, &len); if (init_module(map, len, - USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(options ? options : "") - SKIP_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE("") + IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(options ? options : "") + IF_NOT_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE("") ) != 0) - bb_error_msg_and_die("cannot insert '%s': %s", + bb_error_msg_and_die("can't insert '%s': %s", *argv, moderror(errno)); return 0; } @@ -791,7 +802,7 @@ } while (*argv); if (ENABLE_FEATURE_CLEAN_UP) { - USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);) + IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);) } return EXIT_SUCCESS; }