From: Lucas De Marchi Date: Wed, 14 Dec 2011 17:21:10 +0000 (-0200) Subject: kmod_module: use 'modname/aliasname' as key for hash X-Git-Tag: v1~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=113c66a56290f68d55364f8d6f01aa5cbd02d514;p=thirdparty%2Fkmod.git kmod_module: use 'modname/aliasname' as key for hash 1 alias may correspond to more than 1 module. This would cause a conflict in the hash table when inserting a module there and bad things could happen. Now we use 'modname/aliasname' as key, '/aliasname' part being optional. Internally kmod_module_new_from_alias() will setup a 'modname/aliasname' string and pass to kmod_module_new_from_name() that will treat the case with a '/' in the name. User might call kmod_module_new_from_name() without any slashes, so the key my not contain it. --- diff --git a/TODO b/TODO index 30141071..28b4fcd6 100644 --- a/TODO +++ b/TODO @@ -32,8 +32,5 @@ Features: - dump configuration - use softdep, install and remove commands -Bugs: +Known Bugs: -* With last changes to the hash of kmod module's, if an alias resolves to more - than one module it will conflict in the table. The proper solution is to use - 'modname/modalias' as the hash key. diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index faa736e2..d26ce0ab 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -218,6 +218,7 @@ KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx, struct kmod_module *m; size_t namelen; char name_norm[NAME_MAX]; + char *namesep; if (ctx == NULL || name == NULL) return -ENOENT; @@ -241,10 +242,18 @@ KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx, m->ctx = kmod_ref(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); + namesep = strchr(m->name, '/'); + if (namesep != NULL) { + *namesep = '\0'; + m->alias = namesep + 1; + } + *mod = m; return 0; @@ -254,29 +263,22 @@ int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias, const char *name, struct kmod_module **mod) { int err; - struct kmod_module *m; + char key[NAME_MAX]; + size_t namelen = strlen(name); + size_t aliaslen = strlen(alias); - err = kmod_module_new_from_name(ctx, alias, mod); - if (err < 0) - return err; + if (namelen + aliaslen + 2 > NAME_MAX) + return -ENAMETOOLONG; - m = *mod; + memcpy(key, name, namelen); + memcpy(key + namelen + 1, alias, aliaslen + 1); + key[namelen] = '/'; - /* if module did not came from pool */ - if (m->alias == NULL) { - m->alias = m->name; - m->name = strdup(name); - if (m->name == NULL) - goto fail_oom; - } + err = kmod_module_new_from_name(ctx, key, mod); + if (err < 0) + return err; return 0; - -fail_oom: - ERR(ctx, "out of memory\n"); - kmod_module_unref(m); - *mod = NULL; - return err; } /** @@ -391,8 +393,6 @@ KMOD_EXPORT struct kmod_module *kmod_module_unref(struct kmod_module *mod) free(mod->install_commands); free(mod->remove_commands); free(mod->path); - if (mod->alias != NULL) - free(mod->name); free(mod); return NULL; }