aboutsummaryrefslogtreecommitdiff
path: root/libkmod
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2011-12-11 20:37:01 -0200
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2011-12-11 20:58:22 -0200
commitcb8d4d3e999b1213549fc41618e86bd4ac2f4814 (patch)
treeab92bb94df94d8a3b895a3208a9b400c33b4bca6 /libkmod
parentc3d0a5f2ef7b9eba319ddb97ace2105000f10b07 (diff)
downloadkmod-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.c52
-rw-r--r--libkmod/libkmod-private.h2
-rw-r--r--libkmod/libkmod.c21
-rw-r--r--libkmod/libkmod.h2
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,