Read config files from the following directories:

/run/modprobe.d
        config files generated at runtime, useful e.g. for compatibility
        with non-standard config files (such as /etc/rc.conf in Arch)
/etc/modprobe.d
        config files manually created by the administrator
/lib/modprobe.d
        config files installed by third-party packages
/usr/local/lib/modprobe.d
        config files during development of third-party packages

This scheme is the same as the one employed by udev, systemd and possibly
others.

A follow-up patch lets files in one directory override files in others, as
done elsewhere.

Cc: Jon Masters <[email protected]>
Cc: Kay Sievers <[email protected]>
Cc: Aaron Griffin <[email protected]>
Cc: Thomas Bächler <[email protected]>
Signed-off-by: Tom Gundersen <[email protected]>
---
 modprobe.c |  137 ++++++++++++++++++++++++++++++++----------------------------
 1 files changed, 73 insertions(+), 64 deletions(-)

diff --git a/modprobe.c b/modprobe.c
index 65de11a..9c8ba37 100644
--- a/modprobe.c
+++ b/modprobe.c
@@ -789,10 +789,9 @@ static char *strsep_skipspace(char **string, char *delim)
        return strsep(string, delim);
 }
 
-static int parse_config_scan(const char *filename,
-                            struct modprobe_conf *conf,
+static int parse_config_scan(struct modprobe_conf *conf,
                             int dump_only,
-                            int removing);
+                            int removing, ...);
 
 static int parse_config_file(const char *filename,
                            struct modprobe_conf *conf,
@@ -847,9 +846,9 @@ static int parse_config_file(const char *filename,
                                warn("\"include /etc/modprobe.d\" is "
                                     "the default, ignored\n");
                        } else {
-                               if (!parse_config_scan(newfilename,
-                                                      &newconf, dump_only,
-                                                      removing))
+                               if (!parse_config_scan(&newconf, dump_only,
+                                                      removing, newfilename,
+                                                      NULL))
                                        warn("Failed to open included"
                                              " config file %s: %s\n",
                                              newfilename, strerror(errno));
@@ -1044,70 +1043,77 @@ syntax_error:
        return 1;
 }
 
-static int parse_config_scan(const char *filename,
-                            struct modprobe_conf *conf,
+static int parse_config_scan(struct modprobe_conf *conf,
                             int dump_only,
-                            int removing)
+                            int removing, ...)
 {
+       va_list filelist;
+       char *filename;
        DIR *dir;
        int ret = 0;
 
-       dir = opendir(filename);
-       if (dir) {
-               struct file_entry {
-                       struct list_head node;
-                       char name[];
-               };
-               LIST_HEAD(files_list);
-               struct file_entry *fe, *fe_tmp;
-               struct dirent *i;
-
-               /* sort files from directory into list */
-               while ((i = readdir(dir)) != NULL) {
-                       size_t len;
-
-                       if (i->d_name[0] == '.')
-                               continue;
-                       if (!config_filter(i->d_name))
-                               continue;
-
-                       len = strlen(i->d_name);
-                       if (len < 6 ||
-                           (strcmp(&i->d_name[len-5], ".conf") != 0 &&
-                            strcmp(&i->d_name[len-6], ".alias") != 0))
-                               warn("All config files need .conf: %s/%s, "
-                                    "it will be ignored in a future 
release.\n",
-                                    filename, i->d_name);
-                       fe = malloc(sizeof(struct file_entry) + len + 1);
-                       if (fe == NULL)
-                               continue;
-                       strcpy(fe->name, i->d_name);
-                       list_for_each_entry(fe_tmp, &files_list, node)
-                               if (strcmp(fe_tmp->name, fe->name) >= 0)
-                                       break;
-                       list_add_tail(&fe->node, &fe_tmp->node);
-               }
-               closedir(dir);
-
-               /* parse list of files */
-               list_for_each_entry_safe(fe, fe_tmp, &files_list, node) {
-                       char *cfgfile;
-
-                       nofail_asprintf(&cfgfile, "%s/%s", filename, fe->name);
-                       if (!parse_config_file(cfgfile, conf,
-                                              dump_only, removing))
-                               warn("Failed to open config file "
-                                    "%s: %s\n", fe->name, strerror(errno));
-                       free(cfgfile);
-                       list_del(&fe->node);
-                       free(fe);
-               }
+       va_start(filelist, removing);
+
+       while ((filename = va_arg(filelist, char*))) {
+               dir = opendir(filename);
+               if (dir) {
+                       struct file_entry {
+                               struct list_head node;
+                               char name[];
+                       };
+                       LIST_HEAD(files_list);
+                       struct file_entry *fe, *fe_tmp;
+                       struct dirent *i;
+
+                       /* sort files from directory into list */
+                       while ((i = readdir(dir)) != NULL) {
+                               size_t len;
+
+                               if (i->d_name[0] == '.')
+                                       continue;
+                               if (!config_filter(i->d_name))
+                                       continue;
+
+                               len = strlen(i->d_name);
+                               if (len < 6 ||
+                                   (strcmp(&i->d_name[len-5], ".conf") != 0 &&
+                                    strcmp(&i->d_name[len-6], ".alias") != 0))
+                                       warn("All config files need .conf: 
%s/%s, "
+                                            "it will be ignored in a future 
release.\n",
+                                            filename, i->d_name);
+                               fe = malloc(sizeof(struct file_entry) + len + 
1);
+                               if (fe == NULL)
+                                       continue;
+                               strcpy(fe->name, i->d_name);
+                               list_for_each_entry(fe_tmp, &files_list, node)
+                                       if (strcmp(fe_tmp->name, fe->name) >= 0)
+                                               break;
+                               list_add_tail(&fe->node, &fe_tmp->node);
+                       }
+                       closedir(dir);
+
+                       /* parse list of files */
+                       list_for_each_entry_safe(fe, fe_tmp, &files_list, node) 
{
+                               char *cfgfile;
+
+                               nofail_asprintf(&cfgfile, "%s/%s", filename, 
fe->name);
+                               if (!parse_config_file(cfgfile, conf,
+                                                      dump_only, removing))
+                                       warn("Failed to open config file "
+                                            "%s: %s\n", fe->name, 
strerror(errno));
+                               free(cfgfile);
+                               list_del(&fe->node);
+                               free(fe);
+                       }
 
-               ret = 1;
-       } else {
-               if (parse_config_file(filename, conf, dump_only, removing))
                        ret = 1;
+               } else {
+                       if (parse_config_file(filename, conf, dump_only, 
removing))
+                               ret = 1;
+               }
        }
+
+       va_end(filelist);
        return ret;
 }
 
@@ -1117,7 +1123,8 @@ static void parse_toplevel_config(const char *filename,
                                  int removing)
 {
        if (filename) {
-               if (!parse_config_scan(filename, conf, dump_only, removing))
+               if (!parse_config_scan(conf, dump_only, removing, filename,
+                                      NULL))
                        fatal("Failed to open config file %s: %s\n",
                              filename, strerror(errno));
                return;
@@ -1130,7 +1137,9 @@ static void parse_toplevel_config(const char *filename,
                      "all config files belong into /etc/modprobe.d/.\n");
 
        /* default config */
-       parse_config_scan("/etc/modprobe.d", conf, dump_only, removing);
+       parse_config_scan(conf, dump_only, removing, "/run/modprobe.d",
+                         "/etc/modprobe.d", "/usr/local/lib/modprobe.d",
+                         "/lib/modprobe.d", NULL);
 }
 
 /* Read possible module arguments from the kernel command line. */
-- 
1.7.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-modules" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to