aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2011-05-26 20:57:56 +0200
committerJon Masters <jcm@jonmasters.org>2011-05-30 23:01:27 -0400
commit9454d710137be3799f343cc9d0f833f0802e2111 (patch)
tree03d0cd36b3d3db2db3cc1961c16e48086bf83a17
parent69c099d4371aef5df2129816fefe50d51cb6ae19 (diff)
downloadmodule-init-tools-9454d710137be3799f343cc9d0f833f0802e2111.tar.gz
modprobe: use more than one config directory
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 <jcm@jonmasters.org> Cc: Kay Sievers <kay.sievers@vrfy.org> Cc: Aaron Griffin <aaron@archlinux.org> Cc: Thomas Bächler <thomas@archlinux.org> Signed-off-by: Tom Gundersen <teg@jklm.no> Signed-off-by: Jon Masters <jcm@jonmasters.org>
-rw-r--r--modprobe.c137
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. */