]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
modprobe: Make rmmod_do_module() contain all the removal sequence
authorLucas De Marchi <lucas.demarchi@intel.com>
Tue, 29 Mar 2022 09:05:40 +0000 (02:05 -0700)
committerLucas De Marchi <lucas.demarchi@intel.com>
Thu, 7 Apr 2022 05:04:42 +0000 (22:04 -0700)
Move the remaining part of the removal sequence dangling in
rmmod_do_remove_module() to rmmod_do_module() so we can consider this
function is the one controlling all the module removals.

While at it, add some comments about the removal order and normalize
coding style in this function.

Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
tools/modprobe.c

index 45952a6d8b82cb08ef51ffba138cdee9577db569..830c667b76770e39e8d7195e9b15c91f9e2e562c 100644 (file)
@@ -322,7 +322,6 @@ end:
 static int rmmod_do_remove_module(struct kmod_module *mod)
 {
        const char *modname = kmod_module_get_name(mod);
-       struct kmod_list *deps, *itr;
        int flags = 0, err;
 
        SHOW("rmmod %s\n", kmod_module_get_name(mod));
@@ -341,17 +340,6 @@ static int rmmod_do_remove_module(struct kmod_module *mod)
                        LOG("Module %s is not in kernel.\n", modname);
        }
 
-       deps = kmod_module_get_dependencies(mod);
-       if (deps != NULL) {
-               kmod_list_foreach(itr, deps) {
-                       struct kmod_module *dep = kmod_module_get_module(itr);
-                       if (kmod_module_get_refcnt(dep) == 0)
-                               rmmod_do_remove_module(dep);
-                       kmod_module_unref(dep);
-               }
-               kmod_module_unref_list(deps);
-       }
-
        return err;
 }
 
@@ -394,7 +382,8 @@ static int rmmod_do_module(struct kmod_module *mod, int flags)
                cmd = kmod_module_get_remove_commands(mod);
        }
 
-       if (cmd == NULL && !ignore_loaded) {
+       /* Quick check if module is loaded, otherwise there's nothing to do */
+       if (!cmd && !ignore_loaded) {
                int state = kmod_module_get_initstate(mod);
 
                if (state < 0) {
@@ -416,8 +405,10 @@ static int rmmod_do_module(struct kmod_module *mod, int flags)
                }
        }
 
+       /* 1. @mod's post-softdeps in reverse order */
        rmmod_do_modlist(post, false);
 
+       /* 2. Other modules holding @mod */
        if (flags & RMMOD_FLAG_REMOVE_HOLDERS) {
                struct kmod_list *holders = kmod_module_get_holders(mod);
 
@@ -426,7 +417,8 @@ static int rmmod_do_module(struct kmod_module *mod, int flags)
                        goto error;
        }
 
-       if (!ignore_loaded && !cmd) {
+       /* 3. @mod itself, but check for refcnt first */
+       if (!cmd && !ignore_loaded) {
                int usage = kmod_module_get_refcnt(mod);
 
                if (usage > 0) {
@@ -438,7 +430,7 @@ static int rmmod_do_module(struct kmod_module *mod, int flags)
                }
        }
 
-       if (cmd == NULL)
+       if (!cmd)
                err = rmmod_do_remove_module(mod);
        else
                err = command_do(mod, "remove", cmd, NULL);
@@ -446,6 +438,21 @@ static int rmmod_do_module(struct kmod_module *mod, int flags)
        if (err < 0)
                goto error;
 
+       /* 4. Other modules that became unused: errors are non-fatal */
+       if (!cmd) {
+               struct kmod_list *deps, *itr;
+
+               deps = kmod_module_get_dependencies(mod);
+               kmod_list_foreach(itr, deps) {
+                       struct kmod_module *dep = kmod_module_get_module(itr);
+                       if (kmod_module_get_refcnt(dep) == 0)
+                               rmmod_do_remove_module(dep);
+                       kmod_module_unref(dep);
+               }
+               kmod_module_unref_list(deps);
+       }
+
+       /* 5. @mod's pre-softdeps in reverse order: errors are non-fatal */
        rmmod_do_modlist(pre, false);
 
 error: