summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrett Grandbois <brett.grandbois@opengear.com>2018-04-19 07:55:15 +1000
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>2018-04-19 10:41:19 +1000
commit281b1398778cdcde08aa8a6a96d0d8c7794fd259 (patch)
tree662e80551d0e44b1166d3ff0a107eeb060f2378c
parentb014b38f115dcc1b47e52f8b5f9eb219f75ef071 (diff)
downloadtalos-petitboot-281b1398778cdcde08aa8a6a96d0d8c7794fd259.tar.gz
talos-petitboot-281b1398778cdcde08aa8a6a96d0d8c7794fd259.zip
discover/syslinux-parser: filter out duplicate conf files
in case insensitive filesystems like vfat the duplicate conf file list will create duplicate boot options. to filter that out strore the struct stat of each parsed conf file and compare inodes Signed-off-by: Brett Grandbois <brett.grandbois@opengear.com> Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
-rw-r--r--discover/syslinux-parser.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/discover/syslinux-parser.c b/discover/syslinux-parser.c
index b127494..be7b94a 100644
--- a/discover/syslinux-parser.c
+++ b/discover/syslinux-parser.c
@@ -36,6 +36,11 @@ struct syslinux_options {
char *cfg_dir;
};
+struct conf_file_stat {
+ char *name;
+ struct stat stat;
+ struct list_item list;
+};
static const char *const syslinux_conf_files[] = {
"/boot/syslinux/syslinux.cfg",
@@ -416,9 +421,12 @@ fail:
static int syslinux_parse(struct discover_context *dc)
{
+ struct conf_file_stat *confcmp, *confdat;
+ struct list processed_conf_files;
struct syslinux_options *state;
const char * const *filename;
struct conf_context *conf;
+ struct stat statbuf;
char *cfg_dir;
int len, rc;
char *buf;
@@ -441,6 +449,8 @@ static int syslinux_parse(struct discover_context *dc)
conf->parser_info = state = talloc_zero(conf, struct syslinux_options);
list_init(&state->processed_options);
+ list_init(&processed_conf_files);
+
/*
* set the global defaults
* by spec 'default' defaults to 'linux' and
@@ -453,10 +463,37 @@ static int syslinux_parse(struct discover_context *dc)
conf_set_global_option(conf, "append", "");
for (filename = syslinux_conf_files; *filename; filename++) {
+ /*
+ * guard against duplicate entries in case-insensitive
+ * filesystems, mainly vfat boot partitions
+ */
+ rc = parser_stat_path(dc, dc->device, *filename, &statbuf);
+ if (rc)
+ continue;
+
+ rc = 0;
+
+ list_for_each_entry(&processed_conf_files, confcmp, list) {
+ if (confcmp->stat.st_ino == statbuf.st_ino) {
+ pb_log("conf file %s is a path duplicate of %s..skipping\n",
+ *filename, confcmp->name);
+ rc = 1;
+ break;
+ }
+ }
+
+ if (rc)
+ continue;
+
rc = parser_request_file(dc, dc->device, *filename, &buf, &len);
if (rc)
continue;
+ confdat = talloc_zero(conf, struct conf_file_stat);
+ confdat->stat = statbuf;
+ confdat->name = talloc_strdup(confdat, *filename);
+ list_add(&processed_conf_files, &confdat->list);
+
/*
* save location of root config file for possible
* INCLUDE directives later
OpenPOWER on IntegriCloud