modprobe-small: fix and simplify rmmod
No binary (build failed)
—
(log yok)
| @@ -549,9 +549,23 @@ static int already_loaded(const char *name) | |
| 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. | |
| @@ -568,26 +582,36 @@ static void process_module(char *name, const char *cmdline_options) | |
| 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) | |
| @@ -621,7 +645,7 @@ static void process_module(char *name, const char *cmdline_options) | |
| 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]; | |
| @@ -634,7 +658,7 @@ static void process_module(char *name, const char *cmdline_options) | |
| 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; | |
| @@ -648,29 +672,15 @@ static void process_module(char *name, const char *cmdline_options) | |
| * 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. | |
| @@ -691,7 +701,7 @@ static void process_module(char *name, const char *cmdline_options) | |
| } | |
| free(deps); | |
| - | if (is_rmmod) |
| + | if (is_remove) |
| continue; | |
| /* We are modprobe: load it */ | |
| @@ -894,10 +904,10 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |
| } | |
| #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 */ | |
| @@ -908,7 +918,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |
| } | |
| } | |
| #else | |
| - | if ('r' != applet0) |
| + | if (!(option_mask32 & OPT_r)) |
| argv[1] = NULL; | |
| #endif | |
| @@ -932,10 +942,11 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |
| } | |
| /* 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); | |