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 | |
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
-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 | ||