aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Jenkins <alan-jenkins@tuffmail.co.uk>2010-03-16 17:49:58 +0000
committerAlan Jenkins <alan-jenkins@tuffmail.co.uk>2010-03-17 10:24:58 +0000
commit3ad3131cb10639a35f9e80000717b629a90fe900 (patch)
tree91984462f28d6ac0831735831cc9c01e1dcd1c48
parent8829d1c5870bd9cc99631847b7f5e04d728a7a88 (diff)
downloadmodule-init-tools-3ad3131cb10639a35f9e80000717b629a90fe900.tar.gz
modprobe: try to remove unused modules first
This allows e.g. removing all alsa modules with modprobe -r `lsmod|cut -d " " -f1|grep snd` or even removing all currently unused modules. modprobe -r `lsmod|cut -d " " -f1|grep -v Module`
-rw-r--r--modprobe.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/modprobe.c b/modprobe.c
index 5a1e6ee..26a7163 100644
--- a/modprobe.c
+++ b/modprobe.c
@@ -1863,9 +1863,44 @@ int main(int argc, char *argv[])
for (i = 0; i < num_modules; i++)
underscores(argv[optind + i]);
+ /* If we have a list of modules to remove, try the unused ones first.
+ Aliases and modules which don't seem to exist are handled later. */
+ if (flags & mit_remove) {
+ int progress;
+ do {
+ progress = 0;
+
+ for (i = 0; i < num_modules; i++) {
+ const char *modname;
+ unsigned usecount;
+ LIST_HEAD(list);
+
+ modname = argv[optind + i];
+ if (!modname)
+ continue;
+ if (module_in_kernel(modname, &usecount) != 1)
+ continue;
+ if (usecount != 0)
+ continue;
+
+ read_depends(dirname, modname, &list);
+
+ failed |= handle_module(modname, &list,
+ cmdline_opts, cmdline_opts,
+ &conf, dirname, error, flags);
+ progress++;
+ argv[optind + i] = NULL;
+ INIT_LIST_HEAD(&list);
+ }
+ } while (progress > 0);
+ }
+
/* num_modules is always 1 except for -r or -a. */
for (i = 0; i < num_modules; i++) {
- char *modname = argv[optind + i];
+ const char *modname = argv[optind + i];
+
+ if (!modname)
+ continue;
failed |= do_modprobe(modname, cmdline_opts,
&conf, dirname, error, flags);