From: Lucas De Marchi Date: Tue, 27 Dec 2011 12:15:40 +0000 (-0200) Subject: Do not cache softdeps list X-Git-Tag: v3~73 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2bd7cbf64409f11497a6bfb6d1d998a869783a95;p=thirdparty%2Fkmod.git Do not cache softdeps list This might include a circular dependency which would screw up the refcounting because there's an internal reference. --- diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index 4e19af92..9ad3f827 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -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