385 lines
17 KiB
Diff
385 lines
17 KiB
Diff
|
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
|
||
|
@@ -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
|
||
|
|