Fix changing hash key after module is inserted in hash
authorLucas De Marchi <lucas.demarchi@profusion.mobi>
Thu, 15 Dec 2011 15:11:51 +0000 (13:11 -0200)
committerLucas De Marchi <lucas.demarchi@profusion.mobi>
Thu, 15 Dec 2011 15:48:19 +0000 (13:48 -0200)
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 <------------------*---'

libkmod/libkmod-module.c
libkmod/libkmod-private.h
libkmod/libkmod.c

index 80673e0..55ac1d2 100644 (file)
@@ -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;
 
index 6c6abca..50f3b66 100644 (file)
@@ -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)));
index e9ffd50..a949809 100644 (file)
@@ -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,