]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
API-BREAK: kmod_new() takes a second parameter for configuration directory.
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>
Sun, 11 Dec 2011 22:37:01 +0000 (20:37 -0200)
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>
Sun, 11 Dec 2011 22:58:22 +0000 (20:58 -0200)
This is required by modprobe and also to help doing unit tests in future.

18 files changed:
libkmod/libkmod-config.c
libkmod/libkmod-private.h
libkmod/libkmod.c
libkmod/libkmod.h
test/test-blacklist.c
test/test-get-dependencies.c
test/test-init.c
test/test-insmod.c
test/test-loaded.c
test/test-lookup.c
test/test-mod-double-ref.c
test/test-path-from-name.c
test/test-rmmod.c
test/test-rmmod2.c
tools/kmod-insmod.c
tools/kmod-lsmod.c
tools/kmod-modprobe.c
tools/kmod-rmmod.c

index dd3a036b77fcd2cd09c4a2fea014f27ae7510237..0e4f92cb0bc6ed5163ae1dbade3cff082b622900 100644 (file)
 #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);
 
index ce829643577429bea4075c9a86f1d9bfb52f88e9..3e219869ffe8aa40d48a94bf29518b8c7ef0cb0b 100644 (file)
@@ -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)));
index a23bbbdb65d344b7b84ab68368fb6591d8a38729..14c7a2c21263c7a9398f1a1c0d7ba1d8dab631c5 100644 (file)
@@ -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;
index 130c703b11a342725f9080e299905ba2f4523e65..3a13b9fcd1e9008982bdfb78057c923d2d2f9fe1 100644 (file)
@@ -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,
index 515bfb87fa51020dccdf97d19e0ab3e46ce2e4aa..a53c902e5f6c7b3a5cddeadcd3f7d6442d6ffd4e 100644 (file)
@@ -24,7 +24,7 @@ int main(int argc, char *argv[])
 
        alias = argv[1];
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (ctx == NULL)
                exit(EXIT_FAILURE);
 
index 266c5d4f4f739f04757613ff650ffc4702b1b1c0..3a7bbf2ecaa74b661117937609a414e8047e9158 100644 (file)
@@ -25,7 +25,7 @@ int main(int argc, char *argv[])
 
        name = argv[1];
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (ctx == NULL)
                exit(EXIT_FAILURE);
 
index 18317aafecb6bf913b64ec0b3600ecd7aad8ac63..081a47c3a166cb421c22e3adacb54063535c5ebb 100644 (file)
@@ -10,7 +10,7 @@ int main(int argc, char *argv[])
 {
        struct kmod_ctx *ctx;
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (ctx == NULL)
                exit(EXIT_FAILURE);
 
index 6deaf77ec115c98ede1b3a2b888e06396189c762..7198df073f5f0ad14962dadf9474516e9a05fab5 100644 (file)
@@ -22,7 +22,7 @@ int main(int argc, char *argv[])
 
        path = argv[1];
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (ctx == NULL)
                exit(EXIT_FAILURE);
 
index dc456958ad7b46014b74d9c627d0d8d80a085079..5f3dc587818f0549f88b566c663d56c56cd86303 100644 (file)
@@ -14,7 +14,7 @@ int main(int argc, char *argv[])
        struct kmod_list *list, *itr;
        int err;
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (ctx == NULL)
                exit(EXIT_FAILURE);
 
index 9f3bebcc90e15894b678378535cc3c939ae511fb..34d255d6e90a9a30e161ab8e2a4f59264eeb0626 100644 (file)
@@ -67,7 +67,7 @@ int main(int argc, char *argv[])
 
        alias = argv[optind];
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (ctx == NULL) {
                kmod_unref(ctx);
                exit(EXIT_FAILURE);
index 710957f60b005db657d82fd19619710fd5126f33..872fc7e78ad7676eb050cc66920366a5fe42bdc7 100644 (file)
@@ -22,7 +22,7 @@ int main(int argc, char *argv[])
 
        modname = argv[1];
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (ctx == NULL)
                exit(EXIT_FAILURE);
 
index c5f8ccad96a2b22ad8e39b9ed4c791ef499e5e0a..3f3d568a8cd35281a09e77121b7055a6f3232dd5 100644 (file)
@@ -22,7 +22,7 @@ int main(int argc, char *argv[])
 
        modname = argv[1];
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (ctx == NULL)
                exit(EXIT_FAILURE);
 
index e1b9fb4f21664e2b46daacee18e543700aee2195..c57a0a7453e6c26368443416f1b0d3a7e90e526d 100644 (file)
@@ -18,7 +18,7 @@ int main(int argc, char *argv[])
        if (argc == 2)
                modname = argv[1];
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (ctx == NULL)
                exit(EXIT_FAILURE);
 
index 5e3fa496e27a4b162f657fd76fa150f59cd1d012..7a7a0bac6fbc94005262db5424c1fa8853273993 100644 (file)
@@ -22,7 +22,7 @@ int main(int argc, char *argv[])
 
        modname = argv[1];
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (ctx == NULL)
                exit(EXIT_FAILURE);
 
index 10c269a3aa02a99da8571fc02e22bef2debe6e6f..29a6231e2988e997336da3c49ec6595ca725b752 100644 (file)
@@ -124,7 +124,7 @@ int main(int argc, char *argv[])
                opts[optslen] = '\0';
        }
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (!ctx) {
                fputs("Error: kmod_new() failed!\n", stderr);
                free(opts);
index 20d07579d4d235b7a1a7cdd7ee23fc8db8d50bc2..4f75fd4e0272ed991c4e878ba70de8159417ac92 100644 (file)
@@ -36,7 +36,7 @@ int main(int argc, char *argv[])
                return EXIT_FAILURE;
        }
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (ctx == NULL) {
                fputs("Error: kmod_new() failed!\n", stderr);
                return EXIT_FAILURE;
index 7b78e5ba3669adb06a5998af56ad53ddb7bc6e22..270edd39aa7fceef91cab75e56f5ef3c72a3616c 100644 (file)
@@ -947,11 +947,11 @@ int main(int argc, char **orig_argv)
 {
        struct kmod_ctx *ctx;
        char **args = NULL, **argv;
-       int nargs = 0;
+       const char **config_paths = NULL;
+       int nargs = 0, n_config_paths = 0;
        char dirname_buf[PATH_MAX];
        const char *dirname = NULL;
        const char *root = NULL;
-       const char *config = NULL;
        const char *kversion = NULL;
        const char *list_type = NULL;
        int use_all = 0;
@@ -1025,11 +1025,22 @@ int main(int argc, char **orig_argv)
                case 'n':
                        dry_run = 1;
                        break;
-               case 'C':
+               case 'C': {
+                       size_t bytes = sizeof(char *) * (n_config_paths + 2);
+                       void *tmp = realloc(config_paths, bytes);
+                       if (!tmp) {
+                               fputs("Error: out-of-memory\n", stderr);
+                               goto cmdline_failed;
+                       }
+                       config_paths = tmp;
+                       config_paths[n_config_paths] = optarg;
+                       n_config_paths++;
+                       config_paths[n_config_paths] = NULL;
+
                        env_modprobe_options_append("-C");
                        env_modprobe_options_append(optarg);
-                       config = optarg;
                        break;
+               }
                case 'd':
                        root = optarg;
                        break;
@@ -1101,7 +1112,7 @@ int main(int argc, char **orig_argv)
                dirname = dirname_buf;
        }
 
-       ctx = kmod_new(dirname);
+       ctx = kmod_new(dirname, config_paths);
        if (!ctx) {
                fputs("Error: kmod_new() failed!\n", stderr);
                goto cmdline_failed;
@@ -1140,11 +1151,12 @@ int main(int argc, char **orig_argv)
 
        if (argv != orig_argv)
                free(argv);
-
+       free(config_paths);
        return err >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 
 cmdline_failed:
        if (argv != orig_argv)
                free(argv);
+       free(config_paths);
        return EXIT_FAILURE;
 }
index 8963448b8722d5f2420d92415880bf19d11672ff..fe0d645e76cbb67744753513b9ce47c4d557e2b6 100644 (file)
@@ -146,7 +146,7 @@ int main(int argc, char *argv[])
                return EXIT_FAILURE;
        }
 
-       ctx = kmod_new(NULL);
+       ctx = kmod_new(NULL, NULL);
        if (!ctx) {
                fputs("Error: kmod_new() failed!\n", stderr);
                return EXIT_FAILURE;