The package rpms/grub2.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/grub2.git/commit/?id=420527a50ba7....
Change:
+%ifarch ppc64 ppc64le
Thanks.
Full change:
============
commit 420527a50ba79920b3df3337cc7a641c4bdb006b
Author: Javier Martinez Canillas <javierm(a)redhat.com>
Date: Tue Oct 23 12:20:53 2018 +0200
A bunch of fixes for BLS
- add 10_linux_bls grub.d snippet to generate menu entries from BLS files
Resolves: rhbz#1636013
- Only set kernelopts in grubenv if it wasn't set before
Resolves: rhbz#1636466
- kernel-install: Remove existing initramfs if it's older than the kernel
(pjones)
Resolves: rhbz#1638405
- Update the saved entry correctly after a kernel install (pjones)
Resolves: rhbz#1638117
- blscfg: sort everything with rpm *package* comparison (pjones)
Related: rhbz#1638103
- blscfg: Make 10_linux_bls sort the same way as well
Related: rhbz#1638103
- don't set saved_entry on grub2-mkconfig
Resolves: rhbz#1636466
- Fix menu entry selection based on ID and title (pjones)
Resolves: rhbz#1640979
Signed-off-by: Javier Martinez Canillas <javierm(a)redhat.com>
diff --git a/0254-blscfg-don-t-include-.conf-at-the-end-of-our-id.patch
b/0254-blscfg-don-t-include-.conf-at-the-end-of-our-id.patch
new file mode 100644
index 0000000..59adb84
--- /dev/null
+++ b/0254-blscfg-don-t-include-.conf-at-the-end-of-our-id.patch
@@ -0,0 +1,41 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones(a)redhat.com>
+Date: Thu, 11 Oct 2018 15:30:13 -0400
+Subject: [PATCH] blscfg: don't include ".conf" at the end of our
"id".
+
+Related: rhbz#1638117
+
+Signed-off-by: Peter Jones <pjones(a)redhat.com>
+---
+ grub-core/commands/blscfg.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
+index bec5a9ffe3e..3847572dabd 100644
+--- a/grub-core/commands/blscfg.c
++++ b/grub-core/commands/blscfg.c
+@@ -575,6 +575,7 @@ static void create_entry (struct bls_entry *entry)
+ char **initrds = NULL;
+ char *initrd = NULL;
+ char *id = entry->filename;
++ char *dotconf = id;
+ char *hotkey = NULL;
+
+ char *users = NULL;
+@@ -593,6 +594,16 @@ static void create_entry (struct bls_entry *entry)
+ goto finish;
+ }
+
++ /*
++ * strip the ".conf" off the end before we make it our "id"
field.
++ */
++ do
++ {
++ dotconf = grub_strstr(dotconf, ".conf");
++ } while (dotconf != NULL && dotconf[5] != '\0');
++ if (dotconf)
++ dotconf[0] = '\0';
++
+ title = bls_get_val (entry, "title", NULL);
+ options = expand_val (bls_get_val (entry, "options", NULL));
+ initrds = bls_make_list (entry, "initrd", NULL);
diff --git a/0255-grub-get-kernel-settings-expose-some-more-config-var.patch
b/0255-grub-get-kernel-settings-expose-some-more-config-var.patch
new file mode 100644
index 0000000..2471e5f
--- /dev/null
+++ b/0255-grub-get-kernel-settings-expose-some-more-config-var.patch
@@ -0,0 +1,32 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones(a)redhat.com>
+Date: Thu, 11 Oct 2018 15:31:04 -0400
+Subject: [PATCH] grub-get-kernel-settings: expose some more config variables
+
+This exposes MAKEDEFAULT as GRUB_UPDATE_DEFAULT_KERNEL and DEFAULTDEBUG as
+GRUB_DEFAULT_TO_DEBUG
+
+Related: rhbz#1638117
+Signed-off-by: Peter Jones <pjones(a)redhat.com>
+---
+ util/grub-get-kernel-settings.in | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/util/grub-get-kernel-settings.in b/util/grub-get-kernel-settings.in
+index 12046219878..7e87dfccc0e 100644
+--- a/util/grub-get-kernel-settings.in
++++ b/util/grub-get-kernel-settings.in
+@@ -76,3 +76,13 @@ if [ "$MAKEDEBUG" = "yes" ]; then
+ echo GRUB_LINUX_DEBUG_TITLE_POSTFIX=\" with debugging\"
+ echo export GRUB_LINUX_DEBUG_TITLE_POSTFIX
+ fi
++if [ "$DEFAULTDEBUG" = "yes" ]; then
++ echo GRUB_DEFAULT_TO_DEBUG=true
++else
++ echo GRUB_DEFAULT_TO_DEBUG=false
++fi
++echo export GRUB_DEFAULT_TO_DEBUG
++if [ "$UPDATEDEFAULT" = "yes" ]; then
++ echo GRUB_UPDATE_DEFAULT_KERNEL=true
++ echo export GRUB_UPDATE_DEFAULT_KERNEL
++fi
diff --git a/0256-Reimplement-boot_counter.patch b/0256-Reimplement-boot_counter.patch
new file mode 100644
index 0000000..9091c9e
--- /dev/null
+++ b/0256-Reimplement-boot_counter.patch
@@ -0,0 +1,31 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones(a)redhat.com>
+Date: Thu, 4 Oct 2018 14:22:09 -0400
+Subject: [PATCH] Reimplement boot_counter
+
+This adds "increment" and "decrement" commands, and uses them to
maintain our
+variables in 01_fallback_counter. It also simplifies the counter logic, so
+that there are no nested tests that conflict with each other.
+
+Apparently, this *really* wasn't tested well enough.
+
+Resolves: rhbz#1614637
+Signed-off-by: Peter Jones <pjones(a)redhat.com>
+---
+ util/grub.d/01_fallback_counting.in | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/util/grub.d/01_fallback_counting.in b/util/grub.d/01_fallback_counting.in
+index 6ca13da03df..1a0b5fbecfc 100644
+--- a/util/grub.d/01_fallback_counting.in
++++ b/util/grub.d/01_fallback_counting.in
+@@ -1,5 +1,9 @@
+ #! /bin/sh -e
+
++if ! systemctl -q is-enabled greenboot.service >/dev/null 2>&1 ; then
++ exit 0
++fi
++
+ # Boot Counting
+ cat << EOF
+ insmod increment
diff --git a/0257-add-10_linux_bls-grub.d-snippet-to-generate-menu-ent.patch
b/0257-add-10_linux_bls-grub.d-snippet-to-generate-menu-ent.patch
new file mode 100644
index 0000000..75d9be4
--- /dev/null
+++ b/0257-add-10_linux_bls-grub.d-snippet-to-generate-menu-ent.patch
@@ -0,0 +1,485 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Javier Martinez Canillas <javierm(a)redhat.com>
+Date: Wed, 3 Oct 2018 20:48:32 +0200
+Subject: [PATCH] add 10_linux_bls grub.d snippet to generate menu entries from
+ BLS files
+
+This grub.d snippet can be used on platforms where the bootloader doesn't
+have BLS support and only can parse a normal grub configuration file.
+
+Portions of this script were taken from the ostree-grub-generator script
+included in the OSTree project.
+
+Resolves: rhbz#1636013
+
+Signed-off-by: Javier Martinez Canillas <javierm(a)redhat.com>
+---
+ Makefile.util.def | 7 +
+ util/grub.d/10_linux_bls.in | 440 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 447 insertions(+)
+ create mode 100644 util/grub.d/10_linux_bls.in
+
+diff --git a/Makefile.util.def b/Makefile.util.def
+index c8cb91308d9..eca3dfa753f 100644
+--- a/Makefile.util.def
++++ b/Makefile.util.def
+@@ -508,6 +508,13 @@ script = {
+ condition = COND_HOST_LINUX;
+ };
+
++script = {
++ name = '10_linux_bls';
++ common = util/grub.d/10_linux_bls.in;
++ installdir = grubconf;
++ condition = COND_HOST_LINUX;
++};
++
+ script = {
+ name = '10_xnu';
+ common = util/grub.d/10_xnu.in;
+diff --git a/util/grub.d/10_linux_bls.in b/util/grub.d/10_linux_bls.in
+new file mode 100644
+index 00000000000..3cc7803c6a1
+--- /dev/null
++++ b/util/grub.d/10_linux_bls.in
+@@ -0,0 +1,440 @@
++#! /bin/sh
++set -e
++
++# grub-mkconfig helper script.
++# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
++#
++# GRUB is free software: you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation, either version 3 of the License, or
++# (at your option) any later version.
++#
++# GRUB is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with GRUB. If not, see <
http://www.gnu.org/licenses/>.
++
++prefix="@prefix@"
++exec_prefix="@exec_prefix@"
++datarootdir="@datarootdir@"
++
++. "$pkgdatadir/grub-mkconfig_lib"
++
++export TEXTDOMAIN=@PACKAGE@
++export TEXTDOMAINDIR="@localedir@"
++
++CLASS="--class gnu-linux --class gnu --class os --unrestricted"
++
++if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
++ OS="$(eval $(grep PRETTY_NAME /etc/os-release) ; echo ${PRETTY_NAME})"
++ CLASS="--class $(eval $(grep '^ID_LIKE=\|^ID=' /etc/os-release) ; [ -n
"${ID_LIKE}" ] && echo ${ID_LIKE} || echo ${ID}) ${CLASS}"
++else
++ OS="${GRUB_DISTRIBUTOR}"
++ CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut
-d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}"
++fi
++
++# loop-AES arranges things so that /dev/loop/X can be our root device, but
++# the initrds that Linux uses don't like that.
++case ${GRUB_DEVICE} in
++ /dev/loop/*|/dev/loop[0-9])
++ GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e
"s/^[^(]*(\([^)]\+\)).*/\1/"`
++ ;;
++esac
++
++# Default to disabling partition uuid support to maintian compatibility with
++# older kernels.
++GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true}
++
++# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
++# and mounting btrfs requires user space scanning, so force UUID in this case.
++if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [
"x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \
++ || ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
++ && [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \
++ || ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
++ && ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \
++ || ( test -e "${GRUB_DEVICE}" && uses_abstraction
"${GRUB_DEVICE}" lvm ); then
++ LINUX_ROOT_DEVICE=${GRUB_DEVICE}
++elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \
++ || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then
++ LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID}
++else
++ LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
++fi
++
++case x"$GRUB_FS" in
++ xbtrfs)
++ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ]; then
++ GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX} \${extra_cmdline}"
++ else
++ rootsubvol="`make_system_path_relative_to_its_root /`"
++ rootsubvol="${rootsubvol#/}"
++ if [ "x${rootsubvol}" != x ]; then
++ GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol}
${GRUB_CMDLINE_LINUX}"
++ fi
++ fi;;
++ xzfs)
++ rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
++ bootfs="`make_system_path_relative_to_its_root / | sed -e
"s,@$,,"`"
++ LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs}"
++ ;;
++esac
++
++mktitle ()
++{
++ local title_type
++ local version
++ local OS_NAME
++ local OS_VERS
++
++ title_type=$1 && shift
++ version=$1 && shift
++
++ OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})"
++ OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})"
++
++ case $title_type in
++ recovery)
++ title=$(printf '%s (%s) %s (recovery mode)' \
++ "${OS_NAME}" "${version}"
"${OS_VERS}")
++ ;;
++ *)
++ title=$(printf '%s (%s) %s' \
++ "${OS_NAME}" "${version}"
"${OS_VERS}")
++ ;;
++ esac
++ echo -n ${title}
++}
++
++title_correction_code=
++
++populate_header_warn()
++{
++cat <<EOF
++
++# This section was generated by a script. Do not modify the generated file - all
changes
++# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec
files.
++
++EOF
++}
++
++read_config()
++{
++ config_file=${1}
++ title=""
++ initrd=""
++ options=""
++ linux=""
++
++ while read -r line
++ do
++ record=$(echo ${line} | cut -f 1 -d ' ')
++ value=$(echo ${line} | cut -s -f2- -d ' ')
++ case "${record}" in
++ "title")
++ title=${value}
++ ;;
++ "initrd")
++ initrd=${value}
++ ;;
++ "linux")
++ linux=${value}
++ ;;
++ "options")
++ options=${value}
++ ;;
++ esac
++ done < ${config_file}
++}
++
++populate_menu()
++{
++ entries_path="/boot/loader/entries"
++ gettext_printf "Generating boot entries from BLS files...\n" >&2
++ for config in $(ls -v -r $entries_path/*.conf); do
++ read_config ${config}
++ menu="${menu}menuentry '${title}' {\n"
++ menu="${menu}\t linux ${linux} ${options}\n"
++ if [ -n "${initrd}" ] ; then
++ menu="${menu}\t initrd ${boot_prefix}${initrd}\n"
++ fi
++ menu="${menu}}\n\n"
++ done
++ # The printf command seems to be more reliable across shells for special character
(\n, \t) evaluation
++ printf "$menu"
++}
++
++linux_entry ()
++{
++ os="$1"
++ version="$2"
++ type="$3"
++ isdebug="$4"
++ args="$5"
++
++ if [ -z "$boot_device_id" ]; then
++ boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
++ fi
++
++ if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then
++ if [ x$dirname = x/ ]; then
++ if [ -z "${prepare_root_cache}" ]; then
++ prepare_grub_to_access_device ${GRUB_DEVICE}
++ fi
++ else
++ if [ -z "${prepare_boot_cache}" ]; then
++ prepare_grub_to_access_device ${GRUB_DEVICE_BOOT}
++ fi
++ fi
++
++ if [ -d /sys/firmware/efi ]; then
++ bootefi_device="`${grub_probe} --target=device /boot/efi/`"
++ prepare_grub_to_access_device ${bootefi_device} boot
++ else
++ boot_device="`${grub_probe} --target=device /boot/`"
++ prepare_grub_to_access_device ${boot_device} boot
++ fi
++
++ populate_header_warn
++ populate_menu
++
++ ${grub_editenv} - set saved_entry=0
++ ${grub_editenv} - set kernelopts="root=${linux_root_device_thisversion} ro
${args}"
++
++ exit 0
++ fi
++
++ if [ x$type != xsimple ] ; then
++ title=$(mktitle "$type" "$version")
++ if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [
x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ];
then
++ replacement_title="$(echo "Advanced options for ${OS}" | sed
's,>,>>,g')>$(echo "$title" | sed
's,>,>>,g')"
++ quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
++ title_correction_code="${title_correction_code}if [ \"x\$default\" =
'$quoted' ]; then default='$(echo "$replacement_title" |
grub_quote)'; fi;"
++ fi
++ if [ x$isdebug = xdebug ]; then
++ title="$title${GRUB_LINUX_DEBUG_TITLE_POSTFIX}"
++ fi
++ echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS}
\$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed
"s/^/$submenu_indentation/"
++ else
++ echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS}
\$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed
"s/^/$submenu_indentation/"
++ fi
++ if [ x$type != xrecovery ] ; then
++ save_default_entry | grub_add_tab
++ fi
++
++ # Use ELILO's generic "efifb" when it's known to be available.
++ # FIXME: We need an interface to select vesafb in case efifb can't be used.
++ if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then
++ echo " load_video" | sed "s/^/$submenu_indentation/"
++ if grep -qx "CONFIG_FB_EFI=y" "${config}" 2> /dev/null \
++ && grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" "${config}"
2> /dev/null; then
++ echo " set gfxpayload=keep" | sed "s/^/$submenu_indentation/"
++ fi
++ else
++ if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then
++ echo " load_video" | sed "s/^/$submenu_indentation/"
++ fi
++ echo " set gfxpayload=$GRUB_GFXPAYLOAD_LINUX" | sed
"s/^/$submenu_indentation/"
++ fi
++
++ echo " insmod gzio" | sed "s/^/$submenu_indentation/"
++
++ if [ x$dirname = x/ ]; then
++ if [ -z "${prepare_root_cache}" ]; then
++ prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} |
grub_add_tab)"
++ fi
++ printf '%s\n' "${prepare_root_cache}" | sed
"s/^/$submenu_indentation/"
++ else
++ if [ -z "${prepare_boot_cache}" ]; then
++ prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} |
grub_add_tab)"
++ fi
++ printf '%s\n' "${prepare_boot_cache}" | sed
"s/^/$submenu_indentation/"
++ fi
++ sed "s/^/$submenu_indentation/" << EOF
++ linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
++EOF
++ if test -n "${initrd}" ; then
++ initrd_path=
++ for i in ${initrd}; do
++ initrd_path="${initrd_path} ${rel_dirname}/${i}"
++ done
++ sed "s/^/$submenu_indentation/" << EOF
++ initrd $(echo $initrd_path)
++EOF
++ fi
++ if test -n "${fdt}" ; then
++ sed "s/^/$submenu_indentation/" << EOF
++ devicetree ${rel_dirname}/${fdt}
++EOF
++ fi
++ sed "s/^/$submenu_indentation/" << EOF
++}
++EOF
++}
++
++machine=`uname -m`
++case "x$machine" in
++ xi?86 | xx86_64)
++ list=
++ for i in /boot/vmlinuz-* /vmlinuz-* /boot/kernel-* ; do
++ if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
++ done ;;
++ *)
++ list=
++ for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* /boot/kernel-* ; do
++ if grub_file_is_not_garbage "$i" ; then list="$list
$i" ; fi
++ done ;;
++esac
++
++if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then
++ for i in /boot/ostree/*/vmlinuz-* ; do
++ if grub_file_is_not_garbage "$i" ; then list="$list $i" ;
fi
++ done
++fi
++
++case "$machine" in
++ i?86) GENKERNEL_ARCH="x86" ;;
++ mips|mips64) GENKERNEL_ARCH="mips" ;;
++ mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;;
++ arm*) GENKERNEL_ARCH="arm" ;;
++ *) GENKERNEL_ARCH="$machine" ;;
++esac
++
++prepare_boot_cache=
++prepare_root_cache=
++boot_device_id=
++title_correction_code=
++
++# Extra indentation to add to menu entries in a submenu. We're not in a submenu
++# yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
++submenu_indentation=""
++
++is_top_level=true
++while [ "x$list" != "x" ] ; do
++ linux=`version_find_latest $list`
++ if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then
++ gettext_printf "Found linux image: %s\n" "$linux" >&2
++ fi
++
++ basename=`basename $linux`
++ dirname=`dirname $linux`
++ rel_dirname=`make_system_path_relative_to_its_root $dirname`
++ version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
++ alt_version=`echo $version | sed -e "s,\.old$,,g"`
++ linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
++
++ initrd_early=
++ for i in ${GRUB_EARLY_INITRD_LINUX_STOCK} \
++ ${GRUB_EARLY_INITRD_LINUX_CUSTOM}; do
++ if test -e "${dirname}/${i}" ; then
++ initrd_early="${initrd_early} ${i}"
++ fi
++ done
++
++ initrd_real=
++ for i in "initrd.img-${version}" "initrd-${version}.img"
"initrd-${version}.gz" \
++ "initrd-${version}" "initramfs-${version}.img" \
++ "initrd.img-${alt_version}" "initrd-${alt_version}.img" \
++ "initrd-${alt_version}" "initramfs-${alt_version}.img" \
++ "initramfs-genkernel-${version}" \
++ "initramfs-genkernel-${alt_version}" \
++ "initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
++ "initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do
++ if test -e "${dirname}/${i}" ; then
++ initrd_real="${i}"
++ break
++ fi
++ done
++
++ initrd=
++ if test -n "${initrd_early}" || test -n "${initrd_real}"; then
++ initrd="${initrd_early} ${initrd_real}"
++
++ initrd_display=
++ for i in ${initrd}; do
++ initrd_display="${initrd_display} ${dirname}/${i}"
++ done
++ if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then
++ gettext_printf "Found initrd image: %s\n" "$(echo
$initrd_display)" >&2
++ fi
++ fi
++
++ fdt=
++ for i in "dtb-${version}" "dtb-${alt_version}"; do
++ if test -f "${dirname}/${i}/${GRUB_DEFAULT_DTB}" ; then
++ fdt="${i}/${GRUB_DEFAULT_DTB}"
++ break
++ fi
++ done
++
++ config=
++ for i in "${dirname}/config-${version}"
"${dirname}/config-${alt_version}"
"/etc/kernels/kernel-config-${version}" ; do
++ if test -e "${i}" ; then
++ config="${i}"
++ break
++ fi
++ done
++
++ initramfs=
++ if test -n "${config}" ; then
++ initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr
-d \"`
++ fi
++
++ if test -z "${initramfs}" && test -z "${initrd_real}" ;
then
++ # "UUID=" and "ZFS=" magic is parsed by initrd or initramfs.
Since there's
++ # no initrd or builtin initramfs, it can't work here.
++ if [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] \
++ || [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ]; then
++
++ linux_root_device_thisversion=${GRUB_DEVICE}
++ else
++ linux_root_device_thisversion=PARTUUID=${GRUB_DEVICE_PARTUUID}
++ fi
++ fi
++
++ if [ "x${GRUB_DISABLE_SUBMENU}" = "xyes" ] || [
"x${GRUB_DISABLE_SUBMENU}" = "xy" ]; then
++ GRUB_DISABLE_SUBMENU="true"
++ fi
++
++ if [ "x$is_top_level" = xtrue ] && [
"x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then
++ linux_entry "${OS}" "${version}" simple standard \
++ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
++ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
++ linux_entry "${OS}" "${version}" simple debug \
++ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}
${GRUB_CMDLINE_LINUX_DEBUG}"
++ fi
++
++ submenu_indentation="$grub_tab"
++
++ if [ -z "$boot_device_id" ]; then
++ boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
++ fi
++ # TRANSLATORS: %s is replaced with an OS name
++ echo "submenu '$(gettext_printf "Advanced options for %s"
"${OS}" | grub_quote)' \$menuentry_id_option
'gnulinux-advanced-$boot_device_id' {"
++ is_top_level=false
++ fi
++
++ linux_entry "${OS}" "${version}" advanced standard \
++ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
++ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
++ linux_entry "${OS}" "${version}" advanced debug \
++ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}
${GRUB_CMDLINE_LINUX_DEBUG}"
++ fi
++
++ if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
++ linux_entry "${OS}" "${version}" recovery standard \
++ "single ${GRUB_CMDLINE_LINUX}"
++ fi
++
++ list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr
'\n' ' '`
++done
++
++# If at least one kernel was found, then we need to
++# add a closing '}' for the submenu command.
++if [ x"$is_top_level" != xtrue ]; then
++ echo '}'
++fi
++
++echo "$title_correction_code"
diff --git a/0258-Only-set-kernelopts-in-grubenv-if-it-wasn-t-set-befo.patch
b/0258-Only-set-kernelopts-in-grubenv-if-it-wasn-t-set-befo.patch
new file mode 100644
index 0000000..be3c867
--- /dev/null
+++ b/0258-Only-set-kernelopts-in-grubenv-if-it-wasn-t-set-befo.patch
@@ -0,0 +1,79 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Javier Martinez Canillas <javierm(a)redhat.com>
+Date: Fri, 5 Oct 2018 16:29:47 +0200
+Subject: [PATCH] Only set kernelopts in grubenv if it wasn't set before
+
+Users may want to use a different command line parameters, so if there's
+a kernelopts var set in grubenv, grub2-mkconfig shouldn't reset it.
+
+While being there, print a warning so users know that they shouldn't edit
+the grub config file and instead edit the BootLoaderSpec config files.
+
+Resolves: rhbz#1636466
+
+Signed-off-by: Javier Martinez Canillas <javierm(a)redhat.com>
+---
+ util/grub.d/10_linux.in | 20 +++++++++++++++++++-
+ util/grub.d/10_linux_bls.in | 4 +++-
+ 2 files changed, 22 insertions(+), 2 deletions(-)
+
+diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
+index 9682e97b7f5..01e66e5fc74 100644
+--- a/util/grub.d/10_linux.in
++++ b/util/grub.d/10_linux.in
+@@ -82,6 +82,20 @@ case x"$GRUB_FS" in
+ ;;
+ esac
+
++populate_header_warn()
++{
++cat <<EOF
++
++# This section was generated by a script. Do not modify the generated file - all
changes
++# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec
files.
++#
++# The blscfg command parses the BootLoaderSpec files stored in /boot/loader/entries and
++# populates the boot menu. Please refer to the Boot Loader Specification documentation
++# for the files format:
https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/.
++
++EOF
++}
++
+ mktitle ()
+ {
+ local title_type
+@@ -141,6 +155,8 @@ linux_entry ()
+ prepare_grub_to_access_device ${boot_device} boot
+ fi
+
++ populate_header_warn
++
+ cat << EOF
+ insmod blscfg
+ blscfg
+@@ -150,7 +166,9 @@ fi
+ EOF
+
+ ${grub_editenv} - set saved_entry=0
+- ${grub_editenv} - set kernelopts="root=${linux_root_device_thisversion} ro
${args}"
++ if ! grub2-editenv - list | grep -q kernelopts; then
++ ${grub_editenv} - set kernelopts="root=${linux_root_device_thisversion} ro
${args}"
++ fi
+
+ exit 0
+ fi
+diff --git a/util/grub.d/10_linux_bls.in b/util/grub.d/10_linux_bls.in
+index 3cc7803c6a1..8a3379578bd 100644
+--- a/util/grub.d/10_linux_bls.in
++++ b/util/grub.d/10_linux_bls.in
+@@ -201,7 +201,9 @@ linux_entry ()
+ populate_menu
+
+ ${grub_editenv} - set saved_entry=0
+- ${grub_editenv} - set kernelopts="root=${linux_root_device_thisversion} ro
${args}"
++ if ! grub2-editenv - list | grep -q kernelopts; then
++ ${grub_editenv} - set kernelopts="root=${linux_root_device_thisversion} ro
${args}"
++ fi
+
+ exit 0
+ fi
diff --git a/0259-blscfg-sort-everything-with-rpm-package-comparison.patch
b/0259-blscfg-sort-everything-with-rpm-package-comparison.patch
new file mode 100644
index 0000000..f1d848c
--- /dev/null
+++ b/0259-blscfg-sort-everything-with-rpm-package-comparison.patch
@@ -0,0 +1,161 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones(a)redhat.com>
+Date: Mon, 15 Oct 2018 15:08:33 -0400
+Subject: [PATCH] blscfg: sort everything with rpm *package* comparison
+
+This makes comparisons use the n-v-r tuple, and compare name with name,
+version with version, and release with release.
+
+Related: rhbz#1638103
+
+Signed-off-by: Peter Jones <pjones(a)redhat.com>
+---
+ grub-core/commands/blscfg.c | 118 ++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 108 insertions(+), 10 deletions(-)
+
+diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
+index 3847572dabd..347128c9ddd 100644
+--- a/grub-core/commands/blscfg.c
++++ b/grub-core/commands/blscfg.c
+@@ -206,7 +206,7 @@ static int vercmp(const char * a, const char * b)
+ int isnum;
+ int ret = 0;
+
+- grub_dprintf("blscfg", "%s got here\n", __func__);
++ grub_dprintf("blscfg", "%s got here\n", __func__);
+ if (!grub_strcmp(a, b))
+ return 0;
+
+@@ -315,6 +315,81 @@ finish:
+ return ret;
+ }
+
++/* returns name/version/release */
++/* NULL string pointer returned if nothing found */
++static void
++split_package_string (char *package_string, char **name,
++ char **version, char **release)
++{
++ char *package_version, *package_release;
++
++ /* Release */
++ package_release = grub_strrchr (package_string, '-');
++
++ if (package_release != NULL)
++ *package_release++ = '\0';
++
++ *release = package_release;
++
++ if (name == NULL)
++ {
++ *version = package_string;
++ }
++ else
++ {
++ /* Version */
++ package_version = grub_strrchr(package_string, '-');
++
++ if (package_version != NULL)
++ *package_version++ = '\0';
++
++ *version = package_version;
++ /* Name */
++ *name = package_string;
++ }
++
++ /* Bubble up non-null values from release to name */
++ if (name != NULL && *name == NULL)
++ {
++ *name = (*version == NULL ? *release : *version);
++ *version = *release;
++ *release = NULL;
++ }
++ if (*version == NULL)
++ {
++ *version = *release;
++ *release = NULL;
++ }
++}
++
++static int
++split_cmp(char *nvr0, char *nvr1, int has_name)
++{
++ int ret = 0;
++ char *name0, *version0, *release0;
++ char *name1, *version1, *release1;
++
++ split_package_string(nvr0, has_name ? &name0 : NULL, &version0,
&release0);
++ split_package_string(nvr1, has_name ? &name1 : NULL, &version1,
&release1);
++
++ if (has_name)
++ {
++ ret = vercmp(name0 == NULL ? "" : name0,
++ name1 == NULL ? "" : name1);
++ if (ret != 0)
++ return ret;
++ }
++
++ ret = vercmp(version0 == NULL ? "" : version0,
++ version1 == NULL ? "" : version1);
++ if (ret != 0)
++ return ret;
++
++ ret = vercmp(release0 == NULL ? "" : release0,
++ release1 == NULL ? "" : release1);
++ return ret;
++}
++
+ /* return 1: p0 is newer than p1 */
+ /* 0: p0 and p1 are the same version */
+ /* -1: p1 is newer than p0 */
+@@ -323,18 +398,41 @@ static int bls_cmp(const void *p0, const void *p1, void *state)
+ struct bls_entry * e0 = *(struct bls_entry **)p0;
+ struct bls_entry * e1 = *(struct bls_entry **)p1;
+ bool use_version = *(bool *)state;
+- const char *v0, *v1;
+- int r;
++ char *v0, *v1;
++ char *id0, *id1;
++ int l, r;
+
+- if (use_version) {
+- v0 = bls_get_val(e0, "version", NULL);
+- v1 = bls_get_val(e1, "version", NULL);
++ if (use_version)
++ {
++ v0 = grub_strdup(bls_get_val(e0, "version", NULL));
++ v1 = grub_strdup(bls_get_val(e1, "version", NULL));
+
+- if ((r = vercmp(v0, v1)) != 0)
+- return r;
+- }
++ r = split_cmp(v0, v1, 0);
+
+- return vercmp(e0->filename, e1->filename);
++ grub_free(v0);
++ grub_free(v1);
++
++ if (r != 0)
++ return r;
++ }
++
++ id0 = grub_strdup(e0->filename);
++ id1 = grub_strdup(e1->filename);
++
++ l = grub_strlen(id0);
++ if (l > 5 && grub_strcmp(id0 + l - 5, ".conf"))
++ id0[l-5] = '\0';
++
++ l = grub_strlen(id1);
++ if (l > 5 && grub_strcmp(id1 + l - 5, ".conf"))
++ id1[l-5] = '\0';
++
++ r = split_cmp(id0, id1, 1);
++
++ grub_free(id0);
++ grub_free(id1);
++
++ return r;
+ }
+
+ struct read_entry_info {
diff --git a/0260-10_linux_bls-use-grub2-rpm-sort-instead-of-ls-vr-to-.patch
b/0260-10_linux_bls-use-grub2-rpm-sort-instead-of-ls-vr-to-.patch
new file mode 100644
index 0000000..f23cd47
--- /dev/null
+++ b/0260-10_linux_bls-use-grub2-rpm-sort-instead-of-ls-vr-to-.patch
@@ -0,0 +1,43 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Javier Martinez Canillas <javierm(a)redhat.com>
+Date: Tue, 16 Oct 2018 15:48:15 +0200
+Subject: [PATCH] 10_linux_bls: use grub2-rpm-sort instead of ls -vr to sort
+ entries
+
+Using ls -vr is wrong since it's not the same than the RPM sort algorithm.
+
+Signed-off-by: Javier Martinez Canillas <javierm(a)redhat.com>
+---
+ util/grub.d/10_linux_bls.in | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/util/grub.d/10_linux_bls.in b/util/grub.d/10_linux_bls.in
+index 8a3379578bd..1bc97f29898 100644
+--- a/util/grub.d/10_linux_bls.in
++++ b/util/grub.d/10_linux_bls.in
+@@ -151,10 +151,22 @@ read_config()
+
+ populate_menu()
+ {
+- entries_path="/boot/loader/entries"
++ blsdir="/boot/loader/entries"
++ local -a files
++ local IFS=$'\n'
+ gettext_printf "Generating boot entries from BLS files...\n" >&2
+- for config in $(ls -v -r $entries_path/*.conf); do
+- read_config ${config}
++
++ files=($(for bls in ${blsdir}/*.conf ; do
++ if ! [[ -e "${bls}" ]] ; then
++ continue
++ fi
++ bls="${bls%.conf}"
++ bls="${bls##*/}"
++ echo "${bls}"
++ done | ${kernel_sort} | tac)) || :
++
++ for bls in "${files[@]}" ; do
++ read_config "${blsdir}/${bls}.conf"
+ menu="${menu}menuentry '${title}' {\n"
+ menu="${menu}\t linux ${linux} ${options}\n"
+ if [ -n "${initrd}" ] ; then
diff --git a/0261-don-t-set-saved_entry-on-grub2-mkconfig.patch
b/0261-don-t-set-saved_entry-on-grub2-mkconfig.patch
new file mode 100644
index 0000000..8e3ea47
--- /dev/null
+++ b/0261-don-t-set-saved_entry-on-grub2-mkconfig.patch
@@ -0,0 +1,42 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Javier Martinez Canillas <javierm(a)redhat.com>
+Date: Fri, 19 Oct 2018 14:42:41 +0200
+Subject: [PATCH] don't set saved_entry on grub2-mkconfig
+
+The original plan was for grub2 to rely on the BLS sort criteria to choose
+the default entry to boot, to avoid modifying any files when a new kernel
+was installed. But that was changed and now 20-grub.install changes the
+default, so 10_linux{,bls} shouldn't overwrite this.
+
+Resolves: rhbz#1636466
+
+Signed-off-by: Javier Martinez Canillas <javierm(a)redhat.com>
+---
+ util/grub.d/10_linux.in | 1 -
+ util/grub.d/10_linux_bls.in | 1 -
+ 2 files changed, 2 deletions(-)
+
+diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
+index 01e66e5fc74..b54d2774a7d 100644
+--- a/util/grub.d/10_linux.in
++++ b/util/grub.d/10_linux.in
+@@ -165,7 +165,6 @@ if [ -s \$prefix/grubenv ]; then
+ fi
+ EOF
+
+- ${grub_editenv} - set saved_entry=0
+ if ! grub2-editenv - list | grep -q kernelopts; then
+ ${grub_editenv} - set kernelopts="root=${linux_root_device_thisversion} ro
${args}"
+ fi
+diff --git a/util/grub.d/10_linux_bls.in b/util/grub.d/10_linux_bls.in
+index 1bc97f29898..8745e598d0e 100644
+--- a/util/grub.d/10_linux_bls.in
++++ b/util/grub.d/10_linux_bls.in
+@@ -212,7 +212,6 @@ linux_entry ()
+ populate_header_warn
+ populate_menu
+
+- ${grub_editenv} - set saved_entry=0
+ if ! grub2-editenv - list | grep -q kernelopts; then
+ ${grub_editenv} - set kernelopts="root=${linux_root_device_thisversion} ro
${args}"
+ fi
diff --git a/0262-grub-switch-to-blscfg-use-debug-instead-of-debug-as-.patch
b/0262-grub-switch-to-blscfg-use-debug-instead-of-debug-as-.patch
new file mode 100644
index 0000000..9256c23
--- /dev/null
+++ b/0262-grub-switch-to-blscfg-use-debug-instead-of-debug-as-.patch
@@ -0,0 +1,31 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Javier Martinez Canillas <javierm(a)redhat.com>
+Date: Fri, 19 Oct 2018 18:48:27 +0200
+Subject: [PATCH] grub-switch-to-blscfg: use ~debug instead of -debug as suffix
+ to sort correctly
+
+For the debug BLS entries a -debug suffix was added so they are sorted after
+the kernel entries, but that only works with version sort and not rpm sort.
+
+So instead use ~debug prefix so rpm sort algorithm could sort it correctly.
+
+Related: rhbz#1638103
+
+Signed-off-by: Javier Martinez Canillas <javierm(a)redhat.com>
+---
+ util/grub-switch-to-blscfg.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in
+index 1c6bd1882a7..60cd6ca63cc 100644
+--- a/util/grub-switch-to-blscfg.in
++++ b/util/grub-switch-to-blscfg.in
+@@ -250,7 +250,7 @@ for kernelver in $(cd /lib/modules/ ; ls -1) "" ; do
+ fi
+
+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
+- bls_debug="$(echo ${bls_target} | sed -e
"s/\.${arch}/-debug.${arch}/")"
++ bls_debug="$(echo ${bls_target} | sed -e
"s/${kernelver}/${kernelver}~debug/")"
+ cp -aT "${bls_target}" "${bls_debug}"
+ title="$(grep '^title[ \t]' "${bls_debug}" | sed -e
's/^title[ \t]*//')"
+ blsid="$(grep '^id[ \t]' "${bls_debug}" | sed -e
"s/\.${ARCH}/-debug.${arch}/")"
diff --git a/0263-Make-blscfg-debug-messages-more-useful.patch
b/0263-Make-blscfg-debug-messages-more-useful.patch
new file mode 100644
index 0000000..9a05606
--- /dev/null
+++ b/0263-Make-blscfg-debug-messages-more-useful.patch
@@ -0,0 +1,175 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones(a)redhat.com>
+Date: Fri, 19 Oct 2018 10:03:28 -0400
+Subject: [PATCH] Make blscfg debug messages more useful
+
+Related: rhbz#1640979
+Signed-off-by: Peter Jones <pjones(a)redhat.com>
+---
+ grub-core/commands/blscfg.c | 12 +++++-------
+ grub-core/commands/legacycfg.c | 4 ++--
+ grub-core/commands/menuentry.c | 18 ++++++++++++++----
+ include/grub/normal.h | 2 +-
+ 4 files changed, 22 insertions(+), 14 deletions(-)
+
+diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
+index 347128c9ddd..42892cbfd55 100644
+--- a/grub-core/commands/blscfg.c
++++ b/grub-core/commands/blscfg.c
+@@ -46,8 +46,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
+ #define GRUB_BOOT_DEVICE "($root)"
+ #endif
+
+-#define grub_free(x) ({grub_dprintf("blscfg", "%s freeing %p\n",
__func__, x); grub_free(x); })
+-
+ struct keyval
+ {
+ const char *key;
+@@ -134,7 +132,7 @@ static int bls_add_keyval(struct bls_entry *entry, char *key, char
*val)
+ kv->val = v;
+
+ entry->keyvals[entry->nkeyvals] = kv;
+- grub_dprintf("blscfg", "new keyval at %p:%p:%p\n",
entry->keyvals[entry->nkeyvals], k, v);
++ grub_dprintf("blscfg", "new keyval at %p:%s:%s\n",
entry->keyvals[entry->nkeyvals], k, v);
+ entry->nkeyvals = new_n;
+
+ return 0;
+@@ -144,7 +142,6 @@ static void bls_free_entry(struct bls_entry *entry)
+ {
+ int i;
+
+- grub_dprintf("blscfg", "%s got here\n", __func__);
+ for (i = 0; i < entry->nkeyvals; i++)
+ {
+ struct keyval *kv = entry->keyvals[i];
+@@ -206,7 +203,7 @@ static int vercmp(const char * a, const char * b)
+ int isnum;
+ int ret = 0;
+
+- grub_dprintf("blscfg", "%s got here\n", __func__);
++ grub_dprintf("blscfg", "%s comparing %s and %s\n", __func__, a,
b);
+ if (!grub_strcmp(a, b))
+ return 0;
+
+@@ -682,7 +679,7 @@ static void create_entry (struct bls_entry *entry)
+ char **args = NULL;
+
+ char *src = NULL;
+- int i;
++ int i, index;
+
+ grub_dprintf("blscfg", "%s got here\n", __func__);
+ clinux = bls_get_val (entry, "linux", NULL);
+@@ -756,7 +753,8 @@ static void create_entry (struct bls_entry *entry)
+ GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options :
"",
+ initrd ? initrd : "");
+
+- grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0);
++ grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0,
&index);
++ grub_dprintf ("blscfg", "Added entry %d id:\"%s\"\n",
index, id);
+
+ finish:
+ grub_free (initrd);
+diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
+index b32f3c74cb1..f9d7627bdc3 100644
+--- a/grub-core/commands/legacycfg.c
++++ b/grub-core/commands/legacycfg.c
+@@ -133,7 +133,7 @@ legacy_file (const char *filename)
+ args[0] = oldname;
+ grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy",
+ NULL, NULL,
+- entrysrc, 0);
++ entrysrc, 0, NULL);
+ grub_free (args);
+ entrysrc[0] = 0;
+ grub_free (oldname);
+@@ -186,7 +186,7 @@ legacy_file (const char *filename)
+ }
+ args[0] = entryname;
+ grub_normal_add_menu_entry (1, args, NULL, NULL, NULL,
+- NULL, NULL, entrysrc, 0);
++ NULL, NULL, entrysrc, 0, NULL);
+ grub_free (args);
+ }
+
+diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c
+index 2c5363da7f5..8d242b0187e 100644
+--- a/grub-core/commands/menuentry.c
++++ b/grub-core/commands/menuentry.c
+@@ -78,7 +78,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
+ char **classes, const char *id,
+ const char *users, const char *hotkey,
+ const char *prefix, const char *sourcecode,
+- int submenu)
++ int submenu, int *index)
+ {
+ int menu_hotkey = 0;
+ char **menu_args = NULL;
+@@ -149,9 +149,12 @@ grub_normal_add_menu_entry (int argc, const char **args,
+ if (! menu_title)
+ goto fail;
+
++ grub_dprintf ("menu", "id:\"%s\"\n", id);
++ grub_dprintf ("menu", "title:\"%s\"\n", menu_title);
+ menu_id = grub_strdup (id ? : menu_title);
+ if (! menu_id)
+ goto fail;
++ grub_dprintf ("menu", "menu_id:\"%s\"\n", menu_id);
+
+ /* Save argc, args to pass as parameters to block arg later. */
+ menu_args = grub_malloc (sizeof (char*) * (argc + 1));
+@@ -170,8 +173,12 @@ grub_normal_add_menu_entry (int argc, const char **args,
+ }
+
+ /* Add the menu entry at the end of the list. */
++ int ind=0;
+ while (*last)
+- last = &(*last)->next;
++ {
++ ind++;
++ last = &(*last)->next;
++ }
+
+ *last = grub_zalloc (sizeof (**last));
+ if (! *last)
+@@ -190,6 +197,8 @@ grub_normal_add_menu_entry (int argc, const char **args,
+ (*last)->submenu = submenu;
+
+ menu->size++;
++ if (index)
++ *index = ind;
+ return GRUB_ERR_NONE;
+
+ fail:
+@@ -286,7 +295,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char
**args)
+ users,
+ ctxt->state[2].arg, 0,
+ ctxt->state[3].arg,
+- ctxt->extcmd->cmd->name[0] == 's');
++ ctxt->extcmd->cmd->name[0] == 's',
++ NULL);
+
+ src = args[argc - 1];
+ args[argc - 1] = NULL;
+@@ -303,7 +313,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char
**args)
+ ctxt->state[0].args, ctxt->state[4].arg,
+ users,
+ ctxt->state[2].arg, prefix, src + 1,
+- ctxt->extcmd->cmd->name[0] == 's');
++ ctxt->extcmd->cmd->name[0] == 's', NULL);
+
+ src[len - 1] = ch;
+ args[argc - 1] = src;
+diff --git a/include/grub/normal.h b/include/grub/normal.h
+index 218cbabccaf..cb9901f41b3 100644
+--- a/include/grub/normal.h
++++ b/include/grub/normal.h
+@@ -145,7 +145,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char
**classes,
+ const char *id,
+ const char *users, const char *hotkey,
+ const char *prefix, const char *sourcecode,
+- int submenu);
++ int submenu, int *index);
+
+ grub_err_t
+ grub_normal_set_password (const char *user, const char *password);
diff --git a/0264-Make-grub_strtoul-end-pointer-have-the-right-constif.patch
b/0264-Make-grub_strtoul-end-pointer-have-the-right-constif.patch
new file mode 100644
index 0000000..99787bd
--- /dev/null
+++ b/0264-Make-grub_strtoul-end-pointer-have-the-right-constif.patch
@@ -0,0 +1,391 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones(a)redhat.com>
+Date: Fri, 19 Oct 2018 13:41:48 -0400
+Subject: [PATCH] Make grub_strtoul "end" pointer have the right
+ constification.
+
+Related: rhbz#1640979
+Signed-off-by: Peter Jones <pjones(a)redhat.com>
+---
+ grub-core/kern/fs.c | 2 +-
+ grub-core/kern/misc.c | 8 ++++----
+ grub-core/kern/partition.c | 2 +-
+ grub-core/lib/legacy_parse.c | 2 +-
+ grub-core/lib/syslinux_parse.c | 6 +++---
+ grub-core/loader/i386/xen_fileXX.c | 2 +-
+ grub-core/net/efi/ip4_config.c | 2 +-
+ grub-core/net/efi/ip6_config.c | 2 +-
+ grub-core/net/efi/net.c | 4 ++--
+ grub-core/net/efi/pxe.c | 6 +++---
+ grub-core/net/http.c | 4 ++--
+ grub-core/net/net.c | 8 ++++----
+ grub-core/net/url.c | 2 +-
+ grub-core/script/execute.c | 6 +++---
+ grub-core/term/serial.c | 2 +-
+ grub-core/term/terminfo.c | 2 +-
+ grub-core/tests/strtoull_test.c | 2 +-
+ include/grub/misc.h | 6 +++---
+ 18 files changed, 34 insertions(+), 34 deletions(-)
+
+diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c
+index 9085895b6fe..1bd748be83b 100644
+--- a/grub-core/kern/fs.c
++++ b/grub-core/kern/fs.c
+@@ -134,7 +134,7 @@ struct grub_fs_block
+ static grub_err_t
+ grub_fs_blocklist_open (grub_file_t file, const char *name)
+ {
+- char *p = (char *) name;
++ const char *p = name;
+ unsigned num = 0;
+ unsigned i;
+ grub_disk_t disk = file->device->disk;
+diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
+index 5c3899f0e5b..aaae9aa0ab7 100644
+--- a/grub-core/kern/misc.c
++++ b/grub-core/kern/misc.c
+@@ -383,7 +383,7 @@ grub_isspace (int c)
+ }
+
+ unsigned long
+-grub_strtoul (const char *str, char **end, int base)
++grub_strtoul (const char *str, const char ** const end, int base)
+ {
+ unsigned long long num;
+
+@@ -400,7 +400,7 @@ grub_strtoul (const char *str, char **end, int base)
+ }
+
+ unsigned long long
+-grub_strtoull (const char *str, char **end, int base)
++grub_strtoull (const char *str, const char ** const end, int base)
+ {
+ unsigned long long num = 0;
+ int found = 0;
+@@ -901,14 +901,14 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char
*fmt0,
+ {
+ if (fmt[0] == '0')
+ zerofill = '0';
+- format1 = grub_strtoul (fmt, (char **) &fmt, 10);
++ format1 = grub_strtoul (fmt, &fmt, 10);
+ }
+
+ if (*fmt == '.')
+ fmt++;
+
+ if (grub_isdigit (*fmt))
+- format2 = grub_strtoul (fmt, (char **) &fmt, 10);
++ format2 = grub_strtoul (fmt, &fmt, 10);
+
+ if (*fmt == '$')
+ {
+diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c
+index e499147cbcb..2c401b866c4 100644
+--- a/grub-core/kern/partition.c
++++ b/grub-core/kern/partition.c
+@@ -126,7 +126,7 @@ grub_partition_probe (struct grub_disk *disk, const char *str)
+ while (*ptr && grub_isalpha (*ptr))
+ ptr++;
+ partname_end = ptr;
+- num = grub_strtoul (ptr, (char **) &ptr, 0) - 1;
++ num = grub_strtoul (ptr, &ptr, 0) - 1;
+
+ curpart = 0;
+ /* Use the first partition map type found. */
+diff --git a/grub-core/lib/legacy_parse.c b/grub-core/lib/legacy_parse.c
+index ef56150ac77..05719ab2ccb 100644
+--- a/grub-core/lib/legacy_parse.c
++++ b/grub-core/lib/legacy_parse.c
+@@ -418,7 +418,7 @@ adjust_file (const char *in, grub_size_t len)
+ }
+ if (*comma != ',')
+ return grub_legacy_escape (in, len);
+- part = grub_strtoull (comma + 1, (char **) &rest, 0);
++ part = grub_strtoull (comma + 1, &rest, 0);
+ if (rest[0] == ',' && rest[1] >= 'a' && rest[1]
<= 'z')
+ {
+ subpart = rest[1] - 'a';
+diff --git a/grub-core/lib/syslinux_parse.c b/grub-core/lib/syslinux_parse.c
+index 28ba3aef0bb..21ca040ada7 100644
+--- a/grub-core/lib/syslinux_parse.c
++++ b/grub-core/lib/syslinux_parse.c
+@@ -1058,7 +1058,7 @@ write_entry (struct output_buffer *outbuf,
+ if (ptr[0] == 'h' && ptr[1] == 'd')
+ {
+ is_fd = 0;
+- devn = grub_strtoul (ptr + 2, &ptr, 0);
++ devn = grub_strtoul (ptr + 2, (const char **)&ptr, 0);
+ continue;
+ }
+ if (grub_strncasecmp (ptr, "file=", 5) == 0)
+@@ -1082,12 +1082,12 @@ write_entry (struct output_buffer *outbuf,
+ if (ptr[0] == 'f' && ptr[1] == 'd')
+ {
+ is_fd = 1;
+- devn = grub_strtoul (ptr + 2, &ptr, 0);
++ devn = grub_strtoul (ptr + 2, (const char **)&ptr, 0);
+ continue;
+ }
+ if (grub_isdigit (ptr[0]))
+ {
+- part = grub_strtoul (ptr, &ptr, 0);
++ part = grub_strtoul (ptr, (const char **)&ptr, 0);
+ continue;
+ }
+ /* FIXME: isolinux, ntldr, cmldr, *dos, seg, hide
+diff --git a/grub-core/loader/i386/xen_fileXX.c b/grub-core/loader/i386/xen_fileXX.c
+index fb66e66fe96..293f1ad5c3e 100644
+--- a/grub-core/loader/i386/xen_fileXX.c
++++ b/grub-core/loader/i386/xen_fileXX.c
+@@ -25,7 +25,7 @@ parse_xen_guest (grub_elf_t elf, struct grub_xen_file_info *xi,
+ grub_off_t off, grub_size_t sz)
+ {
+ char *buf;
+- char *ptr;
++ const char *ptr;
+ int has_paddr = 0;
+
+ grub_errno = GRUB_ERR_NONE;
+diff --git a/grub-core/net/efi/ip4_config.c b/grub-core/net/efi/ip4_config.c
+index b711a5d9457..38e2a04747a 100644
+--- a/grub-core/net/efi/ip4_config.c
++++ b/grub-core/net/efi/ip4_config.c
+@@ -62,7 +62,7 @@ grub_efi_string_to_ip4_address (const char *val,
grub_efi_ipv4_address_t *addres
+ for (i = 0; i < 4; i++)
+ {
+ unsigned long t;
+- t = grub_strtoul (ptr, (char **) &ptr, 0);
++ t = grub_strtoul (ptr, &ptr, 0);
+ if (grub_errno)
+ {
+ grub_errno = GRUB_ERR_NONE;
+diff --git a/grub-core/net/efi/ip6_config.c b/grub-core/net/efi/ip6_config.c
+index 017c4d05bc7..e0e00c23d21 100644
+--- a/grub-core/net/efi/ip6_config.c
++++ b/grub-core/net/efi/ip6_config.c
+@@ -84,7 +84,7 @@ grub_efi_string_to_ip6_address (const char *val,
grub_efi_ipv6_address_t *addres
+ ptr++;
+ continue;
+ }
+- t = grub_strtoul (ptr, (char **) &ptr, 16);
++ t = grub_strtoul (ptr, &ptr, 16);
+ if (grub_errno)
+ {
+ grub_errno = GRUB_ERR_NONE;
+diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c
+index f208d1b180c..4c70fc4da2a 100644
+--- a/grub-core/net/efi/net.c
++++ b/grub-core/net/efi/net.c
+@@ -729,7 +729,7 @@ grub_efi_net_parse_address (const char *address,
+ {
+ grub_uint32_t subnet_mask_size;
+
+- subnet_mask_size = grub_strtoul (rest + 1, (char **) &rest, 0);
++ subnet_mask_size = grub_strtoul (rest + 1, &rest, 0);
+
+ if (!grub_errno && subnet_mask_size <= 32 && *rest == 0)
+ {
+@@ -758,7 +758,7 @@ grub_efi_net_parse_address (const char *address,
+ {
+ grub_efi_uint8_t prefix_length;
+
+- prefix_length = grub_strtoul (rest + 1, (char **) &rest, 0);
++ prefix_length = grub_strtoul (rest + 1, &rest, 0);
+ if (!grub_errno && prefix_length <= 128 && *rest == 0)
+ {
+ ip6->prefix_length = prefix_length;
+diff --git a/grub-core/net/efi/pxe.c b/grub-core/net/efi/pxe.c
+index 531949cba5c..73e2bb01c1b 100644
+--- a/grub-core/net/efi/pxe.c
++++ b/grub-core/net/efi/pxe.c
+@@ -187,7 +187,7 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest)
+ ptr++;
+ continue;
+ }
+- t = grub_strtoul (ptr, (char **) &ptr, 16);
++ t = grub_strtoul (ptr, &ptr, 16);
+ if (grub_errno)
+ {
+ grub_errno = GRUB_ERR_NONE;
+@@ -225,7 +225,7 @@ pxe_open (struct grub_efi_net_device *dev,
+ int type __attribute__((unused)))
+ {
+ int i;
+- char *p;
++ const char *p;
+ grub_efi_status_t status;
+ grub_efi_pxe_ip_address_t server_ip;
+ grub_efi_uint64_t file_size = 0;
+@@ -313,7 +313,7 @@ pxe_read (struct grub_efi_net_device *dev,
+ grub_size_t len)
+ {
+ int i;
+- char *p;
++ const char *p;
+ grub_efi_status_t status;
+ grub_efi_pxe_t *pxe = (prefer_ip6) ? dev->ip6_pxe : dev->ip4_pxe;
+ grub_efi_uint64_t bufsz = len;
+diff --git a/grub-core/net/http.c b/grub-core/net/http.c
+index c9c59690a98..b52b558d631 100644
+--- a/grub-core/net/http.c
++++ b/grub-core/net/http.c
+@@ -110,7 +110,7 @@ parse_line (grub_file_t file, http_data_t data, char *ptr,
grub_size_t len)
+ return GRUB_ERR_NONE;
+ }
+ ptr += sizeof ("HTTP/1.1 ") - 1;
+- code = grub_strtoul (ptr, &ptr, 10);
++ code = grub_strtoul (ptr, (const char **)&ptr, 10);
+ if (grub_errno)
+ return grub_errno;
+ switch (code)
+@@ -137,7 +137,7 @@ parse_line (grub_file_t file, http_data_t data, char *ptr,
grub_size_t len)
+ == 0 && !data->size_recv)
+ {
+ ptr += sizeof ("Content-Length: ") - 1;
+- file->size = grub_strtoull (ptr, &ptr, 10);
++ file->size = grub_strtoull (ptr, (const char **)&ptr, 10);
+ data->size_recv = 1;
+ return GRUB_ERR_NONE;
+ }
+diff --git a/grub-core/net/net.c b/grub-core/net/net.c
+index a571ee92efa..a011b940100 100644
+--- a/grub-core/net/net.c
++++ b/grub-core/net/net.c
+@@ -411,7 +411,7 @@ parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
+ for (i = 0; i < 4; i++)
+ {
+ unsigned long t;
+- t = grub_strtoul (ptr, (char **) &ptr, 0);
++ t = grub_strtoul (ptr, &ptr, 0);
+ if (grub_errno)
+ {
+ grub_errno = GRUB_ERR_NONE;
+@@ -465,7 +465,7 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest)
+ ptr++;
+ continue;
+ }
+- t = grub_strtoul (ptr, (char **) &ptr, 16);
++ t = grub_strtoul (ptr, &ptr, 16);
+ if (grub_errno)
+ {
+ grub_errno = GRUB_ERR_NONE;
+@@ -577,7 +577,7 @@ grub_net_resolve_net_address (const char *name,
+ addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
+ if (*rest == '/')
+ {
+- addr->ipv4.masksize = grub_strtoul (rest + 1, (char **) &rest, 0);
++ addr->ipv4.masksize = grub_strtoul (rest + 1, &rest, 0);
+ if (!grub_errno && *rest == 0)
+ return GRUB_ERR_NONE;
+ grub_errno = GRUB_ERR_NONE;
+@@ -593,7 +593,7 @@ grub_net_resolve_net_address (const char *name,
+ addr->type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
+ if (*rest == '/')
+ {
+- addr->ipv6.masksize = grub_strtoul (rest + 1, (char **) &rest, 0);
++ addr->ipv6.masksize = grub_strtoul (rest + 1, &rest, 0);
+ if (!grub_errno && *rest == 0)
+ return GRUB_ERR_NONE;
+ grub_errno = GRUB_ERR_NONE;
+diff --git a/grub-core/net/url.c b/grub-core/net/url.c
+index 146858284cd..d9d2fc9a9dc 100644
+--- a/grub-core/net/url.c
++++ b/grub-core/net/url.c
+@@ -235,7 +235,7 @@ extract_http_url_info (char *url, int ssl,
+ c = *port_end;
+ *port_end = '\0';
+
+- portul = grub_strtoul (port_off, &separator, 10);
++ portul = grub_strtoul (port_off, (const char **)&separator, 10);
+ *port_end = c;
+ #ifdef URL_TEST
+ if (portul == ULONG_MAX && errno == ERANGE)
+diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
+index 93965777138..7d327f59d92 100644
+--- a/grub-core/script/execute.c
++++ b/grub-core/script/execute.c
+@@ -146,7 +146,7 @@ replace_scope (struct grub_script_scope *new_scope)
+ grub_err_t
+ grub_script_break (grub_command_t cmd, int argc, char *argv[])
+ {
+- char *p = 0;
++ const char *p = NULL;
+ unsigned long count;
+
+ if (argc == 0)
+@@ -178,7 +178,7 @@ grub_err_t
+ grub_script_shift (grub_command_t cmd __attribute__((unused)),
+ int argc, char *argv[])
+ {
+- char *p = 0;
++ const char *p = NULL;
+ unsigned long n = 0;
+
+ if (! scope)
+@@ -239,7 +239,7 @@ grub_err_t
+ grub_script_return (grub_command_t cmd __attribute__((unused)),
+ int argc, char *argv[])
+ {
+- char *p;
++ const char *p = NULL;
+ unsigned long n;
+
+ if (! scope || argc > 1)
+diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c
+index db80b3ba0fb..f9271b09239 100644
+--- a/grub-core/term/serial.c
++++ b/grub-core/term/serial.c
+@@ -269,7 +269,7 @@ grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args)
+
+ if (state[OPTION_BASE_CLOCK].set)
+ {
+- char *ptr;
++ const char *ptr;
+ config.base_clock = grub_strtoull (state[OPTION_BASE_CLOCK].arg, &ptr, 0);
+ if (grub_errno)
+ return grub_errno;
+diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c
+index 29df35e6d20..537a5c0cb0b 100644
+--- a/grub-core/term/terminfo.c
++++ b/grub-core/term/terminfo.c
+@@ -737,7 +737,7 @@ grub_cmd_terminfo (grub_extcmd_context_t ctxt, int argc, char
**args)
+
+ if (state[OPTION_GEOMETRY].set)
+ {
+- char *ptr = state[OPTION_GEOMETRY].arg;
++ const char *ptr = state[OPTION_GEOMETRY].arg;
+ w = grub_strtoul (ptr, &ptr, 0);
+ if (grub_errno)
+ return grub_errno;
+diff --git a/grub-core/tests/strtoull_test.c b/grub-core/tests/strtoull_test.c
+index 7da615ff33e..5488ab26b43 100644
+--- a/grub-core/tests/strtoull_test.c
++++ b/grub-core/tests/strtoull_test.c
+@@ -25,7 +25,7 @@ static void
+ strtoull_testcase (const char *input, int base, unsigned long long expected,
+ int num_digits, grub_err_t error)
+ {
+- char *output;
++ const char *output;
+ unsigned long long value;
+ grub_errno = 0;
+ value = grub_strtoull(input, &output, base);
+diff --git a/include/grub/misc.h b/include/grub/misc.h
+index de9016ab709..1258ec6bbf3 100644
+--- a/include/grub/misc.h
++++ b/include/grub/misc.h
+@@ -288,11 +288,11 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
+ - (int) grub_tolower ((grub_uint8_t) *s2);
+ }
+
+-unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base);
+-unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base);
++unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, const char ** const end, int
base);
++unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, const char ** const end,
int base);
+
+ static inline long
+-grub_strtol (const char *str, char **end, int base)
++grub_strtol (const char *str, const char ** const end, int base)
+ {
+ int negative = 0;
+ unsigned long long magnitude;
diff --git a/0265-Fix-menu-entry-selection-based-on-ID-and-title.patch
b/0265-Fix-menu-entry-selection-based-on-ID-and-title.patch
new file mode 100644
index 0000000..065765c
--- /dev/null
+++ b/0265-Fix-menu-entry-selection-based-on-ID-and-title.patch
@@ -0,0 +1,235 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones(a)redhat.com>
+Date: Fri, 19 Oct 2018 10:57:52 -0400
+Subject: [PATCH] Fix menu entry selection based on ID and title
+
+Currently if grub_strtoul(saved_entry_value, NULL, 0) does not return an
+error, we assume the value it has produced is a correct index into our
+menu entry list, and do not try to interpret the value as the "id" or
+"title" . In cases where "id" or "title" start with a
numeral, this
+makes them impossible to use as selection criteria.
+
+This patch splits the search into three phases - matching id, matching
+title, and only once those have been exhausted, trying to interpret the
+ID as a numeral. In that case, we also require that the entire string
+is numeric, not merely a string with leading numeric characters.
+
+Resolves: rhbz#1640979
+---
+ grub-core/normal/menu.c | 146 +++++++++++++++++++++++++-----------------------
+ 1 file changed, 75 insertions(+), 71 deletions(-)
+
+diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
+index 6cb2a071490..95f7abaf2fd 100644
+--- a/grub-core/normal/menu.c
++++ b/grub-core/normal/menu.c
+@@ -164,12 +164,12 @@ grub_menu_set_timeout (int timeout)
+ }
+
+ static int
+-menuentry_eq (const char *id, const char *spec)
++menuentry_eq (const char *id, const char *spec, int limit)
+ {
+ const char *ptr1, *ptr2;
+ ptr1 = id;
+ ptr2 = spec;
+- while (1)
++ while (limit == -1 || ptr1 - id <= limit)
+ {
+ if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1
== 0)
+ return ptr2 - spec;
+@@ -178,7 +178,11 @@ menuentry_eq (const char *id, const char *spec)
+ if (*ptr2 == '>')
+ ptr2++;
+ if (*ptr1 != *ptr2)
+- return 0;
++ {
++ if (limit > -1 && ptr1 - id == limit && !*ptr1 &&
grub_isspace(*ptr2))
++ return ptr1 -id -1;
++ return 0;
++ }
+ if (*ptr1 == 0)
+ return ptr1 - id;
+ ptr1++;
+@@ -187,6 +191,61 @@ menuentry_eq (const char *id, const char *spec)
+ return 0;
+ }
+
++static int
++get_entry_number_helper(grub_menu_t menu,
++ const char * const val, const char ** const tail)
++{
++ /* See if the variable matches the title of a menu entry. */
++ int entry = -1;
++ grub_menu_entry_t e;
++ int i;
++
++ for (i = 0, e = menu->entry_list; e; i++)
++ {
++ int l = 0;
++ while (val[l] && !grub_isspace(val[l]))
++ l++;
++
++ if (menuentry_eq (e->id, val, l))
++ {
++ if (tail)
++ *tail = val + l;
++ return i;
++ }
++ e = e->next;
++ }
++
++ for (i = 0, e = menu->entry_list; e; i++)
++ {
++ int l = 0;
++ while (val[l] && !grub_isspace(val[l]))
++ l++;
++
++ if (menuentry_eq (e->title, val, l))
++ {
++ if (tail)
++ *tail = val + l;
++ return i;
++ }
++ e = e->next;
++ }
++
++ if (tail)
++ *tail = NULL;
++
++ entry = (int) grub_strtoul (val, tail, 0);
++ if (grub_errno == GRUB_ERR_BAD_NUMBER ||
++ (*tail && **tail && !grub_isspace(**tail)))
++ {
++ entry = -1;
++ if (tail)
++ *tail = NULL;
++ grub_errno = GRUB_ERR_NONE;
++ }
++
++ return entry;
++}
++
+ /* Get the first entry number from the value of the environment variable NAME,
+ which is a space-separated list of non-negative integers. The entry number
+ which is returned is stripped from the value of NAME. If no entry number
+@@ -195,9 +254,8 @@ static int
+ get_and_remove_first_entry_number (grub_menu_t menu, const char *name)
+ {
+ const char *val;
+- char *tail;
++ const char *tail;
+ int entry;
+- int sz = 0;
+
+ val = grub_env_get (name);
+ if (! val)
+@@ -205,50 +263,24 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char
*name)
+
+ grub_error_push ();
+
+- entry = (int) grub_strtoul (val, &tail, 0);
++ entry = get_entry_number_helper(menu, val, &tail);
++ if (!(*tail == 0 || grub_isspace(*tail)))
++ entry = -1;
+
+- if (grub_errno == GRUB_ERR_BAD_NUMBER)
++ if (entry >= 0)
+ {
+- /* See if the variable matches the title of a menu entry. */
+- grub_menu_entry_t e = menu->entry_list;
+- int i;
+-
+- for (i = 0; e; i++)
+- {
+- sz = menuentry_eq (e->title, val);
+- if (sz < 1)
+- sz = menuentry_eq (e->id, val);
+-
+- if (sz >= 1)
+- {
+- entry = i;
+- break;
+- }
+- e = e->next;
+- }
+-
+- if (sz > 0)
+- grub_errno = GRUB_ERR_NONE;
+-
+- if (! e)
+- entry = -1;
+- }
+-
+- if (grub_errno == GRUB_ERR_NONE)
+- {
+- if (sz > 0)
+- tail += sz;
+-
+ /* Skip whitespace to find the next entry. */
+ while (*tail && grub_isspace (*tail))
+ tail++;
+- grub_env_set (name, tail);
++ if (*tail)
++ grub_env_set (name, tail);
++ else
++ grub_env_unset (name);
+ }
+ else
+ {
+ grub_env_unset (name);
+ grub_errno = GRUB_ERR_NONE;
+- entry = -1;
+ }
+
+ grub_error_pop ();
+@@ -525,6 +557,7 @@ static int
+ get_entry_number (grub_menu_t menu, const char *name)
+ {
+ const char *val;
++ const char *tail;
+ int entry;
+
+ val = grub_env_get (name);
+@@ -532,38 +565,9 @@ get_entry_number (grub_menu_t menu, const char *name)
+ return -1;
+
+ grub_error_push ();
+-
+- entry = (int) grub_strtoul (val, 0, 0);
+-
+- if (grub_errno == GRUB_ERR_BAD_NUMBER)
+- {
+- /* See if the variable matches the title of a menu entry. */
+- grub_menu_entry_t e = menu->entry_list;
+- int i;
+-
+- grub_errno = GRUB_ERR_NONE;
+-
+- for (i = 0; e; i++)
+- {
+- if (menuentry_eq (e->title, val)
+- || menuentry_eq (e->id, val))
+- {
+- entry = i;
+- break;
+- }
+- e = e->next;
+- }
+-
+- if (! e)
+- entry = -1;
+- }
+-
+- if (grub_errno != GRUB_ERR_NONE)
+- {
+- grub_errno = GRUB_ERR_NONE;
+- entry = -1;
+- }
+-
++ entry = get_entry_number_helper(menu, val, &tail);
++ if (*tail != '\0')
++ entry = -1;
+ grub_error_pop ();
+
+ return entry;
diff --git a/99-grub-mkconfig.install b/99-grub-mkconfig.install
new file mode 100755
index 0000000..5f9545d
--- /dev/null
+++ b/99-grub-mkconfig.install
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+if ! [[ $KERNEL_INSTALL_MACHINE_ID ]]; then
+ exit 0
+fi
+
+ARCH=$(uname -m)
+
+# Is only needed for ppc64* since we can't assume a BLS capable bootloader there
+if [[ $ARCH != "ppc64" && $ARCH != "ppc64le" ]]; then
+ exit 0
+fi
+
+[[ -f /etc/default/grub ]] && . /etc/default/grub
+
+COMMAND="$1"
+
+case "$COMMAND" in
+ add|remove)
+ grub2-mkconfig -o /boot/grub2/grub.cfg >& /dev/null
+ ;;
+ *)
+ ;;
+esac
diff --git a/grub.patches b/grub.patches
index 91d34c0..e3113be 100644
--- a/grub.patches
+++ b/grub.patches
@@ -251,3 +251,15 @@ Patch0250:
0250-grub-switch-to-blscfg-copy-blscfg-module-for-legacy-.patch
Patch0251: 0251-Fix-getroot.c-s-trampolines.patch
Patch0252: 0252-Do-not-allow-stack-trampolines-anywhere.patch
Patch0253: 0253-Reimplement-boot_counter.patch
+Patch0254: 0254-blscfg-don-t-include-.conf-at-the-end-of-our-id.patch
+Patch0255: 0255-grub-get-kernel-settings-expose-some-more-config-var.patch
+Patch0256: 0256-Reimplement-boot_counter.patch
+Patch0257: 0257-add-10_linux_bls-grub.d-snippet-to-generate-menu-ent.patch
+Patch0258: 0258-Only-set-kernelopts-in-grubenv-if-it-wasn-t-set-befo.patch
+Patch0259: 0259-blscfg-sort-everything-with-rpm-package-comparison.patch
+Patch0260: 0260-10_linux_bls-use-grub2-rpm-sort-instead-of-ls-vr-to-.patch
+Patch0261: 0261-don-t-set-saved_entry-on-grub2-mkconfig.patch
+Patch0262: 0262-grub-switch-to-blscfg-use-debug-instead-of-debug-as-.patch
+Patch0263: 0263-Make-blscfg-debug-messages-more-useful.patch
+Patch0264: 0264-Make-grub_strtoul-end-pointer-have-the-right-constif.patch
+Patch0265: 0265-Fix-menu-entry-selection-based-on-ID-and-title.patch
diff --git a/grub2.spec b/grub2.spec
index 0f61083..fed34e5 100644
--- a/grub2.spec
+++ b/grub2.spec
@@ -25,6 +25,7 @@ Source8: strtoull_test.c
Source9: 20-grub.install
Source11: installkernel-bls
Source12: installkernel.in
+Source13: 99-grub-mkconfig.install
%include %{SOURCE1}
@@ -220,6 +221,7 @@ EOF
# Install kernel-install scripts
install -d -m 0755 %{buildroot}%{_prefix}/lib/kernel/install.d/
install -D -m 0755 -t %{buildroot}%{_prefix}/lib/kernel/install.d/ %{SOURCE9}
+install -D -m 0755 -t %{buildroot}%{_prefix}/lib/kernel/install.d/ %{SOURCE13}
install -d -m 0755 %{buildroot}%{_sysconfdir}/kernel/install.d/
install -m 0644 /dev/null %{buildroot}%{_sysconfdir}/kernel/install.d/20-grubby.install
install -m 0644 /dev/null
%{buildroot}%{_sysconfdir}/kernel/install.d/90-loaderentry.install
@@ -336,6 +338,7 @@ fi
%{_prefix}/lib/kernel/install.d/20-grub.install
%{_sysconfdir}/kernel/install.d/20-grubby.install
%{_sysconfdir}/kernel/install.d/90-loaderentry.install
+%{_prefix}/lib/kernel/install.d/99-grub-mkconfig.install
%dir %{_libexecdir}/installkernel
%{_libexecdir}/installkernel/installkernel-bls
%attr(0755,root,root) %{_sbindir}/installkernel
@@ -386,6 +389,11 @@ fi
%files tools
%attr(0644,root,root) %ghost %config(noreplace) %{_sysconfdir}/default/grub
%config %{_sysconfdir}/grub.d/??_*
+%ifarch ppc64 ppc64le
+%exclude %{_sysconfdir}/grub.d/10_linux
+%else
+%exclude %{_sysconfdir}/grub.d/10_linux_bls
+%endif
%exclude %{_sysconfdir}/grub.d/01_fallback_counting
%{_sysconfdir}/grub.d/README
%{_userunitdir}/grub-boot-success.timer
@@ -495,6 +503,24 @@ fi
%endif
%changelog
+* Tue Oct 23 2018 Javier Martinez Canillas <javierm(a)redhat.com>
+- add 10_linux_bls grub.d snippet to generate menu entries from BLS files
+ Resolves: rhbz#1636013
+- Only set kernelopts in grubenv if it wasn't set before
+ Resolves: rhbz#1636466
+- kernel-install: Remove existing initramfs if it's older than the kernel (pjones)
+ Resolves: rhbz#1638405
+- Update the saved entry correctly after a kernel install (pjones)
+ Resolves: rhbz#1638117
+- blscfg: sort everything with rpm *package* comparison (pjones)
+ Related: rhbz#1638103
+- blscfg: Make 10_linux_bls sort the same way as well
+ Related: rhbz#1638103
+- don't set saved_entry on grub2-mkconfig
+ Resolves: rhbz#1636466
+- Fix menu entry selection based on ID and title (pjones)
+ Resolves: rhbz#1640979
+
* Thu Oct 04 2018 Peter Jones <pjones(a)redhat.com> - 2.02-62
- Exclude /etc/grub.d/01_fallback_counting until we work through some design
questions.
commit efb46dff18632215c019c49bf4d89da7e65e9b27
Author: Javier Martinez Canillas <javierm(a)redhat.com>
Date: Fri Oct 19 18:56:26 2018 +0200
20-grub.install: use ~debug instead of -debug as suffix to sort correctly
For the debug BLS entries a -debug suffix was added so they are sorted after
the kernel entries, but that only works with version sort and not rpm sort.
So instead use ~debug prefix so rpm sort algorithm could sort it correctly.
Related: rhbz#1638103
Signed-off-by: Javier Martinez Canillas <javierm(a)redhat.com>
diff --git a/20-grub.install b/20-grub.install
index 4e67c03..8f74530 100755
--- a/20-grub.install
+++ b/20-grub.install
@@ -101,8 +101,8 @@ case "$COMMAND" in
NEWDEFAULT="${BLS_ID}"
if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
ARCH="$(uname -m)"
- BLS_DEBUG_ID="$(echo ${BLS_ID} | sed -e
"s/\.${ARCH}/-debug.${ARCH}/")"
- BLS_DEBUG="$(echo ${BLS_TARGET} | sed -e
"s/\.${ARCH}/-debug.${ARCH}/")"
+ BLS_DEBUG_ID="$(echo ${BLS_ID} | sed -e
"s/${KERNEL_VERSION}/${KERNEL_VERSION}~debug/")"
+ BLS_DEBUG="$(echo ${BLS_TARGET} | sed -e
"s/${KERNEL_VERSION}/${KERNEL_VERSION}~debug/")"
cp -aT "${BLS_TARGET}" "${BLS_DEBUG}"
TITLE="$(grep '^title[ \t]' "${BLS_DEBUG}" | sed
-e 's/^title[ \t]*//')"
sed -i -e "s/^title.*/title
${TITLE}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${BLS_DEBUG}"
@@ -134,7 +134,7 @@ case "$COMMAND" in
if [[ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]] || [[ ! -f
/sbin/new-kernel-pkg ]]; then
ARCH="$(uname -m)"
BLS_TARGET="${BLS_DIR}/${MACHINE_ID}-${KERNEL_VERSION}.conf"
- BLS_DEBUG="$(echo ${BLS_TARGET} | sed -e
"s/\.${ARCH}/-debug.${ARCH}/")"
+ BLS_DEBUG="$(echo ${BLS_TARGET} | sed -e
"s/${KERNEL_VERSION}/${KERNEL_VERSION}~debug/")"
rm -f "${BLS_TARGET}" "${BLS_DEBUG}"
for i in vmlinuz System.map config zImage.stub dtb; do
commit 67aea4f8a57cdfa09a638751a37bbf62a318a306
Author: Peter Jones <pjones(a)redhat.com>
Date: Thu Oct 11 16:13:17 2018 -0400
kernel-install: Remove existing initramfs if it's older than the kernel
Currently we fail to install a new kernel with "make install" on the second
try, because dracut won't over-write the initramfs without --force. In this
patch, 20-grub.install will remove an existing initramfs if it's newer than the
kernel we're installing.
Resolves: rhbz#1638405
Signed-off-by: Peter Jones <pjones(a)redhat.com>
diff --git a/20-grub.install b/20-grub.install
index de1182f..4e67c03 100755
--- a/20-grub.install
+++ b/20-grub.install
@@ -114,6 +114,12 @@ case "$COMMAND" in
fi
grub2-editenv - set "saved_entry=${NEWDEFAULT}"
+ # this probably isn't the best place to do this, but it will do for now.
+ if [ -e "${BOOTPREFIX}${INITRD}" -a -e
"${BOOTPREFIX}${LINUX}" -a \
+ "${BOOTPREFIX}${INITRD}" -ot "${BOOTPREFIX}${LINUX}"
-a \
+ -x /usr/lib/kernel/install.d/50-dracut.install ]; then
+ rm -f "${BOOTPREFIX}${INITRD}"
+ fi
exit 0
fi
commit 66078fcba25ef899cef594f3ae1dbdd6dc13087b
Author: Peter Jones <pjones(a)redhat.com>
Date: Tue Oct 23 11:10:09 2018 +0200
Update the saved entry correctly after a kernel install.
Resolves: rhbz#1638117
Signed-off-by: Peter Jones <pjones(a)redhat.com>
diff --git a/20-grub.install b/20-grub.install
index eda11d8..de1182f 100755
--- a/20-grub.install
+++ b/20-grub.install
@@ -76,8 +76,10 @@ case "$COMMAND" in
fi
if [[ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]] || [[ ! -f
/sbin/new-kernel-pkg ]]; then
+ eval "$(grub2-get-kernel-settings)" || true
[[ -d "$BLS_DIR" ]] || mkdir -m 0700 -p "$BLS_DIR"
- BLS_TARGET="${BLS_DIR}/${MACHINE_ID}-${KERNEL_VERSION}.conf"
+ BLS_ID="${MACHINE_ID}-${KERNEL_VERSION}"
+ BLS_TARGET="${BLS_DIR}/${BLS_ID}.conf"
if [[ -f "${KERNEL_DIR}/bls.conf" ]]; then
cp -aT "${KERNEL_DIR}/bls.conf" "${BLS_TARGET}" ||
exit $?
else
@@ -96,17 +98,21 @@ case "$COMMAND" in
sed -i -e "s,^initrd.*,initrd ${BOOTPREFIX}${INITRD},g"
"${BLS_TARGET}"
fi
- eval "$(grub2-get-kernel-settings)" || true
+ NEWDEFAULT="${BLS_ID}"
if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
ARCH="$(uname -m)"
+ BLS_DEBUG_ID="$(echo ${BLS_ID} | sed -e
"s/\.${ARCH}/-debug.${ARCH}/")"
BLS_DEBUG="$(echo ${BLS_TARGET} | sed -e
"s/\.${ARCH}/-debug.${ARCH}/")"
cp -aT "${BLS_TARGET}" "${BLS_DEBUG}"
TITLE="$(grep '^title[ \t]' "${BLS_DEBUG}" | sed
-e 's/^title[ \t]*//')"
- BLSID="$(grep '^id[ \t]' "${BLS_DEBUG}" | sed -e
"s/\.${ARCH}/-debug.${ARCH}/")"
sed -i -e "s/^title.*/title
${TITLE}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${BLS_DEBUG}"
- sed -i -e "s/^id.*/${BLSID}/" "${BLS_DEBUG}"
+ sed -i -e "s/^id.*/id ${BLS_DEBUG_ID}/"
"${BLS_DEBUG}"
sed -i -e "s/^options.*/options \$kernelopts
${GRUB_CMDLINE_LINUX_DEBUG}/" "${BLS_DEBUG}"
- fi
+ if [ "x$GRUB_UPDATE_DEFAULT_KERNEL" = "xtrue" -a
"x$GRUB_DEFAULT_TO_DEBUG" = "xtrue" ]; then
+ NEWDEFAULT="${BLS_DEBUG_ID}"
+ fi
+ fi
+ grub2-editenv - set "saved_entry=${NEWDEFAULT}"
exit 0
fi
commit 682540cbf55b5995a786d65a23bd1e94046960b9
Author: Javier Martinez Canillas <javierm(a)redhat.com>
Date: Tue Oct 23 12:03:52 2018 +0200
do-rebase: add more options to not depend on the user git configuration
The patches generated by do-rebase depend on the user having core.abbrv=11
in their .gitconfig and also a diff.orderFile set.
These assumptions were removed for the git format-patch command by passing
all the configuration as options, but it was still present for git diff.
Signed-off-by: Javier Martinez Canillas <javierm(a)redhat.com>
diff --git a/do-rebase b/do-rebase
index 93a7f0f..ca10bf9 100755
--- a/do-rebase
+++ b/do-rebase
@@ -6,7 +6,8 @@ shopt -qs expand_aliases
export LC_COLLATE=C
export LC_ALL=C
-format_patch_ops="--zero-commit --no-signature --no-numbered --stat=80 --summary
-O.git.diff.order --patience -l0"
+diff_ops="-O.git.diff.order --patience -l0"
+format_patch_ops="--zero-commit --no-signature --no-numbered --stat=80 --summary
$diff_ops"
alias othergit="GIT_DIR=$PWD/.rhboot.git GIT_WORK_TREE=$PWD git"
alias formatpatch="othergit format-patch $format_patch_ops"
@@ -126,6 +127,7 @@ fi
if [ ! -d $PWD/.rhboot.git ]; then
othergit init
+ othergit config core.abbrev 11
if ! othergit remote add \
rhboot $gitrepo \
/dev/null 2>&1 ; then
@@ -154,7 +156,7 @@ unset LC_ALL
git rm -q 0*.patch
release-to-master.patch
-othergit diff --full-index --binary
grub-2.02..refs/remotes/rhboot/master
release-to-master.patch
+othergit diff --full-index --binary $diff_ops
grub-2.02..refs/remotes/rhboot/master
release-to-master.patch
git add release-to-master.patch
grub.patches