From daf80bbb8f8ca5c4ad56772f379110e7434cbc2c Mon Sep 17 00:00:00 2001
From: classabbyamp <dev@placeviolette.net>
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
@@ -91,10 +91,7 @@ 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 *processed_deps = NULL;
-static Hashmap *modalias_to_kmod = NULL;
 static Hashmap *add_dlopen_features = NULL;
 static Hashmap *omit_dlopen_features = NULL;
 static Hashmap *dlopen_features[2] = NULL;
@@ -110,7 +107,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)
 {
@@ -2148,168 +2145,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:") != 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
-                char *parent_path = realpath(node_path, NULL);
-                if (parent_path != NULL)
-                        if (hashmap_put(suppliers, parent_path, parent_path) < 0)
-                                free(parent_path);
-        }
-}
-
-static void find_suppliers(struct kmod_ctx *ctx)
-{
-        _cleanup_fts_close_ FTS *fts = NULL;
-        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;
@@ -2343,21 +2179,21 @@ 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;
                         }
                 }
 #ifdef CONFIG_WEAKDEP
                 if (*err == 0) {
                         *err = kmod_module_get_weakdeps(mod, &modweak);
                         if (*err == 0)
-                                *err = install_dependent_modules(ctx, modweak, NULL);
+                                *err = install_dependent_modules(modweak);
                 }
 #endif
         } else {
@@ -2367,7 +2203,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;
@@ -2375,44 +2211,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);
-
-                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)) {
-                                        Hashmap *suppliers = find_suppliers_paths_for_module(kmod_module_get_name(mod));
-                                        if (install_dependent_module(ctx, mod, suppliers, &ret))
-                                                return -1;
-                                }
-                        }
-                } else { // Supplier is builtin
-                        _cleanup_destroy_hashmap_ Hashmap *suppliers = hashmap_new(string_hash_func, string_compare_func);
-                        find_suppliers_for_sys_node(suppliers, supplier_path, strlen(supplier_path));
-                        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;
@@ -2465,24 +2271,23 @@ 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;
                 }
         }
 #ifdef CONFIG_WEAKDEP
         if (ret == 0) {
                 ret = kmod_module_get_weakdeps(mod, &modweak);
                 if (ret == 0)
-                        ret = install_dependent_modules(ctx, modweak, NULL);
+                        ret = install_dependent_modules(modweak);
         }
 #endif

@@ -2593,9 +2398,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");
@@ -2683,7 +2485,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)
@@ -2763,7 +2565,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)
@@ -2813,7 +2615,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)
@@ -3006,15 +2808,13 @@ 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);
         processed_deps = hashmap_new(string_hash_func, string_compare_func);
-        modalias_to_kmod = hashmap_new(string_hash_func, string_compare_func);
 
         dlopen_features[0] = add_dlopen_features = hashmap_new(string_hash_func, string_compare_func);
         dlopen_features[1] = omit_dlopen_features = hashmap_new(string_hash_func, string_compare_func);

-        if (!items || !items_failed || !processed_suppliers || !modules_loaded ||
+        if (!items || !items_failed || !modules_loaded ||
             !processed_deps || !add_dlopen_features || !omit_dlopen_features) {
                 log_error("Out of memory");
                 r = EXIT_FAILURE;
                 goto finish1;
@@ -3082,47 +2882,10 @@ 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);
-
-        while ((i = hashmap_steal_first(processed_deps)))
-                item_free(i);
-
-        for (size_t j = 0; j < 2; j++) {
-                char ***array;
-                Iterator it;
-
-                HASHMAP_FOREACH(array, dlopen_features[j], it) {
-                        strv_free(*array);
-                        free(array);
-                }
-
-                while ((i = hashmap_steal_first_key(dlopen_features[j])))
-                        item_free(i);
-
-                hashmap_free(dlopen_features[j]);
-        }
-
-        /*
-         * 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(processed_deps);
-        hashmap_free(modalias_to_kmod);
 
         if (arg_mod_filter_path)
                 regfree(&mod_filter_path);
-- 
2.46.0

