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

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