]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
Do not cache softdeps list
authorLucas De Marchi <lucas.demarchi@profusion.mobi>
Tue, 27 Dec 2011 12:15:40 +0000 (10:15 -0200)
committerLucas De Marchi <lucas.demarchi@profusion.mobi>
Tue, 27 Dec 2011 12:40:51 +0000 (10:40 -0200)
This might include a circular dependency which would screw up the
refcounting because there's an internal reference.

libkmod/libkmod-module.c

index 4e19af92d694487721ef6ecb5a049cc246599bbb..9ad3f827297888d201cc9c247c79985ccf02220b 100644 (file)
@@ -53,10 +53,6 @@ struct kmod_module {
        char *options;
        const char *install_commands;   /* owned by kmod_config */
        const char *remove_commands;    /* owned by kmod_config */
-       struct {
-               struct kmod_list *pre;
-               struct kmod_list *post;
-       } softdeps;
        char *alias; /* only set if this module was created from an alias */
        int n_dep;
        int refcount;
@@ -65,7 +61,6 @@ struct kmod_module {
                bool options : 1;
                bool install_commands : 1;
                bool remove_commands : 1;
-               bool softdeps : 1;
        } init;
 };
 
@@ -407,8 +402,6 @@ KMOD_EXPORT struct kmod_module *kmod_module_unref(struct kmod_module *mod)
        DBG(mod->ctx, "kmod_module %p released\n", mod);
 
        kmod_pool_del_module(mod->ctx, mod, mod->hashkey);
-       kmod_module_unref_list(mod->softdeps.pre);
-       kmod_module_unref_list(mod->softdeps.post);
        kmod_module_unref_list(mod->dep);
        kmod_unref(mod->ctx);
        free(mod->options);
@@ -935,19 +928,21 @@ static struct kmod_list *lookup_softdep(struct kmod_ctx *ctx, const char * const
  * @post: where to save the list of post soft dependencies.
  *
  * Get soft dependencies for this kmod module. Soft dependencies come
- * from configuration file and are cached in @mod. The first call
- * to this function will search for this module in configuration and
- * subsequent calls return the known results.
+ * from configuration file and are not cached in @mod because it may include
+ * dependency cycles that would make we leak kmod_module. Any call
+ * to this function will search for this module in configuration, allocate a
+ * list and return the result.
  *
  * Both @pre and @post are newly created list of kmod_module and
  * should be unreferenced with kmod_module_unref_list().
  *
  * Returns: 0 on success or < 0 otherwise.
  */
-KMOD_EXPORT int kmod_module_get_softdeps(const struct kmod_module *mod, struct kmod_list **pre, struct kmod_list **post)
+KMOD_EXPORT int kmod_module_get_softdeps(const struct kmod_module *mod,
+                                               struct kmod_list **pre,
+                                               struct kmod_list **post)
 {
-       const struct kmod_list *l;
-       struct kmod_list *l_new;
+       const struct kmod_list *l, *ctx_softdeps;
 
        if (mod == NULL || pre == NULL || post == NULL)
                return -ENOENT;
@@ -955,64 +950,31 @@ KMOD_EXPORT int kmod_module_get_softdeps(const struct kmod_module *mod, struct k
        assert(*pre == NULL);
        assert(*post == NULL);
 
-       if (!mod->init.softdeps) {
-               /* lazy init */
-               struct kmod_module *m = (struct kmod_module *)mod;
-               const struct kmod_list *ctx_softdeps;
-
-               ctx_softdeps = kmod_get_softdeps(mod->ctx);
+       ctx_softdeps = kmod_get_softdeps(mod->ctx);
 
-               kmod_list_foreach(l, ctx_softdeps) {
-                       const char *modname = kmod_softdep_get_name(l);
-                       const char * const *array;
-                       unsigned count;
+       kmod_list_foreach(l, ctx_softdeps) {
+               const char *modname = kmod_softdep_get_name(l);
+               const char * const *array;
+               unsigned count;
 
-                       if (fnmatch(modname, mod->name, 0) != 0)
-                               continue;
-
-                       array = kmod_softdep_get_pre(l, &count);
-                       m->softdeps.pre = lookup_softdep(mod->ctx, array, count);
-                       array = kmod_softdep_get_post(l, &count);
-                       m->softdeps.post = lookup_softdep(mod->ctx, array, count);
-                       /*
-                        * find only the first command, as modprobe from
-                        * module-init-tools does
-                        */
-                       break;
-               }
-
-               m->init.softdeps = true;
-       }
+               if (fnmatch(modname, mod->name, 0) != 0)
+                       continue;
 
-       kmod_list_foreach(l, mod->softdeps.pre) {
-               l_new = kmod_list_append(*pre, kmod_module_ref(l->data));
-               if (l_new == NULL) {
-                       kmod_module_unref(l->data);
-                       goto fail;
-               }
-               *pre = l_new;
-       }
+               array = kmod_softdep_get_pre(l, &count);
+               *pre = lookup_softdep(mod->ctx, array, count);
+               array = kmod_softdep_get_post(l, &count);
+               *post = lookup_softdep(mod->ctx, array, count);
 
-       kmod_list_foreach(l, mod->softdeps.post) {
-               l_new = kmod_list_append(*post, kmod_module_ref(l->data));
-               if (l_new == NULL) {
-                       kmod_module_unref(l->data);
-                       goto fail;
-               }
-               *post = l_new;
+               /*
+                * find only the first command, as modprobe from
+                * module-init-tools does
+                */
+               break;
        }
 
        return 0;
-
-fail:
-       kmod_module_unref_list(*pre);
-       *pre = NULL;
-       kmod_module_unref_list(*post);
-       *post = NULL;
-       return -ENOMEM;
 }
 
-
 /**
  * kmod_module_get_remove_commands:
  * @mod: kmod module