Blame SOURCES/0065-Don-t-assume-make-default-just-because-set-index-was.patch

903092
From 0343d901cade475b6b92134cd45184316d80039f Mon Sep 17 00:00:00 2001
903092
From: Robert Marshall <rmarshall@redhat.com>
903092
Date: Tue, 13 Dec 2016 18:20:15 -0500
903092
Subject: [PATCH 65/69] Don't assume --make-default just because --set-index
903092
 was passed.
903092
903092
grubby previously made the assumption that every time a new
903092
boot entry gets added using --set-index, it should be the default. Due
903092
to this behavior, it also masked an logic error that prevented the
903092
selection of the proper index in cases where it was necessary to
903092
dynamically pick a new default boot entry, or to keep the existing
903092
default boot entry when its position in the config file moved.
903092
903092
Resolves: rhbz#1285601
903092
---
903092
 grubby.c | 136 ++++++++++++++++++++++++++++++++++++++++++++-------------------
903092
 1 file changed, 96 insertions(+), 40 deletions(-)
903092
903092
diff --git a/grubby.c b/grubby.c
903092
index 3929212..4e872c0 100644
903092
--- a/grubby.c
903092
+++ b/grubby.c
903092
@@ -2596,66 +2596,121 @@ void markRemovedImage(struct grubConfig *cfg, const char *image,
903092
 		entry->skip = 1;
903092
 }
903092
 
903092
-void setDefaultImage(struct grubConfig *config, int isUserSpecifiedKernelPath,
903092
+void setDefaultImage(struct grubConfig *config, int isAddingBootEntry,
903092
 		     const char *defaultKernelPath, int newBootEntryIsDefault,
903092
-		     const char *prefix, int flags, int newDefaultBootEntryIndex)
903092
+		     const char *prefix, int flags,
903092
+		     int newDefaultBootEntryIndex, int newBootEntryIndex)
903092
 {
903092
-	struct singleEntry *entry, *entry2, *newDefault;
903092
-	int i, j;
903092
+	struct singleEntry *bootEntry, *newDefault;
903092
+	int indexToVerify, firstKernelEntryIndex, currentLookupIndex;
903092
+
903092
+	/* handle the two cases where the user explictly picks the default
903092
+	 * boot entry index as it would exist post-modification */
903092
 
903092
+	/* Case 1: user chose to make the latest boot entry the default */
903092
 	if (newBootEntryIsDefault) {
903092
-		config->defaultImage = FIRST_ENTRY_INDEX;
903092
+		config->defaultImage = newBootEntryIndex;
903092
 		return;
903092
-	} else if ((newDefaultBootEntryIndex >= 0) && config->cfi->defaultIsIndex) {
903092
-		if (findEntryByIndex(config, newDefaultBootEntryIndex))
903092
+	}
903092
+
903092
+	/* Case 2: user picked an arbitrary index as the default boot entry */
903092
+	if (newDefaultBootEntryIndex >= FIRST_ENTRY_INDEX
903092
+	    && config->cfi->defaultIsIndex) {
903092
+		indexToVerify = newDefaultBootEntryIndex;
903092
+
903092
+		/* user chose to make latest boot entry the default */
903092
+		if (newDefaultBootEntryIndex == newBootEntryIndex) {
903092
+			config->defaultImage = newBootEntryIndex;
903092
+			return;
903092
+		}
903092
+
903092
+		/* the user picks the default index based on the
903092
+		 * order of the bootloader configuration after
903092
+		 * modification; ensure we are checking for the
903092
+		 * existence of the correct entry */
903092
+		if (newBootEntryIndex < newDefaultBootEntryIndex) {
903092
+			if (!config->isModified)
903092
+				indexToVerify--;
903092
+		}
903092
+
903092
+		/* verify the user selected index will exist */
903092
+		if (findEntryByIndex(config, indexToVerify)) {
903092
 			config->defaultImage = newDefaultBootEntryIndex;
903092
-		else
903092
+		} else {
903092
 			config->defaultImage = NO_DEFAULT_ENTRY;
903092
+		}
903092
+
903092
 		return;
903092
-	} else if (defaultKernelPath) {
903092
-		i = 0;
903092
-		if (findEntryByPath(config, defaultKernelPath, prefix, &i)) {
903092
-			config->defaultImage = i;
903092
-		} else {
903092
+	}
903092
+
903092
+	/* handle cases where the index value may shift */
903092
+
903092
+	/* check validity of existing default or first-entry-found
903092
+	   selection */
903092
+	if (defaultKernelPath) {
903092
+		/* user requested first-entry-found */
903092
+		if (!findEntryByPath(config, defaultKernelPath,
903092
+				     prefix, &firstKernelEntryIndex)) {
903092
+			/* don't change default if can't find match */
903092
 			config->defaultImage = NO_DEFAULT_ENTRY;
903092
 			return;
903092
 		}
903092
-	}
903092
 
903092
-	/* defaultImage now points to what we'd like to use, but before any order 
903092
-	   changes */
903092
-	if ((config->defaultImage == DEFAULT_SAVED) ||
903092
-	    (config->defaultImage == DEFAULT_SAVED_GRUB2))
903092
-		/* default is set to saved, we don't want to change it */
903092
-		return;
903092
+		config->defaultImage = firstKernelEntryIndex;
903092
 
903092
-	if (config->defaultImage >= FIRST_ENTRY_INDEX)
903092
-		entry = findEntryByIndex(config, config->defaultImage);
903092
-	else
903092
-		entry = NULL;
903092
+		/* this is where we start looking for decrement later */
903092
+		currentLookupIndex = config->defaultImage;
903092
 
903092
-	if (entry && !entry->skip) {
903092
-		/* we can preserve the default */
903092
-		if (isUserSpecifiedKernelPath)
903092
+		if (isAddingBootEntry && !config->isModified &&
903092
+		    (newBootEntryIndex < config->defaultImage)) {
903092
+			/* increment because new entry added before default */
903092
 			config->defaultImage++;
903092
-
903092
-		/* count the number of entries erased before this one */
903092
-		for (j = 0; j < config->defaultImage; j++) {
903092
-			entry2 = findEntryByIndex(config, j);
903092
-			if (entry2->skip)
903092
-				config->defaultImage--;
903092
 		}
903092
-	} else if (isUserSpecifiedKernelPath) {
903092
-		config->defaultImage = FIRST_ENTRY_INDEX;
903092
 	} else {
903092
-		/* Either we just erased the default (or the default line was bad
903092
-		 * to begin with) and didn't put a new one in. We'll use the first
903092
-		 * valid image. */
903092
+		/* use pre-existing default entry */
903092
+		currentLookupIndex = config->defaultImage;
903092
+
903092
+		if (isAddingBootEntry
903092
+		    && (newBootEntryIndex <= config->defaultImage)) {
903092
+			config->defaultImage++;
903092
+
903092
+			if (config->isModified) {
903092
+				currentLookupIndex++;
903092
+			}
903092
+		}
903092
+	}
903092
+
903092
+	/* sanity check - is this entry index valid? */
903092
+	bootEntry = findEntryByIndex(config, currentLookupIndex);
903092
+
903092
+	if ((bootEntry && bootEntry->skip) || !bootEntry) {
903092
+		/* entry is to be skipped or is invalid */
903092
+		if (isAddingBootEntry) {
903092
+			config->defaultImage = newBootEntryIndex;
903092
+			return;
903092
+		}
903092
 		newDefault =
903092
 		    findTemplate(config, prefix, &config->defaultImage, 1,
903092
 				 flags);
903092
-		if (!newDefault)
903092
+		if (!newDefault) {
903092
 			config->defaultImage = NO_DEFAULT_ENTRY;
903092
+		}
903092
+
903092
+		return;
903092
+	}
903092
+
903092
+	currentLookupIndex--;
903092
+
903092
+	/* decrement index by the total number of entries deleted */
903092
+
903092
+	for (indexToVerify = currentLookupIndex;
903092
+	     indexToVerify >= FIRST_ENTRY_INDEX; indexToVerify--) {
903092
+
903092
+		bootEntry = findEntryByIndex(config, indexToVerify);
903092
+
903092
+		if (bootEntry && bootEntry->skip) {
903092
+			config->defaultImage--;
903092
+		}
903092
 	}
903092
 }
903092
 
903092
@@ -5300,7 +5355,8 @@ int main(int argc, const char **argv)
903092
 	markRemovedImage(config, removeKernelPath, bootPrefix);
903092
 	markRemovedImage(config, removeMBKernel, bootPrefix);
903092
 	setDefaultImage(config, newKernelPath != NULL, defaultKernel,
903092
-			makeDefault, bootPrefix, flags, defaultIndex);
903092
+			makeDefault, bootPrefix, flags, defaultIndex,
903092
+			newIndex);
903092
 	setFallbackImage(config, newKernelPath != NULL);
903092
 	if (updateImage(config, updateKernelPath, bootPrefix, newKernelArgs,
903092
 			removeArgs, newMBKernelArgs, removeMBKernelArgs))
903092
-- 
903092
2.9.3
903092