diff options
-rw-r--r-- | modutils/modprobe-small.c | 72 |
1 files changed, 39 insertions, 33 deletions
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index 0fc9ea454..12e09938a 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c | |||
@@ -13,15 +13,14 @@ | |||
13 | //config:config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | 13 | //config:config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE |
14 | //config: bool "Accept module options on modprobe command line" | 14 | //config: bool "Accept module options on modprobe command line" |
15 | //config: default y | 15 | //config: default y |
16 | //config: depends on MODPROBE_SMALL | 16 | //config: depends on MODPROBE_SMALL && (INSMOD || MODPROBE) |
17 | //config: select PLATFORM_LINUX | ||
18 | //config: help | 17 | //config: help |
19 | //config: Allow insmod and modprobe take module options from command line. | 18 | //config: Allow insmod and modprobe take module options from command line. |
20 | //config: | 19 | //config: |
21 | //config:config FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED | 20 | //config:config FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED |
22 | //config: bool "Skip loading of already loaded modules" | 21 | //config: bool "Skip loading of already loaded modules" |
23 | //config: default y | 22 | //config: default y |
24 | //config: depends on MODPROBE_SMALL | 23 | //config: depends on MODPROBE_SMALL && (DEPMOD || INSMOD || MODPROBE) |
25 | //config: help | 24 | //config: help |
26 | //config: Check if the module is already loaded. | 25 | //config: Check if the module is already loaded. |
27 | 26 | ||
@@ -59,6 +58,14 @@ | |||
59 | 58 | ||
60 | #define DEPFILE_BB CONFIG_DEFAULT_DEPMOD_FILE".bb" | 59 | #define DEPFILE_BB CONFIG_DEFAULT_DEPMOD_FILE".bb" |
61 | 60 | ||
61 | #define ONLY_APPLET (ENABLE_MODPROBE + ENABLE_DEPMOD + ENABLE_INSMOD \ | ||
62 | + ENABLE_LSMOD + ENABLE_RMMOD <= 1) | ||
63 | #define is_modprobe (ENABLE_MODPROBE && (ONLY_APPLET || applet_name[0] == 'm')) | ||
64 | #define is_depmod (ENABLE_DEPMOD && (ONLY_APPLET || applet_name[0] == 'd')) | ||
65 | #define is_insmod (ENABLE_INSMOD && (ONLY_APPLET || applet_name[0] == 'i')) | ||
66 | #define is_lsmod (ENABLE_LSMOD && (ONLY_APPLET || applet_name[0] == 'l')) | ||
67 | #define is_rmmod (ENABLE_RMMOD && (ONLY_APPLET || applet_name[0] == 'r')) | ||
68 | |||
62 | enum { | 69 | enum { |
63 | OPT_q = (1 << 0), /* be quiet */ | 70 | OPT_q = (1 << 0), /* be quiet */ |
64 | OPT_r = (1 << 1), /* module removal instead of loading */ | 71 | OPT_r = (1 << 1), /* module removal instead of loading */ |
@@ -361,6 +368,8 @@ static FAST_FUNC int fileAction(const char *pathname, | |||
361 | { | 368 | { |
362 | int cur; | 369 | int cur; |
363 | const char *fname; | 370 | const char *fname; |
371 | bool is_remove = (ENABLE_RMMOD && ONLY_APPLET) | ||
372 | || ((ENABLE_RMMOD || ENABLE_MODPROBE) && (option_mask32 & OPT_r)); | ||
364 | 373 | ||
365 | pathname += 2; /* skip "./" */ | 374 | pathname += 2; /* skip "./" */ |
366 | fname = bb_get_last_path_component_nostrip(pathname); | 375 | fname = bb_get_last_path_component_nostrip(pathname); |
@@ -385,7 +394,7 @@ static FAST_FUNC int fileAction(const char *pathname, | |||
385 | if (parse_module(&modinfo[cur], pathname) != 0) | 394 | if (parse_module(&modinfo[cur], pathname) != 0) |
386 | return TRUE; /* failed to open/read it, no point in trying loading */ | 395 | return TRUE; /* failed to open/read it, no point in trying loading */ |
387 | 396 | ||
388 | if (!(option_mask32 & OPT_r)) { | 397 | if (!is_remove) { |
389 | if (load_module(pathname, module_load_options) == 0) { | 398 | if (load_module(pathname, module_load_options) == 0) { |
390 | /* Load was successful, there is nothing else to do. | 399 | /* Load was successful, there is nothing else to do. |
391 | * This can happen ONLY for "top-level" module load, | 400 | * This can happen ONLY for "top-level" module load, |
@@ -666,7 +675,8 @@ static int process_module(char *name, const char *cmdline_options) | |||
666 | module_info **infovec; | 675 | module_info **infovec; |
667 | module_info *info; | 676 | module_info *info; |
668 | int infoidx; | 677 | int infoidx; |
669 | int is_remove = (option_mask32 & OPT_r) != 0; | 678 | bool is_remove = (ENABLE_RMMOD && ONLY_APPLET) |
679 | || ((ENABLE_RMMOD || ENABLE_MODPROBE) && (option_mask32 & OPT_r)); | ||
670 | int exitcode = EXIT_SUCCESS; | 680 | int exitcode = EXIT_SUCCESS; |
671 | 681 | ||
672 | dbg1_error_msg("process_module('%s','%s')", name, cmdline_options); | 682 | dbg1_error_msg("process_module('%s','%s')", name, cmdline_options); |
@@ -675,9 +685,8 @@ static int process_module(char *name, const char *cmdline_options) | |||
675 | 685 | ||
676 | dbg1_error_msg("already_loaded:%d is_remove:%d", already_loaded(name), is_remove); | 686 | dbg1_error_msg("already_loaded:%d is_remove:%d", already_loaded(name), is_remove); |
677 | 687 | ||
678 | if (applet_name[0] == 'r') { | 688 | if (is_rmmod) { |
679 | /* rmmod. | 689 | /* Does not remove dependencies, no need to scan, just remove. |
680 | * Does not remove dependencies, no need to scan, just remove. | ||
681 | * (compat note: this allows and strips .ko suffix) | 690 | * (compat note: this allows and strips .ko suffix) |
682 | */ | 691 | */ |
683 | rmmod(name); | 692 | rmmod(name); |
@@ -743,7 +752,7 @@ static int process_module(char *name, const char *cmdline_options) | |||
743 | 752 | ||
744 | if (!infovec) { | 753 | if (!infovec) { |
745 | /* both dirscan and find_alias found nothing */ | 754 | /* both dirscan and find_alias found nothing */ |
746 | if (!is_remove && applet_name[0] != 'd') /* it wasn't rmmod or depmod */ | 755 | if (!is_remove && !is_depmod) /* it wasn't rmmod or depmod */ |
747 | bb_error_msg("module '%s' not found", name); | 756 | bb_error_msg("module '%s' not found", name); |
748 | //TODO: _and_die()? or should we continue (un)loading modules listed on cmdline? | 757 | //TODO: _and_die()? or should we continue (un)loading modules listed on cmdline? |
749 | goto ret; | 758 | goto ret; |
@@ -926,11 +935,10 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
926 | { | 935 | { |
927 | int exitcode; | 936 | int exitcode; |
928 | struct utsname uts; | 937 | struct utsname uts; |
929 | char applet0 = applet_name[0]; | 938 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options = NULL;) |
930 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) | ||
931 | 939 | ||
932 | /* are we lsmod? -> just dump /proc/modules */ | 940 | /* are we lsmod? -> just dump /proc/modules */ |
933 | if (ENABLE_LSMOD && 'l' == applet0) { | 941 | if (is_lsmod) { |
934 | xprint_and_close_file(xfopen_for_read("/proc/modules")); | 942 | xprint_and_close_file(xfopen_for_read("/proc/modules")); |
935 | return EXIT_SUCCESS; | 943 | return EXIT_SUCCESS; |
936 | } | 944 | } |
@@ -940,14 +948,13 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
940 | /* Prevent ugly corner cases with no modules at all */ | 948 | /* Prevent ugly corner cases with no modules at all */ |
941 | modinfo = xzalloc(sizeof(modinfo[0])); | 949 | modinfo = xzalloc(sizeof(modinfo[0])); |
942 | 950 | ||
943 | if (!ENABLE_INSMOD || 'i' != applet0) { /* not insmod */ | 951 | if (!is_insmod) { |
944 | /* Goto modules directory */ | 952 | /* Goto modules directory */ |
945 | xchdir(CONFIG_DEFAULT_MODULES_DIR); | 953 | xchdir(CONFIG_DEFAULT_MODULES_DIR); |
946 | } | 954 | } |
947 | uname(&uts); /* never fails */ | 955 | uname(&uts); /* never fails */ |
948 | 956 | ||
949 | /* depmod? */ | 957 | if (is_depmod) { |
950 | if (ENABLE_DEPMOD && 'd' == applet0) { | ||
951 | /* Supported: | 958 | /* Supported: |
952 | * -n: print result to stdout | 959 | * -n: print result to stdout |
953 | * -a: process all modules (default) | 960 | * -a: process all modules (default) |
@@ -978,28 +985,28 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
978 | return !wrote_dep_bb_ok; | 985 | return !wrote_dep_bb_ok; |
979 | } | 986 | } |
980 | 987 | ||
981 | /* insmod, modprobe, rmmod require at least one argument */ | 988 | #if ENABLE_MODPROBE || ENABLE_INSMOD || ENABLE_RMMOD |
989 | /* modprobe, insmod, rmmod require at least one argument */ | ||
982 | opt_complementary = "-1"; | 990 | opt_complementary = "-1"; |
983 | /* only -q (quiet) and -r (rmmod), | 991 | /* only -q (quiet) and -r (rmmod), |
984 | * the rest are accepted and ignored (compat) */ | 992 | * the rest are accepted and ignored (compat) */ |
985 | getopt32(argv, "qrfsvwb"); | 993 | getopt32(argv, "qrfsvwb"); |
986 | argv += optind; | 994 | argv += optind; |
987 | 995 | ||
988 | /* are we rmmod? -> simulate modprobe -r */ | 996 | if (!is_insmod) { |
989 | if (ENABLE_RMMOD && 'r' == applet0) { | ||
990 | option_mask32 |= OPT_r; | ||
991 | } | ||
992 | |||
993 | if (!ENABLE_INSMOD || 'i' != applet0) { /* not insmod */ | ||
994 | /* Goto $VERSION directory */ | 997 | /* Goto $VERSION directory */ |
995 | xchdir(uts.release); | 998 | xchdir(uts.release); |
996 | } | 999 | } |
997 | 1000 | ||
998 | #if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | 1001 | /* are we rmmod? -> simulate modprobe -r, but don't bother the flag if |
1002 | * there're no other applets here */ | ||
1003 | if (is_rmmod) { | ||
1004 | if (!ONLY_APPLET) | ||
1005 | option_mask32 |= OPT_r; | ||
1006 | } else if (!ENABLE_MODPROBE || !(option_mask32 & OPT_r)) { | ||
1007 | # if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | ||
999 | /* If not rmmod/-r, parse possible module options given on command line. | 1008 | /* If not rmmod/-r, parse possible module options given on command line. |
1000 | * insmod/modprobe takes one module name, the rest are parameters. */ | 1009 | * insmod/modprobe takes one module name, the rest are parameters. */ |
1001 | options = NULL; | ||
1002 | if (!(option_mask32 & OPT_r)) { | ||
1003 | char **arg = argv; | 1010 | char **arg = argv; |
1004 | while (*++arg) { | 1011 | while (*++arg) { |
1005 | /* Enclose options in quotes */ | 1012 | /* Enclose options in quotes */ |
@@ -1008,13 +1015,12 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
1008 | free(s); | 1015 | free(s); |
1009 | *arg = NULL; | 1016 | *arg = NULL; |
1010 | } | 1017 | } |
1011 | } | 1018 | # else |
1012 | #else | ||
1013 | if (!(option_mask32 & OPT_r)) | ||
1014 | argv[1] = NULL; | 1019 | argv[1] = NULL; |
1015 | #endif | 1020 | # endif |
1021 | } | ||
1016 | 1022 | ||
1017 | if (ENABLE_INSMOD && 'i' == applet0) { /* insmod */ | 1023 | if (is_insmod) { |
1018 | size_t len; | 1024 | size_t len; |
1019 | void *map; | 1025 | void *map; |
1020 | 1026 | ||
@@ -1023,8 +1029,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
1023 | if (!map) | 1029 | if (!map) |
1024 | bb_perror_msg_and_die("can't read '%s'", *argv); | 1030 | bb_perror_msg_and_die("can't read '%s'", *argv); |
1025 | if (init_module(map, len, | 1031 | if (init_module(map, len, |
1026 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(options ? options : "") | 1032 | (IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(options ? options : ) "") |
1027 | IF_NOT_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE("") | ||
1028 | ) != 0 | 1033 | ) != 0 |
1029 | ) { | 1034 | ) { |
1030 | bb_error_msg_and_die("can't insert '%s': %s", | 1035 | bb_error_msg_and_die("can't insert '%s': %s", |
@@ -1034,7 +1039,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
1034 | } | 1039 | } |
1035 | 1040 | ||
1036 | /* Try to load modprobe.dep.bb */ | 1041 | /* Try to load modprobe.dep.bb */ |
1037 | if (!ENABLE_RMMOD || 'r' != applet0) { /* not rmmod */ | 1042 | if (!is_rmmod) { |
1038 | load_dep_bb(); | 1043 | load_dep_bb(); |
1039 | } | 1044 | } |
1040 | 1045 | ||
@@ -1049,4 +1054,5 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
1049 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);) | 1054 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);) |
1050 | } | 1055 | } |
1051 | return exitcode; | 1056 | return exitcode; |
1057 | #endif /* MODPROBE || INSMOD || RMMOD */ | ||
1052 | } | 1058 | } |