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

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