aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucas De Marchi <lucas.de.marchi@gmail.com>2012-10-03 16:28:24 -0300
committerLucas De Marchi <lucas.de.marchi@gmail.com>2012-10-03 16:29:36 -0300
commit88c247f7f18ac25181ddcaff97fbbecbd3a29f57 (patch)
tree4c01236b51fef6560c36baf58c7ef088c089d08c
parentc5b37dba8956dd8f82c54b9f97dc5dca07940db5 (diff)
downloadkmod-88c247f7f18ac25181ddcaff97fbbecbd3a29f57.tar.gz
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.
-rw-r--r--tools/depmod.c46
1 files 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;