| --- busybox-1.23.1/modutils/modprobe-small.c |
| +++ busybox-1.23.1-modprobe-small/modutils/modprobe-small.c |
| @@ -552,9 +552,23 @@ static int already_loaded(const char *na |
| return ret; |
| } |
| #else |
| -#define already_loaded(name) is_rmmod |
| +#define already_loaded(name) 0 |
| #endif |
| |
| +static int rmmod(const char *filename) |
| +{ |
| + int r; |
| + char modname[MODULE_NAME_LEN]; |
| + |
| + filename2modname(filename, modname); |
| + r = delete_module(modname, O_NONBLOCK | O_EXCL); |
| + dbg1_error_msg("delete_module('%s', O_NONBLOCK | O_EXCL):%d", modname, r); |
| + if (r != 0 && !(option_mask32 & OPT_q)) { |
| + bb_perror_msg("remove '%s'", modname); |
| + } |
| + return r; |
| +} |
| + |
| /* |
| * Given modules definition and module name (or alias, or symbol) |
| * load/remove the module respecting dependencies. |
| @@ -571,26 +585,36 @@ static void process_module(char *name, c |
| module_info **infovec; |
| module_info *info; |
| int infoidx; |
| - int is_rmmod = (option_mask32 & OPT_r) != 0; |
| + int is_remove = (option_mask32 & OPT_r) != 0; |
| |
| dbg1_error_msg("process_module('%s','%s')", name, cmdline_options); |
| |
| replace(name, '-', '_'); |
| |
| - dbg1_error_msg("already_loaded:%d is_rmmod:%d", already_loaded(name), is_rmmod); |
| + dbg1_error_msg("already_loaded:%d is_remove:%d", already_loaded(name), is_remove); |
| + |
| + if (applet_name[0] == 'r') { |
| + /* rmmod. |
| + * Does not remove dependencies, no need to scan, just remove. |
| + * (compat note: this allows and strips .ko suffix) |
| + */ |
| + rmmod(name); |
| + return; |
| + } |
| + |
| /* |
| - * We used to have "is_rmmod != already_loaded(name)" check here, but |
| + * We used to have "is_remove != already_loaded(name)" check here, but |
| * modprobe -r pci:v00008086d00007010sv00000000sd00000000bc01sc01i80 |
| * won't unload modules (there are more than one) |
| * which have this alias. |
| */ |
| - if (!is_rmmod && already_loaded(name)) { |
| + if (!is_remove && already_loaded(name)) { |
| dbg1_error_msg("nothing to do for '%s'", name); |
| return; |
| } |
| |
| options = NULL; |
| - if (!is_rmmod) { |
| + if (!is_remove) { |
| char *opt_filename = xasprintf("/etc/modules/%s", name); |
| options = xmalloc_open_read_close(opt_filename, NULL); |
| if (options) |
| @@ -624,7 +648,7 @@ static void process_module(char *name, c |
| 0 /* depth */ |
| ); |
| dbg1_error_msg("dirscan complete"); |
| - /* Module was not found, or load failed, or is_rmmod */ |
| + /* Module was not found, or load failed, or is_remove */ |
| if (module_found_idx >= 0) { /* module was found */ |
| infovec = xzalloc(2 * sizeof(infovec[0])); |
| infovec[0] = &modinfo[module_found_idx]; |
| @@ -637,7 +661,7 @@ static void process_module(char *name, c |
| |
| if (!infovec) { |
| /* both dirscan and find_alias found nothing */ |
| - if (!is_rmmod && applet_name[0] != 'd') /* it wasn't rmmod or depmod */ |
| + if (!is_remove && applet_name[0] != 'd') /* it wasn't rmmod or depmod */ |
| bb_error_msg("module '%s' not found", name); |
| //TODO: _and_die()? or should we continue (un)loading modules listed on cmdline? |
| goto ret; |
| @@ -651,29 +675,15 @@ static void process_module(char *name, c |
| * a *list* of modinfo pointers from find_alias(). |
| */ |
| |
| - /* rmmod or modprobe -r? unload module(s) */ |
| - if (is_rmmod) { |
| + /* modprobe -r? unload module(s) */ |
| + if (is_remove) { |
| infoidx = 0; |
| while ((info = infovec[infoidx++]) != NULL) { |
| - int r; |
| - char modname[MODULE_NAME_LEN]; |
| - |
| - filename2modname( |
| - bb_get_last_path_component_nostrip(info->pathname), modname); |
| - r = delete_module(modname, O_NONBLOCK | O_EXCL); |
| - dbg1_error_msg("delete_module('%s', O_NONBLOCK | O_EXCL):%d", modname, r); |
| + int r = rmmod(bb_get_last_path_component_nostrip(info->pathname)); |
| if (r != 0) { |
| - if (!(option_mask32 & OPT_q)) |
| - bb_perror_msg("remove '%s'", modname); |
| - goto ret; |
| + goto ret; /* error */ |
| } |
| } |
| - |
| - if (applet_name[0] == 'r') { |
| - /* rmmod: do not remove dependencies, exit */ |
| - goto ret; |
| - } |
| - |
| /* modprobe -r: we do not stop here - |
| * continue to unload modules on which the module depends: |
| * "-r --remove: option causes modprobe to remove a module. |
| @@ -694,7 +704,7 @@ static void process_module(char *name, c |
| } |
| free(deps); |
| |
| - if (is_rmmod) |
| + if (is_remove) |
| continue; |
| |
| /* We are modprobe: load it */ |
| @@ -897,10 +907,10 @@ int modprobe_main(int argc UNUSED_PARAM, |
| } |
| |
| #if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE |
| - /* If not rmmod, parse possible module options given on command line. |
| + /* If not rmmod/-r, parse possible module options given on command line. |
| * insmod/modprobe takes one module name, the rest are parameters. */ |
| options = NULL; |
| - if ('r' != applet0) { |
| + if (!(option_mask32 & OPT_r)) { |
| char **arg = argv; |
| while (*++arg) { |
| /* Enclose options in quotes */ |
| @@ -911,7 +921,7 @@ int modprobe_main(int argc UNUSED_PARAM, |
| } |
| } |
| #else |
| - if ('r' != applet0) |
| + if (!(option_mask32 & OPT_r)) |
| argv[1] = NULL; |
| #endif |
| |
| @@ -935,10 +945,11 @@ int modprobe_main(int argc UNUSED_PARAM, |
| } |
| |
| /* Try to load modprobe.dep.bb */ |
| - load_dep_bb(); |
| + if ('r' != applet0) /* not rmmod */ |
| + load_dep_bb(); |
| |
| /* Load/remove modules. |
| - * Only rmmod loops here, modprobe has only argv[0] */ |
| + * Only rmmod/modprobe -r loops here, insmod/modprobe has only argv[0] */ |
| do { |
| process_module(*argv, options); |
| } while (*++argv); |