]> git.ipfire.org Git - thirdparty/dracut.git/commitdiff
dracut-install: Support modules.softdep
authorJeremy Linton <lintonrjeremy@gmail.com>
Tue, 3 Jul 2018 04:25:05 +0000 (23:25 -0500)
committerHarald Hoyer <harald@hoyer.xyz>
Tue, 3 Jul 2018 11:36:26 +0000 (13:36 +0200)
Dracut uses the module deps to determine module dependencies
but that only works for modules with hard symbolic dependencies.
Some modules have dependencies created via callback API's or other
methods which aren't reflected in the modules.dep but rather in
modules.softdep through the use of "pre:" and "post:" commands
created in the kernel with MODULE_SOFTDEP().

Since in dracut we are only concerned about early boot, this patch
only looks at the pre: section of modules which are already being
inserted in the initrd under the assumption that the pre: section
lists dependencies required for the functionality of the module being
installed in the initrd.

Signed-off-by: Jeremy Linton <lintonrjeremy@gmail.com>
install/dracut-install.c

index f104f66449bba11a88eede474d517fb1bc2619b4..001225b40f97ad78ca16425ae0a2a597e5dcb365 100644 (file)
@@ -1231,11 +1231,42 @@ static bool check_module_path(const char *path)
         return true;
 }
 
+static int install_dependent_modules(struct kmod_list *modlist)
+{
+        struct kmod_list *itr;
+        struct kmod_module *mod;
+        const char *path = NULL;
+        const char *name = NULL;
+        int ret = 0;
+
+        kmod_list_foreach(itr, modlist) {
+                mod = kmod_module_get_module(itr);
+                path = kmod_module_get_path(mod);
+
+                name = kmod_module_get_name(mod);
+                if (arg_mod_filter_noname && (regexec(&mod_filter_noname, name, 0, NULL, 0) == 0)) {
+                        kmod_module_unref(mod);
+                        continue;
+                }
+                ret = dracut_install(path, &path[kerneldirlen], false, false, true);
+                if (ret == 0) {
+                        log_debug("dracut_install '%s' '%s' OK", path, &path[kerneldirlen]);
+                        install_firmware(mod);
+                } else {
+                        log_error("dracut_install '%s' '%s' ERROR", path, &path[kerneldirlen]);
+                }
+                kmod_module_unref(mod);
+        }
+
+        return ret;
+}
+
 static int install_module(struct kmod_module *mod)
 {
         int ret = 0;
-        struct kmod_list *itr;
         _cleanup_kmod_module_unref_list_ struct kmod_list *modlist = NULL;
+        _cleanup_kmod_module_unref_list_ struct kmod_list *modpre = NULL;
+        _cleanup_kmod_module_unref_list_ struct kmod_list *modpost = NULL;
         const char *path = NULL;
         const char *name = NULL;
 
@@ -1278,23 +1309,12 @@ static int install_module(struct kmod_module *mod)
         install_firmware(mod);
 
         modlist = kmod_module_get_dependencies(mod);
-        kmod_list_foreach(itr, modlist) {
-                mod = kmod_module_get_module(itr);
-                path = kmod_module_get_path(mod);
+        ret = install_dependent_modules(modlist);
 
-                name = kmod_module_get_name(mod);
-                if (arg_mod_filter_noname && (regexec(&mod_filter_noname, name, 0, NULL, 0) == 0)) {
-                        kmod_module_unref(mod);
-                        continue;
-                }
-                ret = dracut_install(path, &path[kerneldirlen], false, false, true);
-                if (ret == 0) {
-                        log_debug("dracut_install '%s' '%s' OK", path, &path[kerneldirlen]);
-                        install_firmware(mod);
-                } else {
-                        log_error("dracut_install '%s' '%s' ERROR", path, &path[kerneldirlen]);
-                }
-                kmod_module_unref(mod);
+        if (ret == 0) {
+                ret = kmod_module_get_softdeps(mod, &modpre, &modpost);
+                if (ret == 0)
+                        ret = install_dependent_modules(modpre);
         }
 
         return ret;