#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;
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[];
};
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;
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);
}
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);
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;
}
hash_free(depmod->symbols);
- hash_free(depmod->modules_by_relpath);
+ hash_free(depmod->modules_by_uncrelpath);
hash_free(depmod->modules_by_name);
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;
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;
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)
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);
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;