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