In line with m-i-t's behavior, we should check to see if each module is:
- loaded
- has any holders
- has a 0 refcnt
Detecting any of these lets us provide a more useful message than the
kernel's EPERM response to delete_module(2).
Additionally, alter the main loop behavior to avoid exiting early on the
first error.
---
tools/kmod-rmmod.c | 35 +++++++++++++++++++++++++++++++----
1 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/tools/kmod-rmmod.c b/tools/kmod-rmmod.c
index 658ff6b..029621f 100644
--- a/tools/kmod-rmmod.c
+++ b/tools/kmod-rmmod.c
@@ -107,7 +107,7 @@ static int do_rmmod(int argc, char *argv[])
int flags = KMOD_REMOVE_NOWAIT;
int use_syslog = 0;
int verbose = 0;
- int i, err = 0;
+ int i, err, r = 0;
for (;;) {
int c, idx = 0;
@@ -162,6 +162,8 @@ static int do_rmmod(int argc, char *argv[])
for (i = optind; i < argc; i++) {
struct kmod_module *mod;
+ struct kmod_list *holders;
+ int use_count;
const char *arg = argv[i];
struct stat st;
if (stat(arg, &st) == 0)
@@ -175,15 +177,40 @@ static int do_rmmod(int argc, char *argv[])
break;
}
+ if (kmod_module_get_initstate(mod) == -ENOENT) {
+ fprintf(stderr, "Error: Module %s is not currently
loaded\n",
+ kmod_module_get_name(mod));
+ goto next;
+ }
+
+ holders = kmod_module_get_holders(mod);
+ if (holders != NULL) {
+ struct kmod_module *hm =
kmod_module_get_module(holders);
+ fprintf(stderr, "Error: Module %s is in use by %s\n",
+ kmod_module_get_name(mod),
kmod_module_get_name(hm));
+ kmod_module_unref_list(holders);
+ kmod_module_unref(hm);
+ r++;
+ goto next;
+ }
+
+ use_count = kmod_module_get_refcnt(mod);
+ if (use_count != 0) {
+ fprintf(stderr, "Error: Module %s is in use\n",
+ kmod_module_get_name(mod));
+ r++;
+ goto next;
+ }
+
err = kmod_module_remove_module(mod, flags);
if (err < 0) {
fprintf(stderr,
"Error: could not remove module %s: %s\n",
arg, strerror(-err));
+ r++;
}
+next:
kmod_module_unref(mod);
- if (err < 0)
- break;
}
kmod_unref(ctx);
@@ -191,7 +218,7 @@ static int do_rmmod(int argc, char *argv[])
if (use_syslog)
closelog();
- return err >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+ return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
#ifndef KMOD_BUNDLE_TOOL
--
1.7.8.3
--
To unsubscribe from this list: send the line "unsubscribe linux-modules" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html