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@xxxxxxxxx> --- install/dracut-install.c | 54 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/install/dracut-install.c b/install/dracut-install.c index f104f664..001225b4 100644 --- a/install/dracut-install.c +++ b/install/dracut-install.c @@ -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; -- 2.13.6 -- To unsubscribe from this list: send the line "unsubscribe initramfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html