diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-10 14:16:11 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-10 14:16:11 +0000 |
| commit | 0e2c93fc0b5f335d731ff712ce8f42d8616f05b9 (patch) | |
| tree | 76f4627ad76789d4238e3261f2648d1b5652bcb5 /modutils | |
| parent | 7f950a93ffd00cdeda83f06a447943c360005c34 (diff) | |
| download | busybox-w32-0e2c93fc0b5f335d731ff712ce8f42d8616f05b9.tar.gz busybox-w32-0e2c93fc0b5f335d731ff712ce8f42d8616f05b9.tar.bz2 busybox-w32-0e2c93fc0b5f335d731ff712ce8f42d8616f05b9.zip | |
modprobe-small: make depmod compatible with kernel build.
three last commits' sizes combined:
function old new delta
find_alias 218 612 +394
load_dep_bb - 310 +310
modprobe_main 289 380 +91
copy_stringbuf - 40 +40
process_module 637 655 +18
reset_stringbuf - 15 +15
parse_module 333 334 +1
append 84 85 +1
fileAction 832 819 -13
------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 5/1 up/down: 870/-13) Total: 857 bytes
Diffstat (limited to 'modutils')
| -rw-r--r-- | modutils/Config.in | 16 | ||||
| -rw-r--r-- | modutils/modprobe-small.c | 129 |
2 files changed, 106 insertions, 39 deletions
diff --git a/modutils/Config.in b/modutils/Config.in index 2e7f9b6e5..40da1ac7a 100644 --- a/modutils/Config.in +++ b/modutils/Config.in | |||
| @@ -11,23 +11,31 @@ config MODPROBE_SMALL | |||
| 11 | help | 11 | help |
| 12 | Simplified modutils. | 12 | Simplified modutils. |
| 13 | 13 | ||
| 14 | With this option modprobe does not use or require | 14 | With this option modprobe does not require modules.dep file |
| 15 | modules.dep or /etc/modules.conf files. | 15 | and does not use /etc/modules.conf file. |
| 16 | It scans module files in /lib/modules/`uname -r` and | 16 | It scans module files in /lib/modules/`uname -r` and |
| 17 | determines dependencies and module alias names on the fly. | 17 | determines dependencies and module alias names on the fly. |
| 18 | This may make module loading slower, most notably | 18 | This may make module loading slower, most notably |
| 19 | when one needs to load module by alias (this requires | 19 | when one needs to load module by alias (this requires |
| 20 | scanning through module _bodies_). | 20 | scanning through module _bodies_). |
| 21 | 21 | ||
| 22 | At the first attempt to load a module by alias modprobe | ||
| 23 | will try to generate modules.dep.bb file in order to speed up | ||
| 24 | future loads by alias. Failure to do so (read-only /lib/modules, | ||
| 25 | etc) is not reported, and future modprobes will be slow too. | ||
| 26 | |||
| 27 | NB: modules.dep.bb file format is not compatible | ||
| 28 | with modules.dep file as created/used by standard module tools. | ||
| 29 | |||
| 22 | Additional module parameters can be stored in | 30 | Additional module parameters can be stored in |
| 23 | /etc/modules/$module_name files. | 31 | /etc/modules/$module_name files. |
| 24 | 32 | ||
| 25 | Apart from modprobe, other utilities are also provided: | 33 | Apart from modprobe, other utilities are also provided: |
| 26 | - insmod is an alias to modprobe | 34 | - insmod is an alias to modprobe |
| 27 | - rmmod is an alias to modprobe -r | 35 | - rmmod is an alias to modprobe -r |
| 28 | - depmod is provided but does nothing | 36 | - depmod generates modules.dep.bb |
| 29 | 37 | ||
| 30 | As of 2008-07, this code is experimental. It it 15kb smaller | 38 | As of 2008-07, this code is experimental. It it 14kb smaller |
| 31 | than "non-small" modutils. | 39 | than "non-small" modutils. |
| 32 | 40 | ||
| 33 | config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | 41 | config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE |
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index cf9be47a6..f28c42558 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c | |||
| @@ -44,6 +44,7 @@ struct globals { | |||
| 44 | module_info *modinfo; | 44 | module_info *modinfo; |
| 45 | char *module_load_options; | 45 | char *module_load_options; |
| 46 | smallint dep_bb_seen; | 46 | smallint dep_bb_seen; |
| 47 | smallint wrote_dep_bb_ok; | ||
| 47 | int module_count; | 48 | int module_count; |
| 48 | int module_found_idx; | 49 | int module_found_idx; |
| 49 | int stringbuf_idx; | 50 | int stringbuf_idx; |
| @@ -53,6 +54,7 @@ struct globals { | |||
| 53 | #define G (*ptr_to_globals) | 54 | #define G (*ptr_to_globals) |
| 54 | #define modinfo (G.modinfo ) | 55 | #define modinfo (G.modinfo ) |
| 55 | #define dep_bb_seen (G.dep_bb_seen ) | 56 | #define dep_bb_seen (G.dep_bb_seen ) |
| 57 | #define wrote_dep_bb_ok (G.wrote_dep_bb_ok ) | ||
| 56 | #define module_count (G.module_count ) | 58 | #define module_count (G.module_count ) |
| 57 | #define module_found_idx (G.module_found_idx ) | 59 | #define module_found_idx (G.module_found_idx ) |
| 58 | #define module_load_options (G.module_load_options) | 60 | #define module_load_options (G.module_load_options) |
| @@ -236,15 +238,16 @@ static void parse_module(module_info *info, const char *pathname) | |||
| 236 | break; | 238 | break; |
| 237 | /* DOCME: __ksymtab_gpl and __ksymtab_strings occur | 239 | /* DOCME: __ksymtab_gpl and __ksymtab_strings occur |
| 238 | * in many modules. What do they mean? */ | 240 | * in many modules. What do they mean? */ |
| 239 | if (strcmp(ptr, "gpl") != 0 && strcmp(ptr, "strings") != 0) { | 241 | if (strcmp(ptr, "gpl") == 0 || strcmp(ptr, "strings") == 0) |
| 240 | dbg2_error_msg("alias:'symbol:%s'", ptr); | 242 | goto skip; |
| 241 | append("symbol:"); | 243 | dbg2_error_msg("alias:'symbol:%s'", ptr); |
| 242 | } | 244 | append("symbol:"); |
| 243 | } else { | 245 | } else { |
| 244 | dbg2_error_msg("alias:'%s'", ptr); | 246 | dbg2_error_msg("alias:'%s'", ptr); |
| 245 | } | 247 | } |
| 246 | append(ptr); | 248 | append(ptr); |
| 247 | appendc(' '); | 249 | appendc(' '); |
| 250 | skip: | ||
| 248 | pos = (ptr - module_image); | 251 | pos = (ptr - module_image); |
| 249 | } | 252 | } |
| 250 | bksp(); /* remove last ' ' */ | 253 | bksp(); /* remove last ' ' */ |
| @@ -379,6 +382,10 @@ static int start_dep_bb_writeout(void) | |||
| 379 | { | 382 | { |
| 380 | int fd; | 383 | int fd; |
| 381 | 384 | ||
| 385 | /* depmod -n: write result to stdout */ | ||
| 386 | if (applet_name[0] == 'd' && (option_mask32 & 1)) | ||
| 387 | return STDOUT_FILENO; | ||
| 388 | |||
| 382 | fd = open(DEPFILE_BB".new", O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644); | 389 | fd = open(DEPFILE_BB".new", O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644); |
| 383 | if (fd < 0) { | 390 | if (fd < 0) { |
| 384 | if (errno == EEXIST) { | 391 | if (errno == EEXIST) { |
| @@ -421,13 +428,19 @@ static void write_out_dep_bb(int fd) | |||
| 421 | } | 428 | } |
| 422 | /* Badly formatted depfile is a no-no. Be paranoid. */ | 429 | /* Badly formatted depfile is a no-no. Be paranoid. */ |
| 423 | errno = 0; | 430 | errno = 0; |
| 424 | if (ferror(fp) | fclose(fp)) | 431 | if (ferror(fp) | fclose(fp)) /* | instead of || is intended */ |
| 425 | goto err; | 432 | goto err; |
| 433 | |||
| 434 | if (fd == STDOUT_FILENO) /* it was depmod -n */ | ||
| 435 | goto ok; | ||
| 436 | |||
| 426 | if (rename(DEPFILE_BB".new", DEPFILE_BB) != 0) { | 437 | if (rename(DEPFILE_BB".new", DEPFILE_BB) != 0) { |
| 427 | err: | 438 | err: |
| 428 | bb_perror_msg("can't create %s", DEPFILE_BB); | 439 | bb_perror_msg("can't create %s", DEPFILE_BB); |
| 429 | unlink(DEPFILE_BB".new"); | 440 | unlink(DEPFILE_BB".new"); |
| 430 | } else { | 441 | } else { |
| 442 | ok: | ||
| 443 | wrote_dep_bb_ok = 1; | ||
| 431 | dbg1_error_msg("created "DEPFILE_BB); | 444 | dbg1_error_msg("created "DEPFILE_BB); |
| 432 | } | 445 | } |
| 433 | } | 446 | } |
| @@ -525,8 +538,10 @@ static int already_loaded(const char *name) | |||
| 525 | #endif | 538 | #endif |
| 526 | 539 | ||
| 527 | /* | 540 | /* |
| 528 | Given modules definition and module name (or alias, or symbol) | 541 | * Given modules definition and module name (or alias, or symbol) |
| 529 | load/remove the module respecting dependencies | 542 | * load/remove the module respecting dependencies. |
| 543 | * NB: also called by depmod with bogus name "/", | ||
| 544 | * just in order to force modprobe.dep.bb creation. | ||
| 530 | */ | 545 | */ |
| 531 | #if !ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | 546 | #if !ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE |
| 532 | #define process_module(a,b) process_module(a) | 547 | #define process_module(a,b) process_module(a) |
| @@ -605,8 +620,10 @@ static void process_module(char *name, const char *cmdline_options) | |||
| 605 | * will try to remove them, too." */ | 620 | * will try to remove them, too." */ |
| 606 | } | 621 | } |
| 607 | 622 | ||
| 608 | if (!info) { /* both dirscan and find_alias found nothing */ | 623 | if (!info) { |
| 609 | bb_error_msg("module '%s' not found", name); | 624 | /* both dirscan and find_alias found nothing */ |
| 625 | if (applet_name[0] != 'd') /* it wasn't depmod */ | ||
| 626 | bb_error_msg("module '%s' not found", name); | ||
| 610 | //TODO: _and_die()? | 627 | //TODO: _and_die()? |
| 611 | goto ret; | 628 | goto ret; |
| 612 | } | 629 | } |
| @@ -644,39 +661,51 @@ static void process_module(char *name, const char *cmdline_options) | |||
| 644 | #undef cmdline_options | 661 | #undef cmdline_options |
| 645 | 662 | ||
| 646 | 663 | ||
| 647 | /* For reference, module-init-tools-0.9.15-pre2 options: | 664 | /* For reference, module-init-tools v3.4 options: |
| 648 | 665 | ||
| 649 | # insmod | 666 | # insmod |
| 650 | Usage: insmod filename [args] | 667 | Usage: insmod filename [args] |
| 651 | 668 | ||
| 652 | # rmmod --help | 669 | # rmmod --help |
| 653 | Usage: rmmod [-fhswvV] modulename ... | 670 | Usage: rmmod [-fhswvV] modulename ... |
| 654 | -f (or --force) forces a module unload, and may crash your machine. | 671 | -f (or --force) forces a module unload, and may crash your |
| 672 | machine. This requires the Forced Module Removal option | ||
| 673 | when the kernel was compiled. | ||
| 674 | -h (or --help) prints this help text | ||
| 655 | -s (or --syslog) says use syslog, not stderr | 675 | -s (or --syslog) says use syslog, not stderr |
| 656 | -v (or --verbose) enables more messages | 676 | -v (or --verbose) enables more messages |
| 677 | -V (or --version) prints the version code | ||
| 657 | -w (or --wait) begins a module removal even if it is used | 678 | -w (or --wait) begins a module removal even if it is used |
| 658 | and will stop new users from accessing the module (so it | 679 | and will stop new users from accessing the module (so it |
| 659 | should eventually fall to zero). | 680 | should eventually fall to zero). |
| 660 | 681 | ||
| 661 | # modprobe | 682 | # modprobe |
| 662 | Usage: modprobe [--verbose|--version|--config|--remove] filename [options] | 683 | Usage: modprobe [-v] [-V] [-C config-file] [-n] [-i] [-q] [-b] |
| 684 | [-o <modname>] [ --dump-modversions ] <modname> [parameters...] | ||
| 685 | modprobe -r [-n] [-i] [-v] <modulename> ... | ||
| 686 | modprobe -l -t <dirname> [ -a <modulename> ...] | ||
| 663 | 687 | ||
| 664 | # depmod --help | 688 | # depmod --help |
| 665 | depmod 0.9.15-pre2 -- part of module-init-tools | 689 | depmod 3.4 -- part of module-init-tools |
| 666 | depmod -[aA] [-n -e -v -q -V -r -u] [-b basedirectory] [forced_version] | 690 | depmod -[aA] [-n -e -v -q -V -r -u] |
| 667 | depmod [-n -e -v -q -r -u] [-F kernelsyms] module1.o module2.o ... | 691 | [-b basedirectory] [forced_version] |
| 668 | If no arguments (except options) are given, "depmod -a" is assumed | 692 | depmod [-n -e -v -q -r -u] [-F kernelsyms] module1.ko module2.ko ... |
| 669 | 693 | If no arguments (except options) are given, "depmod -a" is assumed. | |
| 670 | depmod will output a dependancy list suitable for the modprobe utility. | 694 | depmod will output a dependancy list suitable for the modprobe utility. |
| 671 | |||
| 672 | Options: | 695 | Options: |
| 673 | -a, --all Probe all modules | 696 | -a, --all Probe all modules |
| 674 | -n, --show Write the dependency file on stdout only | 697 | -A, --quick Only does the work if there's a new module |
| 675 | -b basedirectory | 698 | -n, --show Write the dependency file on stdout only |
| 676 | --basedir basedirectory Use an image of a module tree. | 699 | -e, --errsyms Report not supplied symbols |
| 677 | -F kernelsyms | 700 | -V, --version Print the release version |
| 678 | --filesyms kernelsyms Use the file instead of the | 701 | -v, --verbose Enable verbose mode |
| 679 | current kernel symbols. | 702 | -h, --help Print this usage message |
| 703 | The following options are useful for people managing distributions: | ||
| 704 | -b basedirectory | ||
| 705 | --basedir basedirectory Use an image of a module tree. | ||
| 706 | -F kernelsyms | ||
| 707 | --filesyms kernelsyms Use the file instead of the | ||
| 708 | current kernel symbols. | ||
| 680 | */ | 709 | */ |
| 681 | 710 | ||
| 682 | int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 711 | int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| @@ -686,10 +715,6 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
| 686 | char applet0 = applet_name[0]; | 715 | char applet0 = applet_name[0]; |
| 687 | USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) | 716 | USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) |
| 688 | 717 | ||
| 689 | /* depmod is a stub */ | ||
| 690 | if ('d' == applet0) | ||
| 691 | return EXIT_SUCCESS; | ||
| 692 | |||
| 693 | /* are we lsmod? -> just dump /proc/modules */ | 718 | /* are we lsmod? -> just dump /proc/modules */ |
| 694 | if ('l' == applet0) { | 719 | if ('l' == applet0) { |
| 695 | xprint_and_close_file(xfopen("/proc/modules", "r")); | 720 | xprint_and_close_file(xfopen("/proc/modules", "r")); |
| @@ -698,6 +723,45 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
| 698 | 723 | ||
| 699 | INIT_G(); | 724 | INIT_G(); |
| 700 | 725 | ||
| 726 | /* Prevent ugly corner cases with no modules at all */ | ||
| 727 | modinfo = xzalloc(sizeof(modinfo[0])); | ||
| 728 | |||
| 729 | /* Goto modules directory */ | ||
| 730 | xchdir(CONFIG_DEFAULT_MODULES_DIR); | ||
| 731 | uname(&uts); /* never fails */ | ||
| 732 | |||
| 733 | /* depmod? */ | ||
| 734 | if ('d' == applet0) { | ||
| 735 | /* Supported: | ||
| 736 | * -n: print result to stdout | ||
| 737 | * -a: process all modules (default) | ||
| 738 | * optional VERSION parameter | ||
| 739 | * Ignored: | ||
| 740 | * -A: do work only if a module is newer than depfile | ||
| 741 | * -e: report any symbols which a module needs | ||
| 742 | * which are not supplied by other modules or the kernel | ||
| 743 | * -F FILE: System.map (symbols for -e) | ||
| 744 | * -q, -r, -u: noop? | ||
| 745 | * Not supported: | ||
| 746 | * -b BASEDIR: (TODO!) modules are in | ||
| 747 | * $BASEDIR/lib/modules/$VERSION | ||
| 748 | * -v: human readable deps to stdout | ||
| 749 | * -V: version (don't want to support it - people may depend | ||
| 750 | * on it as an indicator of "standard" depmod) | ||
| 751 | * -h: help (well duh) | ||
| 752 | * module1.o module2.o parameters (just ignored for now) | ||
| 753 | */ | ||
| 754 | getopt32(argv, "na" "AeF:qru" /* "b:vV", NULL */, NULL); | ||
| 755 | argv += optind; | ||
| 756 | /* if (argv[0] && argv[1]) bb_show_usage(); */ | ||
| 757 | /* Goto $VERSION directory */ | ||
| 758 | xchdir(argv[0] ? argv[0] : uts.release); | ||
| 759 | /* Force full module scan by asking to find a bogus module. | ||
| 760 | * This will generate modules.dep.bb as a side effect. */ | ||
| 761 | process_module((char*)"/", NULL); | ||
| 762 | return !wrote_dep_bb_ok; | ||
| 763 | } | ||
| 764 | |||
| 701 | /* insmod, modprobe, rmmod require at least one argument */ | 765 | /* insmod, modprobe, rmmod require at least one argument */ |
| 702 | opt_complementary = "-1"; | 766 | opt_complementary = "-1"; |
| 703 | /* only -q (quiet) and -r (rmmod), | 767 | /* only -q (quiet) and -r (rmmod), |
| @@ -710,9 +774,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
| 710 | option_mask32 |= OPT_r; | 774 | option_mask32 |= OPT_r; |
| 711 | } | 775 | } |
| 712 | 776 | ||
| 713 | /* goto modules directory */ | 777 | /* Goto $VERSION directory */ |
| 714 | xchdir(CONFIG_DEFAULT_MODULES_DIR); | ||
| 715 | uname(&uts); /* never fails */ | ||
| 716 | xchdir(uts.release); | 778 | xchdir(uts.release); |
| 717 | 779 | ||
| 718 | #if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | 780 | #if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE |
| @@ -734,9 +796,6 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
| 734 | argv[1] = NULL; | 796 | argv[1] = NULL; |
| 735 | #endif | 797 | #endif |
| 736 | 798 | ||
| 737 | /* Prevent ugly corner cases with no modules at all */ | ||
| 738 | modinfo = xzalloc(sizeof(modinfo[0])); | ||
| 739 | |||
| 740 | /* Try to load modprobe.dep.bb */ | 799 | /* Try to load modprobe.dep.bb */ |
| 741 | load_dep_bb(); | 800 | load_dep_bb(); |
| 742 | 801 | ||
