From 88c247f7f18ac25181ddcaff97fbbecbd3a29f57 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Wed, 3 Oct 2012 16:28:24 -0300 Subject: [PATCH] depmod: fix parsing of modules.order with compressed modules We now index the modules by uncompressed-relative-path instead of relative-path. This is because the file modules.order, coming from kernel, always comes with uncompressed paths. This fixes the issue of not sorting the aliases correctly due to paths not matching when using compressed modules. --- tools/depmod.c | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/tools/depmod.c b/tools/depmod.c index 0bf2dea..ff19d6e 100644 --- a/tools/depmod.c +++ b/tools/depmod.c @@ -39,6 +39,8 @@ #define DEFAULT_VERBOSE LOG_WARNING static int verbose = DEFAULT_VERBOSE; +#define KMOD_EXT_UNC 0 + static const struct kmod_ext { const char *ext; size_t len; @@ -1001,6 +1003,7 @@ struct mod { uint16_t idx; /* index in depmod->modules.array */ uint16_t users; /* how many modules depend on this one */ uint8_t dep_loop : 1; + char *uncrelpath; /* same as relpath but ending in .ko */ char modname[]; }; @@ -1014,7 +1017,7 @@ struct depmod { const struct cfg *cfg; struct kmod_ctx *ctx; struct array modules; - struct hash *modules_by_relpath; + struct hash *modules_by_uncrelpath; struct hash *modules_by_name; struct hash *symbols; unsigned int dep_loops; @@ -1025,6 +1028,7 @@ static void mod_free(struct mod *mod) DBG("free %p kmod=%p, path=%s\n", mod, mod->kmod, mod->path); array_free_array(&mod->deps); kmod_module_unref(mod->kmod); + free(mod->uncrelpath); free(mod); } @@ -1066,10 +1070,10 @@ static int depmod_init(struct depmod *depmod, struct cfg *cfg, array_init(&depmod->modules, 128); - depmod->modules_by_relpath = hash_new(512, NULL); - if (depmod->modules_by_relpath == NULL) { + depmod->modules_by_uncrelpath = hash_new(512, NULL); + if (depmod->modules_by_uncrelpath == NULL) { err = -errno; - goto modules_by_relpath_failed; + goto modules_by_uncrelpath_failed; } depmod->modules_by_name = hash_new(512, NULL); @@ -1089,8 +1093,8 @@ static int depmod_init(struct depmod *depmod, struct cfg *cfg, symbols_failed: hash_free(depmod->modules_by_name); modules_by_name_failed: - hash_free(depmod->modules_by_relpath); -modules_by_relpath_failed: + hash_free(depmod->modules_by_uncrelpath); +modules_by_uncrelpath_failed: return err; } @@ -1100,7 +1104,7 @@ static void depmod_shutdown(struct depmod *depmod) hash_free(depmod->symbols); - hash_free(depmod->modules_by_relpath); + hash_free(depmod->modules_by_uncrelpath); hash_free(depmod->modules_by_name); @@ -1114,7 +1118,7 @@ static void depmod_shutdown(struct depmod *depmod) static int depmod_module_add(struct depmod *depmod, struct kmod_module *kmod) { const struct cfg *cfg = depmod->cfg; - const char *modname; + const char *modname, *lastslash; size_t modnamelen; struct mod *mod; int err; @@ -1134,7 +1138,8 @@ static int depmod_module_add(struct depmod *depmod, struct kmod_module *kmod) array_init(&mod->deps, 4); mod->path = kmod_module_get_path(kmod); - mod->baselen = strrchr(mod->path, '/') - mod->path; + lastslash = strrchr(mod->path, '/'); + mod->baselen = lastslash - mod->path; if (strncmp(mod->path, cfg->dirname, cfg->dirnamelen) == 0 && mod->path[cfg->dirnamelen] == '/') mod->relpath = mod->path + cfg->dirnamelen + 1; @@ -1144,25 +1149,32 @@ static int depmod_module_add(struct depmod *depmod, struct kmod_module *kmod) err = hash_add_unique(depmod->modules_by_name, mod->modname, mod); if (err < 0) { ERR("hash_add_unique %s: %s\n", mod->modname, strerror(-err)); - free(mod); - return err; + goto fail; } if (mod->relpath != NULL) { - err = hash_add_unique(depmod->modules_by_relpath, - mod->relpath, mod); + size_t uncrelpathlen = lastslash - mod->relpath + modnamelen + + kmod_exts[KMOD_EXT_UNC].len; + mod->uncrelpath = memdup(mod->relpath, uncrelpathlen + 1); + mod->uncrelpath[uncrelpathlen] = '\0'; + err = hash_add_unique(depmod->modules_by_uncrelpath, + mod->uncrelpath, mod); if (err < 0) { ERR("hash_add_unique %s: %s\n", mod->relpath, strerror(-err)); hash_del(depmod->modules_by_name, mod->modname); - free(mod); - return err; + goto fail; } } DBG("add %p kmod=%p, path=%s\n", mod, kmod, mod->path); return 0; + +fail: + free(mod->uncrelpath); + free(mod); + return err; } static int depmod_module_del(struct depmod *depmod, struct mod *mod) @@ -1170,7 +1182,7 @@ static int depmod_module_del(struct depmod *depmod, struct mod *mod) DBG("del %p kmod=%p, path=%s\n", mod, mod->kmod, mod->path); if (mod->relpath != NULL) - hash_del(depmod->modules_by_relpath, mod->relpath); + hash_del(depmod->modules_by_uncrelpath, mod->relpath); hash_del(depmod->modules_by_name, mod->modname); @@ -1472,7 +1484,7 @@ static void depmod_modules_sort(struct depmod *depmod) continue; line[len - 1] = '\0'; - mod = hash_find(depmod->modules_by_relpath, line); + mod = hash_find(depmod->modules_by_uncrelpath, line); if (mod == NULL) continue; mod->sort_idx = idx - total; -- 1.7.12.4