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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html