summaryrefslogtreecommitdiffstats
path: root/core/busybox
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-02-25 11:04:38 +0200
committerTimo Teras <timo.teras@iki.fi>2009-02-25 11:04:38 +0200
commit34b3831457b38bcff7562d26ce4d21cc83c4771e (patch)
tree39b56a31bf05768e30cb813b7240cafefbf22ad7 /core/busybox
parente6d530f2064b6b25eb36943b1e55cb004e79071f (diff)
downloadaports-34b3831457b38bcff7562d26ce4d21cc83c4771e.tar.bz2
aports-34b3831457b38bcff7562d26ce4d21cc83c4771e.tar.xz
core/busybox: speed up modprobe -a
experimental patch to speed up bootup time.
Diffstat (limited to 'core/busybox')
-rw-r--r--core/busybox/APKBUILD4
-rw-r--r--core/busybox/busybox-1.13.2-modprobe-speedup.patch369
2 files changed, 372 insertions, 1 deletions
diff --git a/core/busybox/APKBUILD b/core/busybox/APKBUILD
index e3080b64..dc3a816d 100644
--- a/core/busybox/APKBUILD
+++ b/core/busybox/APKBUILD
@@ -1,6 +1,6 @@
pkgname=busybox
pkgver=1.13.2
-pkgrel=2
+pkgrel=3
pkgdesc="Size optimized toolbox of many common UNIX utilities"
url=http://busybox.net
license=GPL-2
@@ -12,6 +12,7 @@ source="http://busybox.net/downloads/$pkgname-$pkgver.tar.bz2
busybox-1.13.2-init.patch
busybox-1.13.2-mdev.patch
busybox-1.13.2-modprobe.patch
+ busybox-1.13.2-modprobe-speedup.patch
busybox-1.13.2-tar.patch
busyboxconfig"
@@ -40,5 +41,6 @@ f5a8ae3145aa249868c1a1abc319c228 busybox-1.12.1-vi-path.patch
7afb3a1b474742bc198b3c8450ab9a7e busybox-1.13.2-init.patch
a72d169e9545e26257032e0e367feb95 busybox-1.13.2-mdev.patch
6eeb6efcd71e57082d6654a9a6a368eb busybox-1.13.2-modprobe.patch
+1ef5811b3f60d61c3c5fdc05996c8824 busybox-1.13.2-modprobe-speedup.patch
90d093817855bc63ad16fbb8524f80df busybox-1.13.2-tar.patch
7da47c98607834ca9c47a22bf3fe4b6e busyboxconfig"
diff --git a/core/busybox/busybox-1.13.2-modprobe-speedup.patch b/core/busybox/busybox-1.13.2-modprobe-speedup.patch
new file mode 100644
index 00000000..f94a97ee
--- /dev/null
+++ b/core/busybox/busybox-1.13.2-modprobe-speedup.patch
@@ -0,0 +1,369 @@
+Index: modutils/modprobe.c
+===================================================================
+--- a/modutils/modprobe.c (revision 25448)
++++ b/modutils/modprobe.c (working copy)
+@@ -13,23 +13,23 @@
+ #include <sys/utsname.h>
+ #include <fnmatch.h>
+
+-struct modprobe_option {
++#define MODULE_FLAG_LOADED 0x0001
++#define MODULE_FLAG_EXISTS 0x0002
++#define MODULE_FLAG_BLACKLISTED 0x0004
++
++struct module_entry {
+ char *module;
+- char *option;
++ const char *probe;
++ unsigned int flags;
++ llist_t *aliases;
++ llist_t *options;
++ llist_t *deps;
+ };
+
+ struct modprobe_conf {
+- char probename[MODULE_NAME_LEN];
++ llist_t *db;
++ llist_t *probes;
+ llist_t *options;
+- llist_t *aliases;
+-#if ENABLE_FEATURE_MODPROBE_BLACKLIST
+-#define add_to_blacklist(conf, name) llist_add_to(&conf->blacklist, name)
+-#define check_blacklist(conf, name) (llist_find(conf->blacklist, name) == NULL)
+- llist_t *blacklist;
+-#else
+-#define add_to_blacklist(conf, name) do {} while (0)
+-#define check_blacklist(conf, name) (1)
+-#endif
+ };
+
+ #define MODPROBE_OPTS "acdlnrt:VC:" USE_FEATURE_MODPROBE_BLACKLIST("b")
+@@ -46,21 +46,40 @@
+ MODPROBE_OPT_BLACKLIST = (INSMOD_OPT_UNUSED << 9) * ENABLE_FEATURE_MODPROBE_BLACKLIST,
+ };
+
+-static llist_t *loaded;
+-
+ static int read_config(struct modprobe_conf *conf, const char *path);
+
+-static void add_option(llist_t **all_opts, const char *module, const char *opts)
++static struct module_entry *get_module(llist_t **db, const char *module)
+ {
+- struct modprobe_option *o;
++ char modname[MODULE_NAME_LEN];
++ struct module_entry *e;
++ llist_t *l;
+
+- o = xzalloc(sizeof(struct modprobe_option));
+- if (module)
+- o->module = filename2modname(module, NULL);
+- o->option = xstrdup(opts);
+- llist_add_to(all_opts, o);
++ filename2modname(module, modname);
++ for (l = *db; l != NULL; l = l->link) {
++ e = (struct module_entry *) l->data;
++ if (strcmp(e->module, modname) == 0)
++ return e;
++ }
++
++ e = xzalloc(sizeof(*e));
++ e->module = xstrdup(modname);
++ llist_add_to(db, e);
++
++ return e;
+ }
+
++static struct module_entry *add_probe(struct modprobe_conf *conf,
++ const char *name)
++{
++ struct module_entry *m;
++
++ m = get_module(&conf->db, name);
++ m->probe = name;
++ llist_add_to(&conf->probes, m);
++
++ return m;
++}
++
+ static int FAST_FUNC config_file_action(const char *filename,
+ struct stat *statbuf UNUSED_PARAM,
+ void *userdata,
+@@ -70,6 +89,8 @@
+ RESERVE_CONFIG_BUFFER(modname, MODULE_NAME_LEN);
+ char *tokens[3];
+ parser_t *p;
++ llist_t *l;
++ struct module_entry *m;
+ int rc = TRUE;
+
+ if (bb_basename(filename)[0] == '.')
+@@ -84,18 +105,27 @@
+ while (config_read(p, tokens, 3, 2, "# \t", PARSE_NORMAL)) {
+ if (strcmp(tokens[0], "alias") == 0) {
+ filename2modname(tokens[1], modname);
+- if (tokens[2] &&
+- fnmatch(modname, conf->probename, 0) == 0)
+- llist_add_to(&conf->aliases,
+- filename2modname(tokens[2], NULL));
++ if (tokens[2] == NULL)
++ continue;
++
++ for (l = conf->probes; l != NULL; l = l->link) {
++ m = (struct module_entry *) l->data;
++ if (fnmatch(modname, m->module, 0) != 0)
++ continue;
++ llist_add_to(&m->aliases,
++ filename2modname(tokens[2], NULL));
++ }
+ } else if (strcmp(tokens[0], "options") == 0) {
+- if (tokens[2])
+- add_option(&conf->options, tokens[1], tokens[2]);
++ if (tokens[2] == NULL)
++ continue;
++ m = get_module(&conf->db, tokens[1]);
++ llist_add_to(&m->options, xstrdup(tokens[2]));
+ } else if (strcmp(tokens[0], "include") == 0) {
+ read_config(conf, tokens[1]);
+ } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST &&
+ strcmp(tokens[0], "blacklist") == 0) {
+- add_to_blacklist(conf, xstrdup(tokens[1]));
++ get_module(&conf->db, tokens[1])->flags
++ |= MODULE_FLAG_BLACKLISTED;
+ }
+ }
+ config_close(p);
+@@ -111,74 +141,48 @@
+ config_file_action, NULL, conf, 1);
+ }
+
+-static char *gather_options(llist_t *first, const char *module, int usecmdline)
++static char *gather_options(char *opts, llist_t *o)
+ {
+- struct modprobe_option *opt;
+- llist_t *n;
+- char *opts = xstrdup("");
+- int optlen = 0;
++ int optlen;
+
+- for (n = first; n != NULL; n = n->link) {
+- opt = (struct modprobe_option *) n->data;
++ if (opts == NULL)
++ opts = xstrdup("");
++ optlen = strlen(opts);
+
+- if (opt->module == NULL && !usecmdline)
+- continue;
+- if (opt->module != NULL && strcmp(opt->module, module) != 0)
+- continue;
+-
+- opts = xrealloc(opts, optlen + strlen(opt->option) + 2);
+- optlen += sprintf(opts + optlen, "%s ", opt->option);
++ for (; o != NULL; o = o->link) {
++ opts = xrealloc(opts, optlen + strlen(o->data) + 2);
++ optlen += sprintf(opts + optlen, "%s ", o->data);
+ }
+ return opts;
+ }
+
+-static int do_modprobe(struct modprobe_conf *conf, const char *module)
++static int do_modprobe(struct modprobe_conf *conf, struct module_entry *m)
+ {
+- RESERVE_CONFIG_BUFFER(modname, MODULE_NAME_LEN);
+- llist_t *deps = NULL;
+- char *fn, *options, *colon = NULL, *tokens[2];
+- parser_t *p;
++ struct module_entry *m2;
++ char *fn, *options;
+ int rc = -1;
+
+- p = config_open2(CONFIG_DEFAULT_DEPMOD_FILE, fopen_for_read);
+- if (p == NULL)
+- goto error;
++ if (!(m->flags & MODULE_FLAG_EXISTS))
++ return -ENOENT;
+
+- while (config_read(p, tokens, 2, 1, "# \t", PARSE_NORMAL)) {
+- colon = last_char_is(tokens[0], ':');
+- if (colon == NULL)
+- continue;
+-
+- filename2modname(tokens[0], modname);
+- if (strcmp(modname, module) == 0)
+- break;
+-
+- colon = NULL;
+- }
+- if (colon == NULL)
+- goto error_not_found;
+-
+- colon[0] = '\0';
+- llist_add_to(&deps, xstrdup(tokens[0]));
+- if (tokens[1])
+- string_to_llist(tokens[1], &deps, " ");
+-
+ if (!(option_mask32 & MODPROBE_OPT_REMOVE))
+- deps = llist_rev(deps);
++ m->deps = llist_rev(m->deps);
+
+ rc = 0;
+- while (deps && rc == 0) {
+- fn = llist_pop(&deps);
+- filename2modname(fn, modname);
++ while (m->deps && rc == 0) {
++ fn = llist_pop(&m->deps);
++ m2 = get_module(&conf->db, fn);
+ if (option_mask32 & MODPROBE_OPT_REMOVE) {
+- if (bb_delete_module(modname, O_EXCL) != 0)
++ if (bb_delete_module(m->module, O_EXCL) != 0)
+ rc = errno;
+- } else if (llist_find(loaded, modname) == NULL) {
+- options = gather_options(conf->options, modname,
+- strcmp(modname, module) == 0);
++ } else if (!(m2->flags & MODULE_FLAG_LOADED)) {
++ options = gather_options(NULL, m2->options);
++ if (m == m2)
++ options = gather_options(options,
++ conf->options);
+ rc = bb_init_module(fn, options);
+ if (rc == 0)
+- llist_add_to(&loaded, xstrdup(modname));
++ m2->flags |= MODULE_FLAG_LOADED;
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(options);
+ }
+@@ -187,15 +191,10 @@
+ free(fn);
+ }
+
+-error_not_found:
+- config_close(p);
+-error:
+- if (ENABLE_FEATURE_CLEAN_UP)
+- RELEASE_CONFIG_BUFFER(modname);
+ if (rc > 0 && !(option_mask32 & INSMOD_OPT_SILENT))
+ bb_error_msg("Failed to %sload module %s: %s.",
+ (option_mask32 & MODPROBE_OPT_REMOVE) ? "un" : "",
+- module, moderror(rc));
++ m->probe ? m->probe : m->module, moderror(rc));
+ return rc;
+ }
+
+@@ -205,7 +204,8 @@
+ struct utsname uts;
+ int rc;
+ unsigned opt;
+- llist_t *options = NULL;
++ struct modprobe_conf conf;
++ struct module_entry *m, *m2;
+
+ opt_complementary = "q-v:v-q";
+ opt = getopt32(argv, INSMOD_OPTS MODPROBE_OPTS INSMOD_ARGS,
+@@ -228,11 +228,17 @@
+ }
+ return EXIT_SUCCESS;
+ }
+- if (!(opt & MODPROBE_OPT_INSERT_ALL)) {
+- /* If not -a, we have only one module name,
+- * the rest of parameters are options */
+- add_option(&options, NULL, parse_cmdline_module_options(argv));
+- argv[1] = NULL;
++
++ memset(&conf, 0, sizeof(conf));
++ if (opt & MODPROBE_OPT_INSERT_ALL) {
++ /* Each argument is a module name */
++ for (; *argv != NULL; argv++)
++ add_probe(&conf, *argv);
++ conf.probes = llist_rev(conf.probes);
++ } else {
++ /* First argument is module name, rest are parameters */
++ m = add_probe(&conf, argv[0]);
++ llist_add_to(&conf.options, parse_cmdline_module_options(argv));
+ }
+
+ /* cache modules */
+@@ -240,49 +246,59 @@
+ char *s;
+ parser_t *parser = config_open2("/proc/modules", fopen_for_read);
+ while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY))
+- llist_add_to(&loaded, xstrdup(s));
++ get_module(&conf.db, s)->flags |= MODULE_FLAG_LOADED;
+ config_close(parser);
+ }
+
+- while (*argv) {
+- const char *arg = *argv;
+- struct modprobe_conf *conf;
++ read_config(&conf, "/etc/modprobe.conf");
++ read_config(&conf, "/etc/modprobe.d");
++ if (ENABLE_FEATURE_MODUTILS_SYMBOLS)
++ read_config(&conf, "modules.symbols");
++ if (ENABLE_FEATURE_MODUTILS_ALIAS)
++ read_config(&conf, "modules.alias");
+
+- conf = xzalloc(sizeof(*conf));
+- conf->options = options;
+- filename2modname(arg, conf->probename);
+- read_config(conf, "/etc/modprobe.conf");
+- read_config(conf, "/etc/modprobe.d");
+- if (ENABLE_FEATURE_MODUTILS_SYMBOLS
+- && conf->aliases == NULL
+- && strncmp(arg, "symbol:", 7) == 0
+- ) {
+- read_config(conf, "modules.symbols");
++ {
++ parser_t *p;
++ char *colon, *tokens[2];
++
++ p = config_open2(CONFIG_DEFAULT_DEPMOD_FILE, xfopen_for_read);
++ while (config_read(p, tokens, 2, 1, "# \t", PARSE_NORMAL)) {
++ colon = last_char_is(tokens[0], ':');
++ if (colon == NULL)
++ continue;
++ *colon = 0;
++
++ m = get_module(&conf.db, tokens[0]);
++ m->flags |= MODULE_FLAG_EXISTS;
++ llist_add_to(&m->deps, xstrdup(tokens[0]));
++ if (tokens[1])
++ string_to_llist(tokens[1], &m->deps, " ");
+ }
++ config_close(p);
++ }
+
+- if (ENABLE_FEATURE_MODUTILS_ALIAS && conf->aliases == NULL)
+- read_config(conf, "modules.alias");
+-
+- if (conf->aliases == NULL) {
++ while ((m = llist_pop(&conf.probes)) != NULL) {
++ if (m->aliases == NULL) {
+ /* Try if module by literal name is found; literal
+ * names are blacklist only if '-b' is given. */
+ if (!(opt & MODPROBE_OPT_BLACKLIST) ||
+- check_blacklist(conf, conf->probename)) {
+- rc = do_modprobe(conf, conf->probename);
++ !(m->flags & MODULE_FLAG_BLACKLISTED)) {
++ rc = do_modprobe(&conf, m);
+ if (rc < 0 && !(opt & INSMOD_OPT_SILENT))
+- bb_error_msg("Module %s not found.", arg);
++ bb_error_msg("module %s not found",
++ m->probe);
+ }
+ } else {
+ /* Probe all aliases */
+- while (conf->aliases != NULL) {
+- char *realname = llist_pop(&conf->aliases);
+- if (check_blacklist(conf, realname))
+- do_modprobe(conf, realname);
++ while (m->aliases != NULL) {
++ char *realname = llist_pop(&m->aliases);
++ m2 = get_module(&conf.db, realname);
++ if (!(m2->flags & MODULE_FLAG_BLACKLISTED))
++ do_modprobe(&conf, m2);
+ if (ENABLE_FEATURE_CLEAN_UP)
+ free(realname);
+ }
+ }
+- argv++;
+ }
+
+ return EXIT_SUCCESS;