diff options
author | Ron Yorston <rmy@pobox.com> | 2016-07-07 14:28:08 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2016-07-07 14:58:55 +0100 |
commit | 613f46218c53c8cabdbf0435653e74e0e0e91e1c (patch) | |
tree | ca06a7e7a3e4c861441acb4ea20648d7827fa6ae /modutils | |
parent | a0c61c9492723dd31681f878f9c68c92817a476d (diff) | |
parent | 237bedd499c58034a1355484d6d4d906f0180308 (diff) | |
download | busybox-w32-613f46218c53c8cabdbf0435653e74e0e0e91e1c.tar.gz busybox-w32-613f46218c53c8cabdbf0435653e74e0e0e91e1c.tar.bz2 busybox-w32-613f46218c53c8cabdbf0435653e74e0e0e91e1c.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'modutils')
-rw-r--r-- | modutils/modprobe-small.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index 9c941064b..5936e48cf 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | extern int init_module(void *module, unsigned long len, const char *options); | 22 | extern int init_module(void *module, unsigned long len, const char *options); |
23 | extern int delete_module(const char *module, unsigned flags); | 23 | extern int delete_module(const char *module, unsigned flags); |
24 | extern int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret); | ||
25 | /* linux/include/linux/module.h has limit of 64 chars on module names */ | 24 | /* linux/include/linux/module.h has limit of 64 chars on module names */ |
26 | #undef MODULE_NAME_LEN | 25 | #undef MODULE_NAME_LEN |
27 | #define MODULE_NAME_LEN 64 | 26 | #define MODULE_NAME_LEN 64 |
@@ -46,6 +45,7 @@ typedef struct module_info { | |||
46 | char *pathname; | 45 | char *pathname; |
47 | char *aliases; | 46 | char *aliases; |
48 | char *deps; | 47 | char *deps; |
48 | smallint open_read_failed; | ||
49 | } module_info; | 49 | } module_info; |
50 | 50 | ||
51 | /* | 51 | /* |
@@ -223,7 +223,8 @@ static int load_module(const char *fname, const char *options) | |||
223 | #endif | 223 | #endif |
224 | } | 224 | } |
225 | 225 | ||
226 | static void parse_module(module_info *info, const char *pathname) | 226 | /* Returns !0 if open/read was unsuccessful */ |
227 | static int parse_module(module_info *info, const char *pathname) | ||
227 | { | 228 | { |
228 | char *module_image; | 229 | char *module_image; |
229 | char *ptr; | 230 | char *ptr; |
@@ -232,6 +233,7 @@ static void parse_module(module_info *info, const char *pathname) | |||
232 | dbg1_error_msg("parse_module('%s')", pathname); | 233 | dbg1_error_msg("parse_module('%s')", pathname); |
233 | 234 | ||
234 | /* Read (possibly compressed) module */ | 235 | /* Read (possibly compressed) module */ |
236 | errno = 0; | ||
235 | len = 64 * 1024 * 1024; /* 64 Mb at most */ | 237 | len = 64 * 1024 * 1024; /* 64 Mb at most */ |
236 | module_image = xmalloc_open_zipped_read_close(pathname, &len); | 238 | module_image = xmalloc_open_zipped_read_close(pathname, &len); |
237 | /* module_image == NULL is ok here, find_keyword handles it */ | 239 | /* module_image == NULL is ok here, find_keyword handles it */ |
@@ -299,9 +301,11 @@ static void parse_module(module_info *info, const char *pathname) | |||
299 | dbg2_error_msg("dep:'%s'", ptr); | 301 | dbg2_error_msg("dep:'%s'", ptr); |
300 | append(ptr); | 302 | append(ptr); |
301 | } | 303 | } |
304 | free(module_image); | ||
302 | info->deps = copy_stringbuf(); | 305 | info->deps = copy_stringbuf(); |
303 | 306 | ||
304 | free(module_image); | 307 | info->open_read_failed = (module_image == NULL); |
308 | return info->open_read_failed; | ||
305 | } | 309 | } |
306 | 310 | ||
307 | static FAST_FUNC int fileAction(const char *pathname, | 311 | static FAST_FUNC int fileAction(const char *pathname, |
@@ -332,7 +336,8 @@ static FAST_FUNC int fileAction(const char *pathname, | |||
332 | 336 | ||
333 | dbg1_error_msg("'%s' module name matches", pathname); | 337 | dbg1_error_msg("'%s' module name matches", pathname); |
334 | module_found_idx = cur; | 338 | module_found_idx = cur; |
335 | parse_module(&modinfo[cur], pathname); | 339 | if (parse_module(&modinfo[cur], pathname) != 0) |
340 | return TRUE; /* failed to open/read it, no point in trying loading */ | ||
336 | 341 | ||
337 | if (!(option_mask32 & OPT_r)) { | 342 | if (!(option_mask32 & OPT_r)) { |
338 | if (load_module(pathname, module_load_options) == 0) { | 343 | if (load_module(pathname, module_load_options) == 0) { |
@@ -609,13 +614,14 @@ static int rmmod(const char *filename) | |||
609 | #define process_module(a,b) process_module(a) | 614 | #define process_module(a,b) process_module(a) |
610 | #define cmdline_options "" | 615 | #define cmdline_options "" |
611 | #endif | 616 | #endif |
612 | static void process_module(char *name, const char *cmdline_options) | 617 | static int process_module(char *name, const char *cmdline_options) |
613 | { | 618 | { |
614 | char *s, *deps, *options; | 619 | char *s, *deps, *options; |
615 | module_info **infovec; | 620 | module_info **infovec; |
616 | module_info *info; | 621 | module_info *info; |
617 | int infoidx; | 622 | int infoidx; |
618 | int is_remove = (option_mask32 & OPT_r) != 0; | 623 | int is_remove = (option_mask32 & OPT_r) != 0; |
624 | int exitcode = EXIT_SUCCESS; | ||
619 | 625 | ||
620 | dbg1_error_msg("process_module('%s','%s')", name, cmdline_options); | 626 | dbg1_error_msg("process_module('%s','%s')", name, cmdline_options); |
621 | 627 | ||
@@ -629,7 +635,7 @@ static void process_module(char *name, const char *cmdline_options) | |||
629 | * (compat note: this allows and strips .ko suffix) | 635 | * (compat note: this allows and strips .ko suffix) |
630 | */ | 636 | */ |
631 | rmmod(name); | 637 | rmmod(name); |
632 | return; | 638 | return EXIT_SUCCESS; |
633 | } | 639 | } |
634 | 640 | ||
635 | /* | 641 | /* |
@@ -640,7 +646,7 @@ static void process_module(char *name, const char *cmdline_options) | |||
640 | */ | 646 | */ |
641 | if (!is_remove && already_loaded(name)) { | 647 | if (!is_remove && already_loaded(name)) { |
642 | dbg1_error_msg("nothing to do for '%s'", name); | 648 | dbg1_error_msg("nothing to do for '%s'", name); |
643 | return; | 649 | return EXIT_SUCCESS; |
644 | } | 650 | } |
645 | 651 | ||
646 | options = NULL; | 652 | options = NULL; |
@@ -742,6 +748,11 @@ static void process_module(char *name, const char *cmdline_options) | |||
742 | dbg1_error_msg("'%s': blacklisted", info->pathname); | 748 | dbg1_error_msg("'%s': blacklisted", info->pathname); |
743 | continue; | 749 | continue; |
744 | } | 750 | } |
751 | if (info->open_read_failed) { | ||
752 | /* We already tried it, didn't work. Don't try load again */ | ||
753 | exitcode = EXIT_FAILURE; | ||
754 | continue; | ||
755 | } | ||
745 | errno = 0; | 756 | errno = 0; |
746 | if (load_module(info->pathname, options) != 0) { | 757 | if (load_module(info->pathname, options) != 0) { |
747 | if (EEXIST != errno) { | 758 | if (EEXIST != errno) { |
@@ -753,13 +764,14 @@ static void process_module(char *name, const char *cmdline_options) | |||
753 | info->pathname, | 764 | info->pathname, |
754 | moderror(errno)); | 765 | moderror(errno)); |
755 | } | 766 | } |
767 | exitcode = EXIT_FAILURE; | ||
756 | } | 768 | } |
757 | } | 769 | } |
758 | ret: | 770 | ret: |
759 | free(infovec); | 771 | free(infovec); |
760 | free(options); | 772 | free(options); |
761 | //TODO: return load attempt result from process_module. | 773 | |
762 | //If dep didn't load ok, continuing makes little sense. | 774 | return exitcode; |
763 | } | 775 | } |
764 | #undef cmdline_options | 776 | #undef cmdline_options |
765 | 777 | ||
@@ -866,6 +878,7 @@ The following options are useful for people managing distributions: | |||
866 | int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 878 | int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
867 | int modprobe_main(int argc UNUSED_PARAM, char **argv) | 879 | int modprobe_main(int argc UNUSED_PARAM, char **argv) |
868 | { | 880 | { |
881 | int exitcode; | ||
869 | struct utsname uts; | 882 | struct utsname uts; |
870 | char applet0 = applet_name[0]; | 883 | char applet0 = applet_name[0]; |
871 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) | 884 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) |
@@ -971,21 +984,23 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
971 | bb_error_msg_and_die("can't insert '%s': %s", | 984 | bb_error_msg_and_die("can't insert '%s': %s", |
972 | *argv, moderror(errno)); | 985 | *argv, moderror(errno)); |
973 | } | 986 | } |
974 | return 0; | 987 | return EXIT_SUCCESS; |
975 | } | 988 | } |
976 | 989 | ||
977 | /* Try to load modprobe.dep.bb */ | 990 | /* Try to load modprobe.dep.bb */ |
978 | if ('r' != applet0) /* not rmmod */ | 991 | if ('r' != applet0) { /* not rmmod */ |
979 | load_dep_bb(); | 992 | load_dep_bb(); |
993 | } | ||
980 | 994 | ||
981 | /* Load/remove modules. | 995 | /* Load/remove modules. |
982 | * Only rmmod/modprobe -r loops here, insmod/modprobe has only argv[0] */ | 996 | * Only rmmod/modprobe -r loops here, insmod/modprobe has only argv[0] */ |
997 | exitcode = EXIT_SUCCESS; | ||
983 | do { | 998 | do { |
984 | process_module(*argv, options); | 999 | exitcode |= process_module(*argv, options); |
985 | } while (*++argv); | 1000 | } while (*++argv); |
986 | 1001 | ||
987 | if (ENABLE_FEATURE_CLEAN_UP) { | 1002 | if (ENABLE_FEATURE_CLEAN_UP) { |
988 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);) | 1003 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);) |
989 | } | 1004 | } |
990 | return EXIT_SUCCESS; | 1005 | return exitcode; |
991 | } | 1006 | } |