diff options
author | Gustavo Sverzut Barbieri <barbieri@profusion.mobi> | 2011-12-11 20:37:01 -0200 |
---|---|---|
committer | Gustavo Sverzut Barbieri <barbieri@profusion.mobi> | 2011-12-11 20:58:22 -0200 |
commit | cb8d4d3e999b1213549fc41618e86bd4ac2f4814 (patch) | |
tree | ab92bb94df94d8a3b895a3208a9b400c33b4bca6 /libkmod | |
parent | c3d0a5f2ef7b9eba319ddb97ace2105000f10b07 (diff) | |
download | kmod-cb8d4d3e999b1213549fc41618e86bd4ac2f4814.tar.gz |
API-BREAK: kmod_new() takes a second parameter for configuration directory.
This is required by modprobe and also to help doing unit tests in future.
Diffstat (limited to 'libkmod')
-rw-r--r-- | libkmod/libkmod-config.c | 52 | ||||
-rw-r--r-- | libkmod/libkmod-private.h | 2 | ||||
-rw-r--r-- | libkmod/libkmod.c | 21 | ||||
-rw-r--r-- | libkmod/libkmod.h | 2 |
4 files changed, 52 insertions, 25 deletions
diff --git a/libkmod/libkmod-config.c b/libkmod/libkmod-config.c index dd3a036..0e4f92c 100644 --- a/libkmod/libkmod-config.c +++ b/libkmod/libkmod-config.c @@ -32,12 +32,6 @@ #include "libkmod.h" #include "libkmod-private.h" -static const char *config_files[] = { - "/run/modprobe.d", - "/etc/modprobe.d", - "/lib/modprobe.d", -}; - struct kmod_alias { char *name; char modname[]; @@ -458,7 +452,7 @@ fail_read: return NULL; } -int kmod_config_new(struct kmod_ctx *ctx, struct kmod_config **p_config) +int kmod_config_new(struct kmod_ctx *ctx, struct kmod_config **p_config, const char * const *config_paths) { struct kmod_config *config; size_t i; @@ -469,33 +463,49 @@ int kmod_config_new(struct kmod_ctx *ctx, struct kmod_config **p_config) config->ctx = ctx; - for (i = 0; i < ARRAY_SIZE(config_files); i++) { + for (i = 0; config_paths[i] != NULL; i++) { + const char *path = config_paths[i]; struct kmod_list *list = NULL; + struct stat st; DIR *d; - int fd; - d = conf_files_list(ctx, &list, config_files[i]); + if (stat(path, &st) != 0) { + DBG(ctx, "could not load '%s': %s\n", + path, strerror(errno)); + continue; + } + + if (S_ISREG(st.st_mode)) { + int fd = open(path, O_RDONLY); + DBG(ctx, "parsing file '%s': %d\n", path, fd); + if (fd >= 0) + kmod_config_parse(config, fd, path); + continue; + } else if (!S_ISDIR(st.st_mode)) { + ERR(ctx, "unsupported file mode %s: %#x\n", + path, st.st_mode); + continue; + } + + d = conf_files_list(ctx, &list, path); /* there's no entry */ if (list == NULL) continue; - - /* there's only one entry, and it's a file */ if (d == NULL) { - DBG(ctx, "parsing file '%s'\n", config_files[i]); - list = kmod_list_remove(list); - fd = open(config_files[i], O_RDONLY); - if (fd >= 0) - kmod_config_parse(config, fd, config_files[i]); - + ERR(ctx, "returned list but no directory?\n"); + while (list) { + free(list->data); + kmod_list_remove(list); + } continue; } /* treat all the entries in that dir */ for (; list != NULL; list = kmod_list_remove(list)) { - DBG(ctx, "parsing file '%s/%s'\n", config_files[i], - (char *) list->data); - fd = openat(dirfd(d), list->data, O_RDONLY); + int fd = openat(dirfd(d), list->data, O_RDONLY); + DBG(ctx, "parsing file '%s/%s': %d\n", path, + (const char *) list->data, fd); if (fd >= 0) kmod_config_parse(config, fd, list->data); diff --git a/libkmod/libkmod-private.h b/libkmod/libkmod-private.h index ce82964..3e21986 100644 --- a/libkmod/libkmod-private.h +++ b/libkmod/libkmod-private.h @@ -93,7 +93,7 @@ struct kmod_config { struct kmod_list *remove_commands; struct kmod_list *install_commands; }; -int kmod_config_new(struct kmod_ctx *ctx, struct kmod_config **config) __attribute__((nonnull(1))); +int kmod_config_new(struct kmod_ctx *ctx, struct kmod_config **config, const char * const *config_paths) __attribute__((nonnull(1, 2,3))); void kmod_config_free(struct kmod_config *config) __attribute__((nonnull(1))); const char *kmod_alias_get_name(const struct kmod_list *l) __attribute__((nonnull(1))); const char *kmod_alias_get_modname(const struct kmod_list *l) __attribute__((nonnull(1))); diff --git a/libkmod/libkmod.c b/libkmod/libkmod.c index a23bbbd..14c7a2c 100644 --- a/libkmod/libkmod.c +++ b/libkmod/libkmod.c @@ -57,6 +57,13 @@ static const char* index_files[] = { [KMOD_INDEX_SYMBOL] = "modules.symbols", }; +static const char *default_config_paths[] = { + "/run/modprobe.d", + "/etc/modprobe.d", + "/lib/modprobe.d", + NULL +}; + /** * kmod_ctx: * @@ -179,9 +186,17 @@ static char *get_kernel_release(const char *dirname) * The initial refcount is 1, and needs to be decremented to * release the resources of the kmod library context. * + * @dirname: what to consider as linux module's directory, if NULL + * defaults to /lib/modules/`uname -r` + * @config_paths: ordered array of paths (directories or files) where + * to load user-defined configuration parameters such as + * alias, blacklists, commands (install, remove). If + * NULL defaults to /run/modprobe.d, /etc/modprobe.d and + * /lib/modprobe.d. This array must be null terminated. + * * Returns: a new kmod library context */ -KMOD_EXPORT struct kmod_ctx *kmod_new(const char *dirname) +KMOD_EXPORT struct kmod_ctx *kmod_new(const char *dirname, const char * const *config_paths) { const char *env; struct kmod_ctx *ctx; @@ -203,7 +218,9 @@ KMOD_EXPORT struct kmod_ctx *kmod_new(const char *dirname) if (env != NULL) kmod_set_log_priority(ctx, log_priority(env)); - err = kmod_config_new(ctx, &ctx->config); + if (config_paths == NULL) + config_paths = default_config_paths; + err = kmod_config_new(ctx, &ctx->config, config_paths); if (err < 0) { ERR(ctx, "could not create config\n"); goto fail; diff --git a/libkmod/libkmod.h b/libkmod/libkmod.h index 130c703..3a13b9f 100644 --- a/libkmod/libkmod.h +++ b/libkmod/libkmod.h @@ -35,7 +35,7 @@ extern "C" { * environment, user variables, allows custom logging */ struct kmod_ctx; -struct kmod_ctx *kmod_new(const char *dirname); +struct kmod_ctx *kmod_new(const char *dirname, const char * const *config_dirs); struct kmod_ctx *kmod_ref(struct kmod_ctx *ctx); struct kmod_ctx *kmod_unref(struct kmod_ctx *ctx); void kmod_set_log_fn(struct kmod_ctx *ctx, |