summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas De Marchi <lucas.demarchi@intel.com>2022-02-15 19:12:05 -0800
committerLucas De Marchi <lucas.demarchi@intel.com>2022-02-20 20:58:11 -0800
commit82972710196442c503cc1068a05651c354a865fb (patch)
tree50782a5205e460843762a6c05bbfffc9f8d3846d
parent61a93a043aa52ad62a11ba940d4ba93cb3254e78 (diff)
downloadkmod-82972710196442c503cc1068a05651c354a865fb.tar.gz
kmod-82972710196442c503cc1068a05651c354a865fb.tar.bz2
kmod-82972710196442c503cc1068a05651c354a865fb.zip
libkmod: Add helper function to iterate lookup options
The CHECK_ERR_AND_FINISH macro with conditional code flow changes has been a source of bugs. Get rid of it replacing with a helper function to iterate an array of lookup functions. This helper may also be useful in future to create different lookup APIs in libkmod. Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
-rw-r--r--libkmod/libkmod-module.c82
1 files changed, 37 insertions, 45 deletions
diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
index 1b59c3c..7cb6d26 100644
--- a/libkmod/libkmod-module.c
+++ b/libkmod/libkmod-module.c
@@ -499,13 +499,26 @@ KMOD_EXPORT struct kmod_module *kmod_module_ref(struct kmod_module *mod)
return mod;
}
-#define CHECK_ERR_AND_FINISH(_err, _label_err, _list, label_finish) \
- do { \
- if ((_err) < 0) \
- goto _label_err; \
- if (*(_list) != NULL) \
- goto finish; \
- } while (0)
+typedef int (*lookup_func)(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3)));
+
+static int __kmod_module_new_from_lookup(struct kmod_ctx *ctx, const lookup_func lookup[],
+ size_t lookup_count, const char *s,
+ struct kmod_list **list)
+{
+ unsigned int i;
+
+ for (i = 0; i < lookup_count; i++) {
+ int err;
+
+ err = lookup[i](ctx, s, list);
+ if (err < 0 && err != -ENOSYS)
+ return err;
+ else if (*list != NULL)
+ return 0;
+ }
+
+ return 0;
+}
/**
* kmod_module_new_from_lookup:
@@ -538,8 +551,17 @@ KMOD_EXPORT int kmod_module_new_from_lookup(struct kmod_ctx *ctx,
const char *given_alias,
struct kmod_list **list)
{
- int err;
+ const lookup_func lookup[] = {
+ kmod_lookup_alias_from_config,
+ kmod_lookup_alias_from_moddep_file,
+ kmod_lookup_alias_from_symbols_file,
+ kmod_lookup_alias_from_commands,
+ kmod_lookup_alias_from_aliases_file,
+ kmod_lookup_alias_from_builtin_file,
+ kmod_lookup_alias_from_kernel_builtin_file,
+ };
char alias[PATH_MAX];
+ int err;
if (ctx == NULL || given_alias == NULL)
return -ENOENT;
@@ -556,48 +578,18 @@ KMOD_EXPORT int kmod_module_new_from_lookup(struct kmod_ctx *ctx,
DBG(ctx, "input alias=%s, normalized=%s\n", given_alias, alias);
- /* Aliases from config file override all the others */
- err = kmod_lookup_alias_from_config(ctx, alias, list);
- CHECK_ERR_AND_FINISH(err, fail, list, finish);
+ err = __kmod_module_new_from_lookup(ctx, lookup, sizeof(lookup),
+ alias, list);
- DBG(ctx, "lookup modules.dep %s\n", alias);
- err = kmod_lookup_alias_from_moddep_file(ctx, alias, list);
- CHECK_ERR_AND_FINISH(err, fail, list, finish);
-
- DBG(ctx, "lookup modules.symbols %s\n", alias);
- err = kmod_lookup_alias_from_symbols_file(ctx, alias, list);
- CHECK_ERR_AND_FINISH(err, fail, list, finish);
-
- DBG(ctx, "lookup install and remove commands %s\n", alias);
- err = kmod_lookup_alias_from_commands(ctx, alias, list);
- CHECK_ERR_AND_FINISH(err, fail, list, finish);
-
- DBG(ctx, "lookup modules.aliases %s\n", alias);
- err = kmod_lookup_alias_from_aliases_file(ctx, alias, list);
- CHECK_ERR_AND_FINISH(err, fail, list, finish);
-
- DBG(ctx, "lookup modules.builtin %s\n", alias);
- err = kmod_lookup_alias_from_builtin_file(ctx, alias, list);
- CHECK_ERR_AND_FINISH(err, fail, list, finish);
-
- DBG(ctx, "lookup modules.builtin.modinfo %s\n", alias);
- err = kmod_lookup_alias_from_kernel_builtin_file(ctx, alias, list);
- /* Optional index missing, ignore */
- if (err == -ENOSYS)
- err = 0;
- CHECK_ERR_AND_FINISH(err, fail, list, finish);
+ DBG(ctx, "lookup=%s found=%d\n", alias, err >= 0 && *list);
+ if (err < 0) {
+ kmod_module_unref_list(*list);
+ *list = NULL;
+ }
-finish:
- DBG(ctx, "lookup %s matches=%d, list=%p\n", alias, err, *list);
- return err > 0 ? 0 : err;
-fail:
- DBG(ctx, "Failed to lookup %s\n", alias);
- kmod_module_unref_list(*list);
- *list = NULL;
return err;
}
-#undef CHECK_ERR_AND_FINISH
/**
* kmod_module_unref_list: