From: Lucas De Marchi Date: Thu, 15 Dec 2011 15:11:51 +0000 (-0200) Subject: Fix changing hash key after module is inserted in hash X-Git-Tag: v1~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8bdeca11b14c2e1350b018386b9b91aa1a52dfcb;p=thirdparty%2Fkmod.git Fix changing hash key after module is inserted in hash The hash key is not copied so we can't change the string from: modname/modalias to: modname'\0'modalias in order to setup mod->name and mod->alias. Now what we do is: 1) if name is in the form 'modname/modalias', the final struct kmod_module will be: struct kmod_module { char *alias;------, char *name;-----, | char *hashkey;--|-|-, } | | | name <------------------' | | alias <-------------------' | hashkey <-------------------' 2) if name is in the simple form 'modname', then the final struct kmod_module will be: struct kmod_module { char *alias;------> NULL char *name;-----, char *hashkey;--|---, } | | name <------------------*---' --- diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index 80673e0d..55ac1d22 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -45,6 +45,7 @@ */ struct kmod_module { struct kmod_ctx *ctx; + char *hashkey; char *name; char *path; struct kmod_list *dep; @@ -231,7 +232,8 @@ KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx, return 0; } - m = malloc(sizeof(*m) + namelen + 1); + namesep = strchr(name_norm, '/'); + m = malloc(sizeof(*m) + (namesep == NULL ? 1 : 2) * namelen + 2); if (m == NULL) { free(m); return -ENOMEM; @@ -243,17 +245,19 @@ KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx, m->name = (char *)m + sizeof(*m); memcpy(m->name, name_norm, namelen + 1); - m->refcount = 1; - - /* set alias later, so m->name is still modname/modalias */ - kmod_pool_add_module(ctx, m); + if (namesep) { + size_t len = namesep - name_norm; - namesep = strchr(m->name, '/'); - if (namesep != NULL) { - *namesep = '\0'; - m->alias = namesep + 1; + m->name[len] = '\0'; + m->alias = m->name + len + 1; + m->hashkey = m->name + namelen + 1; + memcpy(m->hashkey, name_norm, namelen + 1); + } else { + m->hashkey = m->name; } + m->refcount = 1; + kmod_pool_add_module(ctx, m, m->hashkey); *mod = m; return 0; @@ -358,9 +362,10 @@ KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx, m->name = (char *)m + sizeof(*m); memcpy(m->name, name, namelen); m->path = abspath; + m->hashkey = m->name; m->refcount = 1; - kmod_pool_add_module(ctx, m); + kmod_pool_add_module(ctx, m, m->hashkey); *mod = m; diff --git a/libkmod/libkmod-private.h b/libkmod/libkmod-private.h index 6c6abca4..50f3b66f 100644 --- a/libkmod/libkmod-private.h +++ b/libkmod/libkmod-private.h @@ -77,9 +77,9 @@ int kmod_lookup_alias_from_moddep_file(struct kmod_ctx *ctx, const char *name, s 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))); +struct kmod_module *kmod_pool_get_module(struct kmod_ctx *ctx, const char *key) __attribute__((nonnull(1,2))); +void kmod_pool_add_module(struct kmod_ctx *ctx, struct kmod_module *mod, const char *key) __attribute__((nonnull(1,2, 3))); +void kmod_pool_del_module(struct kmod_ctx *ctx, struct kmod_module *mod, const char *key) __attribute__((nonnull(1,2, 3))); const struct kmod_list *kmod_get_options(const struct kmod_ctx *ctx) __must_check __attribute__((nonnull(1))); const struct kmod_list *kmod_get_install_commands(const struct kmod_ctx *ctx) __must_check __attribute__((nonnull(1))); diff --git a/libkmod/libkmod.c b/libkmod/libkmod.c index e9ffd506..a9498097 100644 --- a/libkmod/libkmod.c +++ b/libkmod/libkmod.c @@ -342,33 +342,31 @@ KMOD_EXPORT void kmod_set_log_priority(struct kmod_ctx *ctx, int priority) } struct kmod_module *kmod_pool_get_module(struct kmod_ctx *ctx, - const char *name) + const char *key) { struct kmod_module *mod; - mod = kmod_hash_find(ctx->modules_by_name, name); + mod = kmod_hash_find(ctx->modules_by_name, key); - DBG(ctx, "get module name='%s' found=%p\n", name, mod); + DBG(ctx, "get module name='%s' found=%p\n", key, mod); return mod; } -void kmod_pool_add_module(struct kmod_ctx *ctx, struct kmod_module *mod) +void kmod_pool_add_module(struct kmod_ctx *ctx, struct kmod_module *mod, + const char *key) { - const char *name = kmod_module_get_name(mod); + DBG(ctx, "add %p key='%s'\n", mod, key); - DBG(ctx, "add %p name='%s'\n", mod, name); - - kmod_hash_add(ctx->modules_by_name, name, mod); + kmod_hash_add(ctx->modules_by_name, key, mod); } -void kmod_pool_del_module(struct kmod_ctx *ctx, struct kmod_module *mod) +void kmod_pool_del_module(struct kmod_ctx *ctx, struct kmod_module *mod, + const char *key) { - const char *name = kmod_module_get_name(mod); - - DBG(ctx, "del %p name='%s'\n", mod, name); + DBG(ctx, "del %p key='%s'\n", mod, key); - kmod_hash_del(ctx->modules_by_name, name); + kmod_hash_del(ctx->modules_by_name, key); } static int kmod_lookup_alias_from_alias_bin(struct kmod_ctx *ctx,