[PATCH 1/9] v2 add code to validate a grub2 entry

Gene Czarcinski gczarcinski at ec.rr.com
Mon Sep 15 12:50:44 UTC 2014


Add findValidEntryByIndex() to test for the comment
"### END /etc/grub.d/10_linux ###" indicating that the
previous entry was the last "valid" entry.  This prevents findTemplate()
from looking at entries created by 30_os-prober and 40_custom.

This new function is currently only used in findTemplate()
---
 grubby.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 55 insertions(+), 4 deletions(-)

diff --git a/grubby.c b/grubby.c
index 88a1f08..e47e97b 100644
--- a/grubby.c
+++ b/grubby.c
@@ -148,6 +148,7 @@ typedef const int (*writeLineFunc)(struct configFileInfo *,
 				struct singleLine *line);
 typedef char *(*getEnvFunc)(struct configFileInfo *, char *name);
 typedef int (*setEnvFunc)(struct configFileInfo *, char *name, char *value);
+typedef int (*validateEntryFunc)(struct singleEntry *entry);
 
 struct configFileInfo {
     char * defaultConfig;
@@ -155,6 +156,7 @@ struct configFileInfo {
     writeLineFunc writeLine;
     getEnvFunc getEnv;
     setEnvFunc setEnv;
+    validateEntryFunc validateEntry;
     struct keywordTypes * keywords;
     int caseInsensitive;
     int defaultIsIndex;
@@ -473,10 +475,29 @@ char *grub2ExtractTitle(struct singleLine * line) {
     return result;
 }
 
+static const char * endOfValidGrub2Entries = "### END /etc/grub.d/10_linux ###";
+
+int grub2ValidateEntry(struct singleEntry *entry) {
+    struct singleLine * line = entry->lines;
+    while(line != NULL) {
+	if ((line->numElements == 0) &&
+	    (line->type == LT_WHITESPACE) &&
+	    (line->indent != NULL) &&
+	    (strcmp(line->indent, endOfValidGrub2Entries) == 0)) {
+		dbgPrintf("findEntryByIndex() end valid entries: %s\n",
+		    endOfValidGrub2Entries);
+		return 0;
+	}
+	line = line->next;
+    }
+    return -1;
+}
+
 struct configFileInfo grub2ConfigType = {
     .findConfig = grub2FindConfig,
     .getEnv = grub2GetEnv,
     .setEnv = grub2SetEnv,
+    .validateEntry = grub2ValidateEntry,
     .keywords = grub2Keywords,
     .defaultIsIndex = 1,
     .defaultSupportSaved = 1,
@@ -654,6 +675,7 @@ struct grubConfig {
 blkid_cache blkid;
 
 struct singleEntry * findEntryByIndex(struct grubConfig * cfg, int index);
+struct singleEntry * findValidEntryByIndex(struct grubConfig * cfg, int index);
 struct singleEntry * findEntryByPath(struct grubConfig * cfg, 
 				     const char * path, const char * prefix,
 				     int * index);
@@ -2096,6 +2118,30 @@ struct singleEntry * findEntryByIndex(struct grubConfig * cfg, int index) {
     return entry;
 }
 
+/* ** code added to detect end of valid entries ** */
+/* A separate function because other code may depend on currect functionality. */
+/* Right now, findTemplate() is the ony use but there may be other places */
+/* this should be used instead of findEntryByIndex. */
+struct singleEntry * findValidEntryByIndex(struct grubConfig * cfg, int index) {
+    struct singleEntry * entry;
+
+    entry = cfg->entries;
+    while (index && entry) {
+	entry = entry->next;
+	index--;
+    }
+
+    if (entry == NULL)
+	return NULL;
+
+    if (cfg->cfi->validateEntry) {
+	if (!cfg->cfi->validateEntry(entry))
+	    return NULL;
+    }
+
+    return entry;
+}
+
 /* Find a good template to use for the new kernel. An entry is
  * good if the kernel and mkinitrd exist (even if the entry
  * is going to be removed). Try and use the default entry, but
@@ -2113,16 +2159,21 @@ struct singleEntry * findTemplate(struct grubConfig * cfg, const char * prefix,
 		int index = 0;
 		if (isnumber(defTitle)) {
 		    index = atoi(defTitle);
-		    entry = findEntryByIndex(cfg, index);
+		    entry = findValidEntryByIndex(cfg, index);
 		} else {
 		    entry = findEntryByTitle(cfg, defTitle, &index);
 		}
-		if (entry)
+		if (entry) {
 		    cfg->defaultImage = index;
+	            if (suitableImage(entry, prefix, skipRemoved, flags)) {
+	                dbgPrintf("suitable template found based on saved_entry");
+	                return entry;
+	            }
+		}
 	    }
 	}
     } else if (cfg->defaultImage > -1) {
-	entry = findEntryByIndex(cfg, cfg->defaultImage);
+	entry = findValidEntryByIndex(cfg, cfg->defaultImage);
 	if (entry && suitableImage(entry, prefix, skipRemoved, flags)) {
 	    if (indexPtr) *indexPtr = cfg->defaultImage;
 	    return entry;
@@ -2130,7 +2181,7 @@ struct singleEntry * findTemplate(struct grubConfig * cfg, const char * prefix,
     }
 
     index = 0;
-    while ((entry = findEntryByIndex(cfg, index))) {
+    while ((entry = findValidEntryByIndex(cfg, index))) {
 	if (suitableImage(entry, prefix, skipRemoved, flags)) {
             int j;
             for (j = 0; j < index; j++) {
-- 
1.9.3



More information about the anaconda-patches mailing list