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

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