Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/modutils/modprobe.c
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/modutils/modprobe.c
r2725 r3232 9 9 */ 10 10 11 //applet:IF_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_DROP)) 11 //applet:IF_MODPROBE(APPLET(modprobe, BB_DIR_SBIN, BB_SUID_DROP)) 12 13 #include "libbb.h" 14 #include "modutils.h" 15 #include <sys/utsname.h> 16 #include <fnmatch.h> 17 18 //#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) 19 #define DBG(...) ((void)0) 20 21 /* Note that unlike older versions of modules.dep/depmod (busybox and m-i-t), 22 * we expect the full dependency list to be specified in modules.dep. 23 * Older versions would only export the direct dependency list. 24 */ 25 12 26 13 27 //usage:#if !ENABLE_MODPROBE_SMALL … … 73 87 //usage: 74 88 //usage:#define modprobe_trivial_usage 75 //usage: "[-alrqvs" 76 //usage: IF_FEATURE_MODPROBE_BLACKLIST("b") 77 //usage: "] MODULE [symbol=value]..." 89 //usage: "[-alrqvsD" IF_FEATURE_MODPROBE_BLACKLIST("b") "]" 90 //usage: " MODULE [symbol=value]..." 78 91 //usage:#define modprobe_full_usage "\n\n" 79 //usage: "Options:" 80 //usage: "\n -a Load multiple MODULEs" 92 //usage: " -a Load multiple MODULEs" 81 93 //usage: "\n -l List (MODULE is a pattern)" 82 94 //usage: "\n -r Remove MODULE (stacks) or do autoclean" … … 84 96 //usage: "\n -v Verbose" 85 97 //usage: "\n -s Log to syslog" 98 //usage: "\n -D Show dependencies" 86 99 //usage: IF_FEATURE_MODPROBE_BLACKLIST( 87 100 //usage: "\n -b Apply blacklist to module names too" … … 89 102 //usage:#endif /* !ENABLE_MODPROBE_SMALL */ 90 103 91 #include "libbb.h" 92 #include "modutils.h" 93 #include <sys/utsname.h> 94 #include <fnmatch.h> 95 96 //#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) 97 #define DBG(...) ((void)0) 98 99 /* Note that unlike older versions of modules.dep/depmod (busybox and m-i-t), 100 * we expect the full dependency list to be specified in modules.dep. 101 * Older versions would only export the direct dependency list. 104 /* Note: usage text doesn't document various 2.4 options 105 * we pull in through INSMOD_OPTS define 106 * Note2: -b is always accepted, but if !FEATURE_MODPROBE_BLACKLIST, 107 * it is a no-op. 102 108 */ 103 104 /* Note that usage text doesn't document various 2.4 options 105 * we pull in through INSMOD_OPTS define */ 106 107 #define MODPROBE_COMPLEMENTARY "q-v:v-q:l--ar:a--lr:r--al" 108 #define MODPROBE_OPTS "alr" IF_FEATURE_MODPROBE_BLACKLIST("b") 109 #define MODPROBE_OPTS "alrDb" 110 /* -a and -D _are_ in fact compatible */ 111 #define MODPROBE_COMPLEMENTARY ("q-v:v-q:l--arD:r--alD:a--lr:D--rl") 112 //#define MODPROBE_OPTS "acd:lnrt:C:b" 109 113 //#define MODPROBE_COMPLEMENTARY "q-v:v-q:l--acr:a--lr:r--al" 110 //#define MODPROBE_OPTS "acd:lnrt:C:" IF_FEATURE_MODPROBE_BLACKLIST("b")111 114 enum { 112 MODPROBE_OPT_INSERT_ALL = (INSMOD_OPT_UNUSED << 0), /* a */ 113 //MODPROBE_OPT_DUMP_ONLY= (INSMOD_OPT_UNUSED << x), /* c */ 114 //MODPROBE_OPT_DIRNAME = (INSMOD_OPT_UNUSED << x), /* d */ 115 MODPROBE_OPT_LIST_ONLY = (INSMOD_OPT_UNUSED << 1), /* l */ 116 //MODPROBE_OPT_SHOW_ONLY= (INSMOD_OPT_UNUSED << x), /* n */ 117 MODPROBE_OPT_REMOVE = (INSMOD_OPT_UNUSED << 2), /* r */ 118 //MODPROBE_OPT_RESTRICT = (INSMOD_OPT_UNUSED << x), /* t */ 119 //MODPROBE_OPT_VERONLY = (INSMOD_OPT_UNUSED << x), /* V */ 120 //MODPROBE_OPT_CONFIGFILE=(INSMOD_OPT_UNUSED << x), /* C */ 121 MODPROBE_OPT_BLACKLIST = (INSMOD_OPT_UNUSED << 3) * ENABLE_FEATURE_MODPROBE_BLACKLIST, 115 OPT_INSERT_ALL = (INSMOD_OPT_UNUSED << 0), /* a */ 116 //OPT_DUMP_ONLY = (INSMOD_OPT_UNUSED << x), /* c */ 117 //OPT_DIRNAME = (INSMOD_OPT_UNUSED << x), /* d */ 118 OPT_LIST_ONLY = (INSMOD_OPT_UNUSED << 1), /* l */ 119 //OPT_SHOW_ONLY = (INSMOD_OPT_UNUSED << x), /* n */ 120 OPT_REMOVE = (INSMOD_OPT_UNUSED << 2), /* r */ 121 //OPT_RESTRICT = (INSMOD_OPT_UNUSED << x), /* t */ 122 //OPT_VERONLY = (INSMOD_OPT_UNUSED << x), /* V */ 123 //OPT_CONFIGFILE = (INSMOD_OPT_UNUSED << x), /* C */ 124 OPT_SHOW_DEPS = (INSMOD_OPT_UNUSED << 3), /* D */ 125 OPT_BLACKLIST = (INSMOD_OPT_UNUSED << 4) * ENABLE_FEATURE_MODPROBE_BLACKLIST, 122 126 }; 127 #if ENABLE_LONG_OPTS 128 static const char modprobe_longopts[] ALIGN1 = 129 /* nobody asked for long opts (yet) */ 130 // "all\0" No_argument "a" 131 // "list\0" No_argument "l" 132 // "remove\0" No_argument "r" 133 // "quiet\0" No_argument "q" 134 // "verbose\0" No_argument "v" 135 // "syslog\0" No_argument "s" 136 /* module-init-tools 3.11.1 has only long opt --show-depends 137 * but no short -D, we provide long opt for scripts which 138 * were written for 3.11.1: */ 139 "show-depends\0" No_argument "D" 140 // "use-blacklist\0" No_argument "b" 141 ; 142 #endif 123 143 124 144 #define MODULE_FLAG_LOADED 0x0001 … … 139 159 }; 140 160 161 #define DB_HASH_SIZE 256 162 141 163 struct globals { 142 llist_t *db; /* MEs of all modules ever seen (caching for speed) */143 164 llist_t *probes; /* MEs of module(s) requested on cmdline */ 144 165 char *cmdline_mopts; /* module options from cmdline */ … … 146 167 /* bool. "Did we have 'symbol:FOO' requested on cmdline?" */ 147 168 smallint need_symbols; 169 struct utsname uts; 170 llist_t *db[DB_HASH_SIZE]; /* MEs of all modules ever seen (caching for speed) */ 148 171 } FIX_ALIASING; 149 #define G (*(struct globals*)&bb_common_bufsiz1) 150 #define INIT_G() do { } while (0) 172 #define G (*ptr_to_globals) 173 #define INIT_G() do { \ 174 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 175 } while (0) 151 176 152 177 … … 168 193 } 169 194 195 /* These three functions called many times, optimizing for speed. 196 * Users reported minute-long delays when they runn iptables repeatedly 197 * (iptables use modprobe to install needed kernel modules). 198 */ 170 199 static struct module_entry *helper_get_module(const char *module, int create) 171 200 { … … 173 202 struct module_entry *e; 174 203 llist_t *l; 204 unsigned i; 205 unsigned hash; 175 206 176 207 filename2modname(module, modname); 177 for (l = G.db; l != NULL; l = l->link) { 208 209 hash = 0; 210 for (i = 0; modname[i]; i++) 211 hash = ((hash << 5) + hash) + modname[i]; 212 hash %= DB_HASH_SIZE; 213 214 for (l = G.db[hash]; l; l = l->link) { 178 215 e = (struct module_entry *) l->data; 179 216 if (strcmp(e->modname, modname) == 0) … … 185 222 e = xzalloc(sizeof(*e)); 186 223 e->modname = xstrdup(modname); 187 llist_add_to(&G.db , e);224 llist_add_to(&G.db[hash], e); 188 225 189 226 return e; 190 227 } 191 static struct module_entry *get_or_add_modentry(const char *module)228 static ALWAYS_INLINE struct module_entry *get_or_add_modentry(const char *module) 192 229 { 193 230 return helper_get_module(module, 1); 194 231 } 195 static struct module_entry *get_modentry(const char *module)232 static ALWAYS_INLINE struct module_entry *get_modentry(const char *module) 196 233 { 197 234 return helper_get_module(module, 0); … … 203 240 204 241 m = get_or_add_modentry(name); 205 if (!(option_mask32 & MODPROBE_OPT_REMOVE)242 if (!(option_mask32 & (OPT_REMOVE | OPT_SHOW_DEPS)) 206 243 && (m->flags & MODULE_FLAG_LOADED) 207 244 ) { … … 253 290 filename2modname(tokens[1], wildcard); 254 291 255 for (l = G.probes; l != NULL; l = l->link) {292 for (l = G.probes; l; l = l->link) { 256 293 m = (struct module_entry *) l->data; 257 294 if (fnmatch(wildcard, m->modname, 0) != 0) … … 354 391 static int do_modprobe(struct module_entry *m) 355 392 { 356 struct module_entry *m2 = m2; /* for compiler */357 char *fn, *options;358 393 int rc, first; 359 llist_t *l;360 394 361 395 if (!(m->flags & MODULE_FLAG_FOUND_IN_MODDEP)) { … … 367 401 DBG("do_modprob'ing %s", m->modname); 368 402 369 if (!(option_mask32 & MODPROBE_OPT_REMOVE))403 if (!(option_mask32 & OPT_REMOVE)) 370 404 m->deps = llist_rev(m->deps); 371 405 372 for (l = m->deps; l != NULL; l = l->link) 373 DBG("dep: %s", l->data); 406 if (0) { 407 llist_t *l; 408 for (l = m->deps; l; l = l->link) 409 DBG("dep: %s", l->data); 410 } 374 411 375 412 first = 1; 376 413 rc = 0; 377 414 while (m->deps) { 415 struct module_entry *m2; 416 char *fn, *options; 417 378 418 rc = 0; 379 419 fn = llist_pop(&m->deps); /* we leak it */ 380 420 m2 = get_or_add_modentry(fn); 381 421 382 if (option_mask32 & MODPROBE_OPT_REMOVE) {422 if (option_mask32 & OPT_REMOVE) { 383 423 /* modprobe -r */ 384 424 if (m2->flags & MODULE_FLAG_LOADED) { … … 400 440 } 401 441 402 if (m2->flags & MODULE_FLAG_LOADED) {403 DBG("%s is already loaded, skipping", fn);404 continue;405 }406 407 442 options = m2->options; 408 443 m2->options = NULL; … … 410 445 if (m == m2) 411 446 options = gather_options_str(options, G.cmdline_mopts); 447 448 if (option_mask32 & OPT_SHOW_DEPS) { 449 printf(options ? "insmod %s/%s/%s %s\n" 450 : "insmod %s/%s/%s\n", 451 CONFIG_DEFAULT_MODULES_DIR, G.uts.release, fn, 452 options); 453 free(options); 454 continue; 455 } 456 457 if (m2->flags & MODULE_FLAG_LOADED) { 458 DBG("%s is already loaded, skipping", fn); 459 free(options); 460 continue; 461 } 462 412 463 rc = bb_init_module(fn, options); 413 464 DBG("loaded %s '%s', rc:%d", fn, options, rc); … … 457 508 /* Optimization... */ 458 509 if ((m->flags & MODULE_FLAG_LOADED) 459 && !(option_mask32 & MODPROBE_OPT_REMOVE)510 && !(option_mask32 & (OPT_REMOVE | OPT_SHOW_DEPS)) 460 511 ) { 461 512 DBG("skip deps of %s, it's already loaded", tokens[0]); … … 478 529 int modprobe_main(int argc UNUSED_PARAM, char **argv) 479 530 { 480 struct utsname uts;481 531 int rc; 482 532 unsigned opt; 483 533 struct module_entry *me; 484 534 535 INIT_G(); 536 537 IF_LONG_OPTS(applet_long_options = modprobe_longopts;) 485 538 opt_complementary = MODPROBE_COMPLEMENTARY; 486 539 opt = getopt32(argv, INSMOD_OPTS MODPROBE_OPTS INSMOD_ARGS); … … 489 542 /* Goto modules location */ 490 543 xchdir(CONFIG_DEFAULT_MODULES_DIR); 491 uname(&uts); 492 xchdir(uts.release); 493 494 if (opt & MODPROBE_OPT_LIST_ONLY) { 544 uname(&G.uts); 545 xchdir(G.uts.release); 546 547 if (opt & OPT_LIST_ONLY) { 548 int i; 495 549 char name[MODULE_NAME_LEN]; 496 550 char *colon, *tokens[2]; 497 551 parser_t *p = config_open2(CONFIG_DEFAULT_DEPMOD_FILE, xfopen_for_read); 552 553 for (i = 0; argv[i]; i++) 554 replace(argv[i], '-', '_'); 498 555 499 556 while (config_read(p, tokens, 2, 1, "# \t", PARSE_NORMAL)) { … … 506 563 puts(tokens[0]); 507 564 else { 508 int i;509 565 for (i = 0; argv[i]; i++) { 510 566 if (fnmatch(argv[i], name, 0) == 0) { … … 522 578 523 579 if (!argv[0]) { 524 if (opt & MODPROBE_OPT_REMOVE) {580 if (opt & OPT_REMOVE) { 525 581 /* "modprobe -r" (w/o params). 526 582 * "If name is NULL, all unused modules marked … … 542 598 } 543 599 544 if (opt & ( MODPROBE_OPT_INSERT_ALL | MODPROBE_OPT_REMOVE)) {600 if (opt & (OPT_INSERT_ALL | OPT_REMOVE)) { 545 601 /* Each argument is a module name */ 546 602 do { … … 552 608 DBG("probing just module %s", *argv); 553 609 add_probe(argv[0]); 554 G.cmdline_mopts = parse_cmdline_module_options(argv );610 G.cmdline_mopts = parse_cmdline_module_options(argv, /*quote_spaces:*/ 1); 555 611 } 556 612 … … 576 632 * only if '-b' is given. 577 633 */ 578 if (!(opt & MODPROBE_OPT_BLACKLIST)634 if (!(opt & OPT_BLACKLIST) 579 635 || !(me->flags & MODULE_FLAG_BLACKLISTED) 580 636 ) { … … 593 649 if (!(m2->flags & MODULE_FLAG_BLACKLISTED) 594 650 && (!(m2->flags & MODULE_FLAG_LOADED) 595 || (opt & MODPROBE_OPT_REMOVE))651 || (opt & (OPT_REMOVE | OPT_SHOW_DEPS))) 596 652 ) { 597 653 //TODO: we can pass "me" as 2nd param to do_modprobe,
Note:
See TracChangeset
for help on using the changeset viewer.