aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2011-05-26 20:57:57 +0200
committerJon Masters <jcm@jonmasters.org>2011-05-30 23:01:31 -0400
commit799506a34a14df6cbea3e73cd32af26626fca5d3 (patch)
tree9c29c464af6177651bfee58bdd9a2d75d2960c99
parent9454d710137be3799f343cc9d0f833f0802e2111 (diff)
downloadmodule-init-tools-799506a34a14df6cbea3e73cd32af26626fca5d3.tar.gz
modprobe: implement precedence of configuration directories
Configuration files are parsed in alphabetic order, regardles of what directory they reside in. Furthermore, if several files by the same name exist in different directories only the one in the directory with highest precedence is loaded. The order of precedence is /run, /etc, /usr/local/lib, /lib. 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.c69
1 files changed, 44 insertions, 25 deletions
diff --git a/modprobe.c b/modprobe.c
index 9c8ba37..31beb9e 100644
--- a/modprobe.c
+++ b/modprobe.c
@@ -1050,6 +1050,13 @@ static int parse_config_scan(struct modprobe_conf *conf,
va_list filelist;
char *filename;
DIR *dir;
+ struct file_entry {
+ struct list_head node;
+ char *name;
+ char *path;
+ };
+ struct file_entry *fe, *fe_tmp;
+ LIST_HEAD(files_list);
int ret = 0;
va_start(filelist, removing);
@@ -1057,17 +1064,12 @@ static int parse_config_scan(struct modprobe_conf *conf,
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 */
+ /* sort files from directories into list, ignoring duplicates */
while ((i = readdir(dir)) != NULL) {
size_t len;
+ int cmp = -1;
if (i->d_name[0] == '.')
continue;
@@ -1081,30 +1083,29 @@ static int parse_config_scan(struct modprobe_conf *conf,
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);
+ fe = malloc(sizeof(struct file_entry));
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)
+ if ((cmp = strcmp(fe_tmp->name, i->d_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);
+ if (cmp != 0) {
+ fe->name = malloc(len + 1);
+ fe->path = malloc(strlen(filename) + 1);
+ strcpy(fe->name, i->d_name);
+ strcpy(fe->path, filename);
+
+ if (cmp < 0)
+ list_add_tail(&fe->node, &files_list);
+ else
+ list_add_tail(&fe->node, &fe_tmp->node);
+ } else
+ info("Ignoring config file %s/%s\n", filename, i->d_name);
+
}
+ closedir(dir);
ret = 1;
} else {
@@ -1113,6 +1114,24 @@ static int parse_config_scan(struct modprobe_conf *conf,
}
}
+ /* parse list of files */
+ list_for_each_entry_safe(fe, fe_tmp, &files_list, node) {
+ char *cfgfile;
+
+ nofail_asprintf(&cfgfile, "%s/%s", fe->path, fe->name);
+ if (!parse_config_file(cfgfile, conf,
+ dump_only, removing))
+ warn("Failed to open config file %s: %s\n",
+ cfgfile, strerror(errno));
+ else
+ info("Parsing config file %s\n", cfgfile);
+ free(cfgfile);
+ list_del(&fe->node);
+ free(fe->name);
+ free(fe->path);
+ free(fe);
+ }
+
va_end(filelist);
return ret;
}