path_to_modname(name, name_norm, &namelen);
+ m = kmod_pool_get_module(ctx, name_norm);
+ if (m != NULL) {
+ *mod = kmod_module_ref(m);
+ return 0;
+ }
+
m = calloc(1, sizeof(*m) + namelen + 1);
if (m == NULL) {
free(m);
memcpy(m->name, name_norm, namelen + 1);
m->refcount = 1;
+ kmod_pool_add_module(ctx, m);
+
*mod = m;
return 0;
path_to_modname(path, name, &namelen);
+ m = kmod_pool_get_module(ctx, name);
+ if (m != NULL) {
+ *mod = kmod_module_ref(m);
+ return 0;
+ }
+
m = calloc(1, sizeof(*m) + namelen + 1);
if (m == NULL)
return -errno;
memcpy(m->name, name, namelen);
m->refcount = 1;
+ kmod_pool_add_module(ctx, m);
+
*mod = m;
return 0;
/* libkmod.c */
const char *kmod_get_dirname(const struct kmod_ctx *ctx) __attribute__((nonnull(1)));
+
int kmod_lookup_alias_from_config(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3)));
int kmod_lookup_alias_from_symbols_file(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3)));
int kmod_lookup_alias_from_aliases_file(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3)));
int kmod_lookup_alias_from_moddep_file(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3)));
+
char *kmod_search_moddep(struct kmod_ctx *ctx, const char *name) __attribute__((nonnull(1,2)));
+struct kmod_module *kmod_pool_get_module(struct kmod_ctx *ctx, const char *name) __attribute__((nonnull(1,2)));
+void kmod_pool_add_module(struct kmod_ctx *ctx, struct kmod_module *mod) __attribute__((nonnull(1,2)));
+void kmod_pool_del_module(struct kmod_ctx *ctx, struct kmod_module *mod) __attribute__((nonnull(1,2)));
+
+
/* libkmod-config.c */
struct kmod_config {
struct kmod_ctx *ctx;
#include "libkmod-private.h"
#include "libkmod-index.h"
+#define KMOD_HASH_SIZE (256)
+#define KMOD_LRU_MAX (128)
+
/**
* SECTION:libkmod
* @short_description: libkmod context
const void *userdata;
char *dirname;
struct kmod_config *config;
+ struct kmod_hash *modules_by_name;
};
void kmod_log(struct kmod_ctx *ctx,
err = kmod_config_new(ctx, &ctx->config);
if (err < 0) {
- ERR(ctx, "could not create config");
- free(ctx->dirname);
- free(ctx);
- return NULL;
+ ERR(ctx, "could not create config\n");
+ goto fail;
+ }
+
+ ctx->modules_by_name = kmod_hash_new(KMOD_HASH_SIZE, NULL);
+ if (ctx->modules_by_name == NULL) {
+ ERR(ctx, "could not create by-name hash\n");
+ goto fail;
}
INFO(ctx, "ctx %p created\n", ctx);
DBG(ctx, "log_priority=%d\n", ctx->log_priority);
return ctx;
+
+fail:
+ free(ctx->modules_by_name);
+ free(ctx->dirname);
+ free(ctx);
+ return NULL;
}
/**
if (--ctx->refcount > 0)
return ctx;
INFO(ctx, "context %p released\n", ctx);
+ kmod_hash_free(ctx->modules_by_name);
free(ctx->dirname);
if (ctx->config)
kmod_config_free(ctx->config);
ctx->log_priority = priority;
}
+struct kmod_module *kmod_pool_get_module(struct kmod_ctx *ctx,
+ const char *name)
+{
+ struct kmod_module *mod;
+
+ mod = kmod_hash_find(ctx->modules_by_name, name);
+
+ DBG(ctx, "get module name='%s' found=%p\n", name, mod);
+
+ return mod;
+}
+
+void kmod_pool_add_module(struct kmod_ctx *ctx, struct kmod_module *mod)
+{
+ const char *name = kmod_module_get_name(mod);
+
+ DBG(ctx, "add %p name='%s'\n", mod, name);
+
+ kmod_hash_add(ctx->modules_by_name, name, mod);
+}
+
+void kmod_pool_del_module(struct kmod_ctx *ctx, struct kmod_module *mod)
+{
+ const char *name = kmod_module_get_name(mod);
+
+ DBG(ctx, "del %p name='%s'\n", mod, name);
+
+ kmod_hash_del(ctx->modules_by_name, name);
+}
static int kmod_lookup_alias_from_alias_bin(struct kmod_ctx *ctx,
const char *file,