aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2015-02-07 20:44:46 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2015-02-07 20:44:46 +0100
commit68c048fb23bd8b0831bbd02ec66900b12390cf19 (patch)
treec0180ca96c35db0779232b028b316f40b4ae2d15
parent782ee2aa0e1646aebc96c8590ddc0a16405b8297 (diff)
downloadbusybox-w32-68c048fb23bd8b0831bbd02ec66900b12390cf19.tar.gz
busybox-w32-68c048fb23bd8b0831bbd02ec66900b12390cf19.tar.bz2
busybox-w32-68c048fb23bd8b0831bbd02ec66900b12390cf19.zip
modprobe-small: fix and simplify rmmod
"rmmod OUT_OF_TREE_MODULE" was not working, because module is not in depmod file. In general, rmmod doesn't need scanning, it simply unloads every argv[i]. function old new delta rmmod - 63 +63 modprobe_main 449 465 +16 process_module 705 667 -38 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/1 up/down: 79/-38) Total: 41 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--modutils/modprobe-small.c75
1 files changed, 43 insertions, 32 deletions
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c
index cafbdc0b2..6b0a4400c 100644
--- a/modutils/modprobe-small.c
+++ b/modutils/modprobe-small.c
@@ -549,9 +549,23 @@ static int already_loaded(const char *name)
549 return ret; 549 return ret;
550} 550}
551#else 551#else
552#define already_loaded(name) is_rmmod 552#define already_loaded(name) 0
553#endif 553#endif
554 554
555static int rmmod(const char *filename)
556{
557 int r;
558 char modname[MODULE_NAME_LEN];
559
560 filename2modname(filename, modname);
561 r = delete_module(modname, O_NONBLOCK | O_EXCL);
562 dbg1_error_msg("delete_module('%s', O_NONBLOCK | O_EXCL):%d", modname, r);
563 if (r != 0 && !(option_mask32 & OPT_q)) {
564 bb_perror_msg("remove '%s'", modname);
565 }
566 return r;
567}
568
555/* 569/*
556 * Given modules definition and module name (or alias, or symbol) 570 * Given modules definition and module name (or alias, or symbol)
557 * load/remove the module respecting dependencies. 571 * load/remove the module respecting dependencies.
@@ -568,26 +582,36 @@ static void process_module(char *name, const char *cmdline_options)
568 module_info **infovec; 582 module_info **infovec;
569 module_info *info; 583 module_info *info;
570 int infoidx; 584 int infoidx;
571 int is_rmmod = (option_mask32 & OPT_r) != 0; 585 int is_remove = (option_mask32 & OPT_r) != 0;
572 586
573 dbg1_error_msg("process_module('%s','%s')", name, cmdline_options); 587 dbg1_error_msg("process_module('%s','%s')", name, cmdline_options);
574 588
575 replace(name, '-', '_'); 589 replace(name, '-', '_');
576 590
577 dbg1_error_msg("already_loaded:%d is_rmmod:%d", already_loaded(name), is_rmmod); 591 dbg1_error_msg("already_loaded:%d is_remove:%d", already_loaded(name), is_remove);
592
593 if (applet_name[0] == 'r') {
594 /* rmmod.
595 * Does not remove dependencies, no need to scan, just remove.
596 * (compat note: this allows and strips .ko suffix)
597 */
598 rmmod(name);
599 return;
600 }
601
578 /* 602 /*
579 * We used to have "is_rmmod != already_loaded(name)" check here, but 603 * We used to have "is_remove != already_loaded(name)" check here, but
580 * modprobe -r pci:v00008086d00007010sv00000000sd00000000bc01sc01i80 604 * modprobe -r pci:v00008086d00007010sv00000000sd00000000bc01sc01i80
581 * won't unload modules (there are more than one) 605 * won't unload modules (there are more than one)
582 * which have this alias. 606 * which have this alias.
583 */ 607 */
584 if (!is_rmmod && already_loaded(name)) { 608 if (!is_remove && already_loaded(name)) {
585 dbg1_error_msg("nothing to do for '%s'", name); 609 dbg1_error_msg("nothing to do for '%s'", name);
586 return; 610 return;
587 } 611 }
588 612
589 options = NULL; 613 options = NULL;
590 if (!is_rmmod) { 614 if (!is_remove) {
591 char *opt_filename = xasprintf("/etc/modules/%s", name); 615 char *opt_filename = xasprintf("/etc/modules/%s", name);
592 options = xmalloc_open_read_close(opt_filename, NULL); 616 options = xmalloc_open_read_close(opt_filename, NULL);
593 if (options) 617 if (options)
@@ -621,7 +645,7 @@ static void process_module(char *name, const char *cmdline_options)
621 0 /* depth */ 645 0 /* depth */
622 ); 646 );
623 dbg1_error_msg("dirscan complete"); 647 dbg1_error_msg("dirscan complete");
624 /* Module was not found, or load failed, or is_rmmod */ 648 /* Module was not found, or load failed, or is_remove */
625 if (module_found_idx >= 0) { /* module was found */ 649 if (module_found_idx >= 0) { /* module was found */
626 infovec = xzalloc(2 * sizeof(infovec[0])); 650 infovec = xzalloc(2 * sizeof(infovec[0]));
627 infovec[0] = &modinfo[module_found_idx]; 651 infovec[0] = &modinfo[module_found_idx];
@@ -634,7 +658,7 @@ static void process_module(char *name, const char *cmdline_options)
634 658
635 if (!infovec) { 659 if (!infovec) {
636 /* both dirscan and find_alias found nothing */ 660 /* both dirscan and find_alias found nothing */
637 if (!is_rmmod && applet_name[0] != 'd') /* it wasn't rmmod or depmod */ 661 if (!is_remove && applet_name[0] != 'd') /* it wasn't rmmod or depmod */
638 bb_error_msg("module '%s' not found", name); 662 bb_error_msg("module '%s' not found", name);
639//TODO: _and_die()? or should we continue (un)loading modules listed on cmdline? 663//TODO: _and_die()? or should we continue (un)loading modules listed on cmdline?
640 goto ret; 664 goto ret;
@@ -648,29 +672,15 @@ static void process_module(char *name, const char *cmdline_options)
648 * a *list* of modinfo pointers from find_alias(). 672 * a *list* of modinfo pointers from find_alias().
649 */ 673 */
650 674
651 /* rmmod or modprobe -r? unload module(s) */ 675 /* modprobe -r? unload module(s) */
652 if (is_rmmod) { 676 if (is_remove) {
653 infoidx = 0; 677 infoidx = 0;
654 while ((info = infovec[infoidx++]) != NULL) { 678 while ((info = infovec[infoidx++]) != NULL) {
655 int r; 679 int r = rmmod(bb_get_last_path_component_nostrip(info->pathname));
656 char modname[MODULE_NAME_LEN];
657
658 filename2modname(
659 bb_get_last_path_component_nostrip(info->pathname), modname);
660 r = delete_module(modname, O_NONBLOCK | O_EXCL);
661 dbg1_error_msg("delete_module('%s', O_NONBLOCK | O_EXCL):%d", modname, r);
662 if (r != 0) { 680 if (r != 0) {
663 if (!(option_mask32 & OPT_q)) 681 goto ret; /* error */
664 bb_perror_msg("remove '%s'", modname);
665 goto ret;
666 } 682 }
667 } 683 }
668
669 if (applet_name[0] == 'r') {
670 /* rmmod: do not remove dependencies, exit */
671 goto ret;
672 }
673
674 /* modprobe -r: we do not stop here - 684 /* modprobe -r: we do not stop here -
675 * continue to unload modules on which the module depends: 685 * continue to unload modules on which the module depends:
676 * "-r --remove: option causes modprobe to remove a module. 686 * "-r --remove: option causes modprobe to remove a module.
@@ -691,7 +701,7 @@ static void process_module(char *name, const char *cmdline_options)
691 } 701 }
692 free(deps); 702 free(deps);
693 703
694 if (is_rmmod) 704 if (is_remove)
695 continue; 705 continue;
696 706
697 /* We are modprobe: load it */ 707 /* We are modprobe: load it */
@@ -894,10 +904,10 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
894 } 904 }
895 905
896#if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE 906#if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE
897 /* If not rmmod, parse possible module options given on command line. 907 /* If not rmmod/-r, parse possible module options given on command line.
898 * insmod/modprobe takes one module name, the rest are parameters. */ 908 * insmod/modprobe takes one module name, the rest are parameters. */
899 options = NULL; 909 options = NULL;
900 if ('r' != applet0) { 910 if (!(option_mask32 & OPT_r)) {
901 char **arg = argv; 911 char **arg = argv;
902 while (*++arg) { 912 while (*++arg) {
903 /* Enclose options in quotes */ 913 /* Enclose options in quotes */
@@ -908,7 +918,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
908 } 918 }
909 } 919 }
910#else 920#else
911 if ('r' != applet0) 921 if (!(option_mask32 & OPT_r))
912 argv[1] = NULL; 922 argv[1] = NULL;
913#endif 923#endif
914 924
@@ -932,10 +942,11 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv)
932 } 942 }
933 943
934 /* Try to load modprobe.dep.bb */ 944 /* Try to load modprobe.dep.bb */
935 load_dep_bb(); 945 if ('r' != applet0) /* not rmmod */
946 load_dep_bb();
936 947
937 /* Load/remove modules. 948 /* Load/remove modules.
938 * Only rmmod loops here, modprobe has only argv[0] */ 949 * Only rmmod/modprobe -r loops here, insmod/modprobe has only argv[0] */
939 do { 950 do {
940 process_module(*argv, options); 951 process_module(*argv, options);
941 } while (*++argv); 952 } while (*++argv);