172 lines
5.3 KiB
Diff
172 lines
5.3 KiB
Diff
|
Patch to fix busybox MODPROBE_SMALL from upstream:
|
||
|
http://busybox.net/downloads/fixes-1.23.1/busybox-1.23.1-modprobe-small.patch
|
||
|
|
||
|
Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
|
||
|
|
||
|
--- 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);
|