summaryrefslogtreecommitdiff
path: root/modutils
diff options
context:
space:
mode:
authorDenys Vlasenko2009-05-28 03:54:29 +0200
committerDenys Vlasenko2009-05-28 03:54:29 +0200
commitf3cbfc0e2c2486e14ad099b8075293857c4890e8 (patch)
tree89d299561d91e3c0244c6c37f7a1507da083eb68 /modutils
parent398c65997050ffadf0f445a8f858b74e0355753d (diff)
downloadbusybox-f3cbfc0e2c2486e14ad099b8075293857c4890e8.zip
busybox-f3cbfc0e2c2486e14ad099b8075293857c4890e8.tar.gz
modprobe: fix more bugs in modprobe -r
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'modutils')
-rw-r--r--modutils/modprobe.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/modutils/modprobe.c b/modutils/modprobe.c
index 54cd84c..d000c91 100644
--- a/modutils/modprobe.c
+++ b/modutils/modprobe.c
@@ -211,9 +211,9 @@ static int read_config(const char *path)
static int do_modprobe(struct module_entry *m)
{
- struct module_entry *m2;
+ struct module_entry *m2 = m2; /* for compiler */
char *fn, *options;
- int rc = -1;
+ int rc, first;
llist_t *l;
if (!(m->flags & MODULE_FLAG_FOUND_IN_MODDEP)) {
@@ -228,13 +228,22 @@ static int do_modprobe(struct module_entry *m)
for (l = m->deps; l != NULL; l = l->link)
DBG("dep: %s", l->data);
+ first = 1;
rc = 0;
while (m->deps && rc == 0) {
fn = llist_pop(&m->deps);
m2 = get_or_add_modentry(fn);
if (option_mask32 & MODPROBE_OPT_REMOVE) {
- if (bb_delete_module(m->modname, O_EXCL) != 0)
- rc = errno;
+ if (m2->flags & MODULE_FLAG_LOADED) {
+ if (bb_delete_module(m2->modname, O_EXCL) != 0) {
+ if (first)
+ rc = errno;
+ } else {
+ m2->flags &= ~MODULE_FLAG_LOADED;
+ }
+ }
+ /* do not error out if *deps* fail to unload */
+ first = 0;
} else if (!(m2->flags & MODULE_FLAG_LOADED)) {
options = m2->options;
m2->options = NULL;
@@ -252,11 +261,10 @@ static int do_modprobe(struct module_entry *m)
free(fn);
}
-//FIXME: what if rc < 0?
- if (rc > 0 && !(option_mask32 & INSMOD_OPT_SILENT)) {
+ if (rc && !(option_mask32 & INSMOD_OPT_SILENT)) {
bb_error_msg("failed to %sload module %s: %s",
(option_mask32 & MODPROBE_OPT_REMOVE) ? "un" : "",
- m->probed_name ? m->probed_name : m->modname,
+ m2->probed_name ? m2->probed_name : m2->modname,
moderror(rc)
);
}