From daf80bbb8f8ca5c4ad56772f379110e7434cbc2c Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Wed, 16 Oct 2024 13:45:35 -0400 Subject: [PATCH] Revert "feat(dracut-install): add fw_devlink suppliers as module dependencies" ...and associated later changes, as they cause serious regressions with aarch64 devices like the Lenovo X13s. see also https://github.com/dracut-ng/dracut-ng/issues/316 This reverts commit 8de0258d71dc5600d715d7534471e35b2b75c7be. This reverts commit 07e2c4926780b672922563a6ea0bf1bd4bcfcd9f. This reverts commit d71bec4aa444d92820e428c0629d0e75e268c815. This reverts commit 6500e95494175819b382acbac8eafcdf72fabd6d. This reverts commit 131822e26d76a3ce2028e9a545be2af066805629. This reverts commit 3de4c7313260fb600507c9b87f780390b874c870. --- src/install/dracut-install.c | 245 +++-------------------------------- 1 file changed, 15 insertions(+), 230 deletions(-) diff --git a/src/install/dracut-install.c b/src/install/dracut-install.c index 96bc2eb6..96644151 100644 --- a/src/install/dracut-install.c +++ b/src/install/dracut-install.c @@ -83,9 +83,6 @@ FILE *logfile_f = NULL; static Hashmap *items = NULL; static Hashmap *items_failed = NULL; static Hashmap *modules_loaded = NULL; -static Hashmap *modules_suppliers = NULL; -static Hashmap *processed_suppliers = NULL; -static Hashmap *modalias_to_kmod = NULL; static regex_t mod_filter_path; static regex_t mod_filter_nopath; static regex_t mod_filter_symbol; @@ -98,7 +95,7 @@ static bool arg_mod_filter_nosymbol = false; static bool arg_mod_filter_noname = false; static int dracut_install(const char *src, const char *dst, bool isdir, bool resolvedeps, bool hashdst); -static int install_dependent_modules(struct kmod_ctx *ctx, struct kmod_list *modlist, Hashmap *suppliers_paths); +static int install_dependent_modules(struct kmod_list *modlist); static void item_free(char *i) { @@ -1571,164 +1568,7 @@ static bool check_module_path(const char *path) return true; } -static int find_kmod_module_from_sysfs_driver(struct kmod_ctx *ctx, const char *sysfs_node, int sysfs_node_len, - struct kmod_module **module) -{ - char mod_path[PATH_MAX], mod_realpath[PATH_MAX]; - const char *mod_name; - if ((size_t)snprintf(mod_path, sizeof(mod_path), "%.*s/driver/module", - sysfs_node_len, sysfs_node) >= sizeof(mod_path)) - return -1; - - if (realpath(mod_path, mod_realpath) == NULL) - return -1; - - if ((mod_name = basename(mod_realpath)) == NULL) - return -1; - - return kmod_module_new_from_name(ctx, mod_name, module); -} - -static int find_kmod_module_from_sysfs_modalias(struct kmod_ctx *ctx, const char *sysfs_node, int sysfs_node_len, - struct kmod_list **modules) -{ - char modalias_path[PATH_MAX]; - if ((size_t)snprintf(modalias_path, sizeof(modalias_path), "%.*s/modalias", sysfs_node_len, - sysfs_node) >= sizeof(modalias_path)) - return -1; - - _cleanup_close_ int modalias_file = -1; - if ((modalias_file = open(modalias_path, O_RDONLY | O_CLOEXEC)) == -1) - return 0; - - char alias[page_size()]; - ssize_t len = read(modalias_file, alias, sizeof(alias)); - alias[len - 1] = '\0'; - - void *list; - - if (hashmap_get_exists(modalias_to_kmod, alias, &list) == 1) { - *modules = list; - return 0; - } - - int ret = kmod_module_new_from_lookup(ctx, alias, modules); - if (!ret) { - hashmap_put(modalias_to_kmod, strdup(alias), *modules); - } - - return ret; -} - -static int find_modules_from_sysfs_node(struct kmod_ctx *ctx, const char *sysfs_node, Hashmap *modules) -{ - _cleanup_kmod_module_unref_ struct kmod_module *drv = NULL; - struct kmod_list *list = NULL; - struct kmod_list *l = NULL; - - if (find_kmod_module_from_sysfs_driver(ctx, sysfs_node, strlen(sysfs_node), &drv) >= 0) { - char *module = strdup(kmod_module_get_name(drv)); - if (hashmap_put(modules, module, module) < 0) - free(module); - return 0; - } - - if (find_kmod_module_from_sysfs_modalias(ctx, sysfs_node, strlen(sysfs_node), &list) >= 0) { - kmod_list_foreach(l, list) { - struct kmod_module *mod = kmod_module_get_module(l); - char *module = strdup(kmod_module_get_name(mod)); - kmod_module_unref(mod); - - if (hashmap_put(modules, module, module) < 0) - free(module); - } - } - - return 0; -} - -static void find_suppliers_for_sys_node(Hashmap *suppliers, const char *node_path_raw, - size_t node_path_len) -{ - char node_path[PATH_MAX]; - char real_path[PATH_MAX]; - - memcpy(node_path, node_path_raw, node_path_len); - node_path[node_path_len] = '\0'; - - DIR *d; - struct dirent *dir; - while (realpath(node_path, real_path) != NULL && strcmp(real_path, "/sys/devices")) { - d = opendir(node_path); - if (d) { - size_t real_path_len = strlen(real_path); - while ((dir = readdir(d)) != NULL) { - if (strstr(dir->d_name, "supplier:platform") != NULL) { - if ((size_t)snprintf(real_path + real_path_len, sizeof(real_path) - real_path_len, "/%s/supplier", - dir->d_name) < sizeof(real_path) - real_path_len) { - char *real_supplier_path = realpath(real_path, NULL); - if (real_supplier_path != NULL) - if (hashmap_put(suppliers, real_supplier_path, real_supplier_path) < 0) - free(real_supplier_path); - } - } - } - closedir(d); - } - strcat(node_path, "/.."); // Also find suppliers of parents - } -} - -static void find_suppliers(struct kmod_ctx *ctx) -{ - _cleanup_fts_close_ FTS *fts; - char *paths[] = { "/sys/devices/platform", NULL }; - fts = fts_open(paths, FTS_NOSTAT | FTS_PHYSICAL, NULL); - - for (FTSENT *ftsent = fts_read(fts); ftsent != NULL; ftsent = fts_read(fts)) { - if (strcmp(ftsent->fts_name, "modalias") == 0) { - _cleanup_kmod_module_unref_ struct kmod_module *drv = NULL; - struct kmod_list *list = NULL; - struct kmod_list *l; - - if (find_kmod_module_from_sysfs_driver(ctx, ftsent->fts_parent->fts_path, ftsent->fts_parent->fts_pathlen, &drv) >= 0) { - const char *name = kmod_module_get_name(drv); - Hashmap *suppliers = hashmap_get(modules_suppliers, name); - if (suppliers == NULL) { - suppliers = hashmap_new(string_hash_func, string_compare_func); - hashmap_put(modules_suppliers, strdup(name), suppliers); - } - - find_suppliers_for_sys_node(suppliers, ftsent->fts_parent->fts_path, ftsent->fts_parent->fts_pathlen); - - /* Skip modalias check */ - continue; - } - - if (find_kmod_module_from_sysfs_modalias(ctx, ftsent->fts_parent->fts_path, ftsent->fts_parent->fts_pathlen, &list) < 0) - continue; - - kmod_list_foreach(l, list) { - _cleanup_kmod_module_unref_ struct kmod_module *mod = kmod_module_get_module(l); - const char *name = kmod_module_get_name(mod); - Hashmap *suppliers = hashmap_get(modules_suppliers, name); - if (suppliers == NULL) { - suppliers = hashmap_new(string_hash_func, string_compare_func); - hashmap_put(modules_suppliers, strdup(name), suppliers); - } - - find_suppliers_for_sys_node(suppliers, ftsent->fts_parent->fts_path, ftsent->fts_parent->fts_pathlen); - } - } - } -} - -static Hashmap *find_suppliers_paths_for_module(const char *module) -{ - return hashmap_get(modules_suppliers, module); -} - -static int install_dependent_module(struct kmod_ctx *ctx, struct kmod_module *mod, Hashmap *suppliers_paths, int *err) +static int install_dependent_module(struct kmod_module *mod, int *err) { const char *path = NULL; const char *name = NULL; @@ -1762,13 +1602,13 @@ static int install_dependent_module(struct kmod_ctx *ctx, struct kmod_module *mo log_debug("dracut_install '%s' '%s' OK", path, &path[kerneldirlen]); install_firmware(mod); modlist = kmod_module_get_dependencies(mod); - *err = install_dependent_modules(ctx, modlist, suppliers_paths); + *err = install_dependent_modules(modlist); if (*err == 0) { *err = kmod_module_get_softdeps(mod, &modpre, &modpost); if (*err == 0) { int r; - *err = install_dependent_modules(ctx, modpre, NULL); - r = install_dependent_modules(ctx, modpost, NULL); + *err = install_dependent_modules(modpre); + r = install_dependent_modules(modpost); *err = *err ? : r; } } @@ -1786,7 +1626,7 @@ static int install_dependent_module(struct kmod_ctx *ctx, struct kmod_module *mo return 0; } -static int install_dependent_modules(struct kmod_ctx *ctx, struct kmod_list *modlist, Hashmap *suppliers_paths) +static int install_dependent_modules(struct kmod_list *modlist) { struct kmod_list *itr = NULL; int ret = 0; @@ -1794,44 +1634,14 @@ static int install_dependent_modules(struct kmod_ctx *ctx, struct kmod_list *mod kmod_list_foreach(itr, modlist) { _cleanup_kmod_module_unref_ struct kmod_module *mod = NULL; mod = kmod_module_get_module(itr); - if (install_dependent_module(ctx, mod, find_suppliers_paths_for_module(kmod_module_get_name(mod)), &ret)) + if (install_dependent_module(mod, &ret)) return -1; } - const char *supplier_path; - Iterator i; - HASHMAP_FOREACH(supplier_path, suppliers_paths, i) { - if (check_hashmap(processed_suppliers, supplier_path)) - continue; - - char *path = strdup(supplier_path); - hashmap_put(processed_suppliers, path, path); - - _cleanup_destroy_hashmap_ Hashmap *modules = hashmap_new(string_hash_func, string_compare_func); - find_modules_from_sysfs_node(ctx, supplier_path, modules); - - _cleanup_destroy_hashmap_ Hashmap *suppliers = hashmap_new(string_hash_func, string_compare_func); - find_suppliers_for_sys_node(suppliers, supplier_path, strlen(supplier_path)); - - if (!hashmap_isempty(modules)) { // Supplier is a module - const char *module; - Iterator j; - HASHMAP_FOREACH(module, modules, j) { - _cleanup_kmod_module_unref_ struct kmod_module *mod = NULL; - if (!kmod_module_new_from_name(ctx, module, &mod)) { - if (install_dependent_module(ctx, mod, suppliers, &ret)) - return -1; - } - } - } else { // Supplier is builtin - install_dependent_modules(ctx, NULL, suppliers); - } - } - return ret; } -static int install_module(struct kmod_ctx *ctx, struct kmod_module *mod) +static int install_module(struct kmod_module *mod) { int ret = 0; _cleanup_kmod_module_unref_list_ struct kmod_list *modlist = NULL; @@ -1884,16 +1694,15 @@ static int install_module(struct kmod_ctx *ctx, struct kmod_module *mod) } install_firmware(mod); - Hashmap *suppliers = find_suppliers_paths_for_module(name); modlist = kmod_module_get_dependencies(mod); - ret = install_dependent_modules(ctx, modlist, suppliers); + ret = install_dependent_modules(modlist); if (ret == 0) { ret = kmod_module_get_softdeps(mod, &modpre, &modpost); if (ret == 0) { int r; - ret = install_dependent_modules(ctx, modpre, NULL); - r = install_dependent_modules(ctx, modpost, NULL); + ret = install_dependent_modules(modpre); + r = install_dependent_modules(modpost); ret = ret ? : r; } } @@ -2012,9 +1821,6 @@ static int install_modules(int argc, char **argv) if (p != NULL) kerneldirlen = p - abskpath; - modules_suppliers = hashmap_new(string_hash_func, string_compare_func); - find_suppliers(ctx); - if (arg_hostonly) { char *modalias_file; modalias_file = getenv("DRACUT_KERNEL_MODALIASES"); @@ -2102,7 +1908,7 @@ static int install_modules(int argc, char **argv) } kmod_list_foreach(itr, modlist) { mod = kmod_module_get_module(itr); - r = install_module(ctx, mod); + r = install_module(mod); kmod_module_unref(mod); if ((r < 0) && !arg_optional) { if (!arg_silent) @@ -2181,7 +1987,7 @@ static int install_modules(int argc, char **argv) } kmod_list_foreach(itr, modlist) { mod = kmod_module_get_module(itr); - r = install_module(ctx, mod); + r = install_module(mod); kmod_module_unref(mod); if ((r < 0) && !arg_optional) { if (!arg_silent) @@ -2232,7 +2038,7 @@ static int install_modules(int argc, char **argv) } kmod_list_foreach(itr, modlist) { mod = kmod_module_get_module(itr); - r = install_module(ctx, mod); + r = install_module(mod); kmod_module_unref(mod); if ((r < 0) && !arg_optional) { if (!arg_silent) @@ -2333,10 +2139,8 @@ int main(int argc, char **argv) items = hashmap_new(string_hash_func, string_compare_func); items_failed = hashmap_new(string_hash_func, string_compare_func); - processed_suppliers = hashmap_new(string_hash_func, string_compare_func); - modalias_to_kmod = hashmap_new(string_hash_func, string_compare_func); - if (!items || !items_failed || !processed_suppliers || !modules_loaded) { + if (!items || !items_failed || !modules_loaded) { log_error("Out of memory"); r = EXIT_FAILURE; goto finish1; @@ -2397,28 +2201,9 @@ finish2: while ((i = hashmap_steal_first(items_failed))) item_free(i); - Hashmap *h; - while ((h = hashmap_steal_first(modules_suppliers))) { - while ((i = hashmap_steal_first(h))) { - item_free(i); - } - hashmap_free(h); - } - - while ((i = hashmap_steal_first(processed_suppliers))) - item_free(i); - - /* - * Note: modalias_to_kmod's values are freed implicitly by the kmod context destruction - * in kmod_unref(). - */ - hashmap_free(items); hashmap_free(items_failed); hashmap_free(modules_loaded); - hashmap_free(modules_suppliers); - hashmap_free(processed_suppliers); - hashmap_free(modalias_to_kmod); if (arg_mod_filter_path) regfree(&mod_filter_path); -- 2.46.0