From 1d2f64689b2456ade81d6d489c4f5bfb5fdb92fd Mon Sep 17 00:00:00 2001 From: Dave Reisner Date: Tue, 31 Jan 2012 00:13:43 -0500 Subject: [PATCH 2/4] libkmod-module: used shared code in module creation --- libkmod/libkmod-module.c | 135 ++++++++++++++++++++++++++------------------- 1 files changed, 78 insertions(+), 57 deletions(-) diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index 47b1709..48e4aa1 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -162,6 +162,76 @@ fail: return err; } +/* + * Memory layout with alias: + * + * struct kmod_module { + * hashkey -----. + * alias -----. | + * name ----. | | + * } | | | + * name <----------' | | + * alias <-----------' | + * name\alias <--------' + * + * Memory layout without alias: + * + * struct kmod_module { + * hashkey ---. + * alias -----|----> NULL + * name ----. | + * } | | + * name <----------'-' + * + * @key is "name\alias" or "name" (in which case alias == NULL) + */ +static int kmod_module_new(struct kmod_ctx *ctx, const char *key, + const char *name, size_t namelen, + const char *alias, size_t aliaslen, + struct kmod_module **mod) +{ + struct kmod_module *m; + size_t keylen; + + m = kmod_pool_get_module(ctx, key); + if (m != NULL) { + *mod = kmod_module_ref(m); + return 0; + } + + if (alias == NULL) + keylen = namelen; + else + keylen = namelen + aliaslen + 1; + + m = malloc(sizeof(*m) + (alias == NULL ? 1 : 2) * (keylen + 1)); + if (m == NULL) { + free(m); + return -ENOMEM; + } + + memset(m, 0, sizeof(*m)); + + m->ctx = kmod_ref(ctx); + m->name = (char *)m + sizeof(*m); + memcpy(m->name, key, keylen + 1); + if (alias == NULL) { + m->hashkey = m->name; + m->alias = NULL; + } else { + m->name[namelen] = '\0'; + m->alias = m->name + namelen + 1; + m->hashkey = m->name + keylen + 1; + memcpy(m->hashkey, key, keylen + 1); + } + + m->refcount = 1; + kmod_pool_add_module(ctx, m, m->hashkey); + *mod = m; + + return 0; +} + /** * kmod_module_new_from_name: * @ctx: kmod library context @@ -188,54 +258,15 @@ KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx, const char *name, struct kmod_module **mod) { - struct kmod_module *m; size_t namelen; char name_norm[PATH_MAX]; - char *namesep; if (ctx == NULL || name == NULL || mod == NULL) return -ENOENT; - if (alias_normalize(name, name_norm, &namelen) < 0) { - DBG(ctx, "invalid alias: %s\n", name); - return -EINVAL; - } + modname_normalize(name, name_norm, &namelen); - m = kmod_pool_get_module(ctx, name_norm); - if (m != NULL) { - *mod = kmod_module_ref(m); - return 0; - } - - namesep = strchr(name_norm, '/'); - m = malloc(sizeof(*m) + (namesep == NULL ? 1 : 2) * namelen + 2); - if (m == NULL) { - free(m); - return -ENOMEM; - } - - memset(m, 0, sizeof(*m)); - - m->ctx = kmod_ref(ctx); - m->name = (char *)m + sizeof(*m); - memcpy(m->name, name_norm, namelen + 1); - - if (namesep) { - size_t len = namesep - name_norm; - - 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; + return kmod_module_new(ctx, name_norm, name_norm, namelen, NULL, 0, mod); } int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias, @@ -251,9 +282,9 @@ int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias, memcpy(key, name, namelen); memcpy(key + namelen + 1, alias, aliaslen + 1); - key[namelen] = '/'; + key[namelen] = '\\'; - err = kmod_module_new_from_name(ctx, key, mod); + err = kmod_module_new(ctx, key, name, namelen, alias, aliaslen, mod); if (err < 0) return err; @@ -323,7 +354,7 @@ KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx, free(abspath); else { ERR(ctx, "kmod_module '%s' already exists with different path: new-path='%s' old-path='%s'\n", - name, abspath, m->path); + name, abspath, m->path); free(abspath); return -EEXIST; } @@ -332,21 +363,11 @@ KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx, return 0; } - m = malloc(sizeof(*m) + namelen + 1); - if (m == NULL) - return -errno; - - memset(m, 0, sizeof(*m)); + err = kmod_module_new(ctx, name, name, namelen, NULL, 0, &m); + if (err < 0) + return err; - m->ctx = kmod_ref(ctx); - m->name = (char *)m + sizeof(*m); - memcpy(m->name, name, namelen + 1); m->path = abspath; - m->hashkey = m->name; - m->refcount = 1; - - kmod_pool_add_module(ctx, m, m->hashkey); - *mod = m; return 0; -- 1.7.9