Blame SOURCES/0236-add-10_linux_bls-grub.d-snippet-to-generate-menu-ent.patch

d9d99f
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
d9d99f
From: Javier Martinez Canillas <javierm@redhat.com>
d9d99f
Date: Wed, 3 Oct 2018 20:48:32 +0200
d9d99f
Subject: [PATCH] add 10_linux_bls grub.d snippet to generate menu entries from
d9d99f
 BLS files
d9d99f
d9d99f
This grub.d snippet can be used on platforms where the bootloader doesn't
d9d99f
have BLS support and only can parse a normal grub configuration file.
d9d99f
d9d99f
Portions of this script were taken from the ostree-grub-generator script
d9d99f
included in the OSTree project.
d9d99f
d9d99f
Resolves: rhbz#1636013
d9d99f
d9d99f
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
d9d99f
---
d9d99f
 Makefile.util.def           |   7 +
d9d99f
 util/grub.d/10_linux_bls.in | 440 ++++++++++++++++++++++++++++++++++++++++++++
d9d99f
 2 files changed, 447 insertions(+)
d9d99f
 create mode 100644 util/grub.d/10_linux_bls.in
d9d99f
d9d99f
diff --git a/Makefile.util.def b/Makefile.util.def
b71686
index cba4d5001..08cc98ddb 100644
d9d99f
--- a/Makefile.util.def
d9d99f
+++ b/Makefile.util.def
d9d99f
@@ -502,6 +502,13 @@ script = {
d9d99f
   condition = COND_HOST_LINUX;
d9d99f
 };
d9d99f
 
d9d99f
+script = {
d9d99f
+  name = '10_linux_bls';
d9d99f
+  common = util/grub.d/10_linux_bls.in;
d9d99f
+  installdir = grubconf;
d9d99f
+  condition = COND_HOST_LINUX;
d9d99f
+};
d9d99f
+
d9d99f
 script = {
d9d99f
   name = '10_xnu';
d9d99f
   common = util/grub.d/10_xnu.in;
d9d99f
diff --git a/util/grub.d/10_linux_bls.in b/util/grub.d/10_linux_bls.in
d9d99f
new file mode 100644
b71686
index 000000000..3cc7803c6
d9d99f
--- /dev/null
d9d99f
+++ b/util/grub.d/10_linux_bls.in
d9d99f
@@ -0,0 +1,440 @@
d9d99f
+#! /bin/sh
d9d99f
+set -e
d9d99f
+
d9d99f
+# grub-mkconfig helper script.
d9d99f
+# Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
d9d99f
+#
d9d99f
+# GRUB is free software: you can redistribute it and/or modify
d9d99f
+# it under the terms of the GNU General Public License as published by
d9d99f
+# the Free Software Foundation, either version 3 of the License, or
d9d99f
+# (at your option) any later version.
d9d99f
+#
d9d99f
+# GRUB is distributed in the hope that it will be useful,
d9d99f
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
d9d99f
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
d9d99f
+# GNU General Public License for more details.
d9d99f
+#
d9d99f
+# You should have received a copy of the GNU General Public License
d9d99f
+# along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
d9d99f
+
d9d99f
+prefix="@prefix@"
d9d99f
+exec_prefix="@exec_prefix@"
d9d99f
+datarootdir="@datarootdir@"
d9d99f
+
d9d99f
+. "$pkgdatadir/grub-mkconfig_lib"
d9d99f
+
d9d99f
+export TEXTDOMAIN=@PACKAGE@
d9d99f
+export TEXTDOMAINDIR="@localedir@"
d9d99f
+
d9d99f
+CLASS="--class gnu-linux --class gnu --class os --unrestricted"
d9d99f
+
d9d99f
+if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
d9d99f
+  OS="$(eval $(grep PRETTY_NAME /etc/os-release) ; echo ${PRETTY_NAME})"
d9d99f
+  CLASS="--class $(eval $(grep '^ID_LIKE=\|^ID=' /etc/os-release) ; [ -n "${ID_LIKE}" ] && echo ${ID_LIKE} || echo ${ID}) ${CLASS}"
d9d99f
+else
d9d99f
+  OS="${GRUB_DISTRIBUTOR}"
d9d99f
+  CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}"
d9d99f
+fi
d9d99f
+
d9d99f
+# loop-AES arranges things so that /dev/loop/X can be our root device, but
d9d99f
+# the initrds that Linux uses don't like that.
d9d99f
+case ${GRUB_DEVICE} in
d9d99f
+  /dev/loop/*|/dev/loop[0-9])
d9d99f
+    GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
d9d99f
+  ;;
d9d99f
+esac
d9d99f
+
d9d99f
+# Default to disabling partition uuid support to maintian compatibility with
d9d99f
+# older kernels.
d9d99f
+GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true}
d9d99f
+
d9d99f
+# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
d9d99f
+# and mounting btrfs requires user space scanning, so force UUID in this case.
d9d99f
+if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \
d9d99f
+    || ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
d9d99f
+	&& [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \
d9d99f
+    || ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
d9d99f
+	&& ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \
d9d99f
+    || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
d9d99f
+  LINUX_ROOT_DEVICE=${GRUB_DEVICE}
d9d99f
+elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \
d9d99f
+    || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then
d9d99f
+  LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID}
d9d99f
+else
d9d99f
+  LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
d9d99f
+fi
d9d99f
+
d9d99f
+case x"$GRUB_FS" in
d9d99f
+    xbtrfs)
d9d99f
+	if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ]; then
d9d99f
+	GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX} \${extra_cmdline}"
d9d99f
+	else
d9d99f
+	rootsubvol="`make_system_path_relative_to_its_root /`"
d9d99f
+	rootsubvol="${rootsubvol#/}"
d9d99f
+	if [ "x${rootsubvol}" != x ]; then
d9d99f
+	    GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
d9d99f
+	fi
d9d99f
+	fi;;
d9d99f
+    xzfs)
d9d99f
+	rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
d9d99f
+	bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
d9d99f
+	LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs}"
d9d99f
+	;;
d9d99f
+esac
d9d99f
+
d9d99f
+mktitle ()
d9d99f
+{
d9d99f
+  local title_type
d9d99f
+  local version
d9d99f
+  local OS_NAME
d9d99f
+  local OS_VERS
d9d99f
+
d9d99f
+  title_type=$1 && shift
d9d99f
+  version=$1 && shift
d9d99f
+
d9d99f
+  OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})"
d9d99f
+  OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})"
d9d99f
+
d9d99f
+  case $title_type in
d9d99f
+    recovery)
d9d99f
+      title=$(printf '%s (%s) %s (recovery mode)' \
d9d99f
+                     "${OS_NAME}" "${version}" "${OS_VERS}")
d9d99f
+      ;;
d9d99f
+    *)
d9d99f
+      title=$(printf '%s (%s) %s' \
d9d99f
+                     "${OS_NAME}" "${version}" "${OS_VERS}")
d9d99f
+      ;;
d9d99f
+  esac
d9d99f
+  echo -n ${title}
d9d99f
+}
d9d99f
+
d9d99f
+title_correction_code=
d9d99f
+
d9d99f
+populate_header_warn()
d9d99f
+{
d9d99f
+cat <
d9d99f
+
d9d99f
+# This section was generated by a script. Do not modify the generated file - all changes
d9d99f
+# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec files.
d9d99f
+
d9d99f
+EOF
d9d99f
+}
d9d99f
+
d9d99f
+read_config()
d9d99f
+{
d9d99f
+    config_file=${1}
d9d99f
+    title=""
d9d99f
+    initrd=""
d9d99f
+    options=""
d9d99f
+    linux=""
d9d99f
+
d9d99f
+    while read -r line
d9d99f
+    do
d9d99f
+        record=$(echo ${line} | cut -f 1 -d ' ')
d9d99f
+        value=$(echo ${line} | cut -s -f2- -d ' ')
d9d99f
+        case "${record}" in
d9d99f
+            "title")
d9d99f
+                title=${value}
d9d99f
+                ;;
d9d99f
+            "initrd")
d9d99f
+                initrd=${value}
d9d99f
+                ;;
d9d99f
+            "linux")
d9d99f
+                linux=${value}
d9d99f
+                ;;
d9d99f
+            "options")
d9d99f
+                options=${value}
d9d99f
+                ;;
d9d99f
+        esac
d9d99f
+    done < ${config_file}
d9d99f
+}
d9d99f
+
d9d99f
+populate_menu()
d9d99f
+{
d9d99f
+    entries_path="/boot/loader/entries"
d9d99f
+    gettext_printf "Generating boot entries from BLS files...\n" >&2
d9d99f
+    for config in $(ls -v -r $entries_path/*.conf); do
d9d99f
+        read_config ${config}
d9d99f
+        menu="${menu}menuentry '${title}' {\n"
d9d99f
+        menu="${menu}\t linux ${linux} ${options}\n"
d9d99f
+        if [ -n "${initrd}" ] ; then
d9d99f
+            menu="${menu}\t initrd ${boot_prefix}${initrd}\n"
d9d99f
+        fi
d9d99f
+        menu="${menu}}\n\n"
d9d99f
+    done
d9d99f
+    # The printf command seems to be more reliable across shells for special character (\n, \t) evaluation
d9d99f
+    printf "$menu"
d9d99f
+}
d9d99f
+
d9d99f
+linux_entry ()
d9d99f
+{
d9d99f
+  os="$1"
d9d99f
+  version="$2"
d9d99f
+  type="$3"
d9d99f
+  isdebug="$4"
d9d99f
+  args="$5"
d9d99f
+
d9d99f
+  if [ -z "$boot_device_id" ]; then
d9d99f
+      boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
d9d99f
+  fi
d9d99f
+
d9d99f
+  if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then
d9d99f
+    if [ x$dirname = x/ ]; then
d9d99f
+      if [ -z "${prepare_root_cache}" ]; then
d9d99f
+        prepare_grub_to_access_device ${GRUB_DEVICE}
d9d99f
+      fi
d9d99f
+    else
d9d99f
+      if [ -z "${prepare_boot_cache}" ]; then
d9d99f
+        prepare_grub_to_access_device ${GRUB_DEVICE_BOOT}
d9d99f
+      fi
d9d99f
+    fi
d9d99f
+
d9d99f
+    if [ -d /sys/firmware/efi ]; then
d9d99f
+        bootefi_device="`${grub_probe} --target=device /boot/efi/`"
d9d99f
+        prepare_grub_to_access_device ${bootefi_device} boot
d9d99f
+    else
d9d99f
+        boot_device="`${grub_probe} --target=device /boot/`"
d9d99f
+        prepare_grub_to_access_device ${boot_device} boot
d9d99f
+    fi
d9d99f
+
d9d99f
+    populate_header_warn
d9d99f
+    populate_menu
d9d99f
+
d9d99f
+    ${grub_editenv} - set saved_entry=0
d9d99f
+    ${grub_editenv} - set kernelopts="root=${linux_root_device_thisversion} ro ${args}"
d9d99f
+
d9d99f
+    exit 0
d9d99f
+  fi
d9d99f
+
d9d99f
+  if [ x$type != xsimple ] ; then
d9d99f
+      title=$(mktitle "$type" "$version")
d9d99f
+      if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
d9d99f
+	  replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
d9d99f
+	  quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
d9d99f
+	  title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;"
d9d99f
+      fi
d9d99f
+      if [ x$isdebug = xdebug ]; then
d9d99f
+	  title="$title${GRUB_LINUX_DEBUG_TITLE_POSTFIX}"
d9d99f
+      fi
d9d99f
+      echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
d9d99f
+  else
d9d99f
+      echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/"
d9d99f
+  fi
d9d99f
+  if [ x$type != xrecovery ] ; then
d9d99f
+      save_default_entry | grub_add_tab
d9d99f
+  fi
d9d99f
+
d9d99f
+  # Use ELILO's generic "efifb" when it's known to be available.
d9d99f
+  # FIXME: We need an interface to select vesafb in case efifb can't be used.
d9d99f
+  if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then
d9d99f
+      echo "	load_video" | sed "s/^/$submenu_indentation/"
d9d99f
+      if grep -qx "CONFIG_FB_EFI=y" "${config}" 2> /dev/null \
d9d99f
+	  && grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" "${config}" 2> /dev/null; then
d9d99f
+	  echo "	set gfxpayload=keep" | sed "s/^/$submenu_indentation/"
d9d99f
+      fi
d9d99f
+  else
d9d99f
+      if [ "x$GRUB_GFXPAYLOAD_LINUX" != xtext ]; then
d9d99f
+	  echo "	load_video" | sed "s/^/$submenu_indentation/"
d9d99f
+      fi
d9d99f
+      echo "	set gfxpayload=$GRUB_GFXPAYLOAD_LINUX" | sed "s/^/$submenu_indentation/"
d9d99f
+  fi
d9d99f
+
d9d99f
+  echo "	insmod gzio" | sed "s/^/$submenu_indentation/"
d9d99f
+
d9d99f
+  if [ x$dirname = x/ ]; then
d9d99f
+    if [ -z "${prepare_root_cache}" ]; then
d9d99f
+      prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | grub_add_tab)"
d9d99f
+    fi
d9d99f
+    printf '%s\n' "${prepare_root_cache}" | sed "s/^/$submenu_indentation/"
d9d99f
+  else
d9d99f
+    if [ -z "${prepare_boot_cache}" ]; then
d9d99f
+      prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)"
d9d99f
+    fi
d9d99f
+    printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/"
d9d99f
+  fi
d9d99f
+  sed "s/^/$submenu_indentation/" << EOF
d9d99f
+	linux	${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
d9d99f
+EOF
d9d99f
+  if test -n "${initrd}" ; then
d9d99f
+    initrd_path=
d9d99f
+    for i in ${initrd}; do
d9d99f
+      initrd_path="${initrd_path} ${rel_dirname}/${i}"
d9d99f
+    done
d9d99f
+    sed "s/^/$submenu_indentation/" << EOF
d9d99f
+	initrd	$(echo $initrd_path)
d9d99f
+EOF
d9d99f
+  fi
d9d99f
+  if test -n "${fdt}" ; then
d9d99f
+    sed "s/^/$submenu_indentation/" << EOF
d9d99f
+	devicetree	${rel_dirname}/${fdt}
d9d99f
+EOF
d9d99f
+  fi
d9d99f
+  sed "s/^/$submenu_indentation/" << EOF
d9d99f
+}
d9d99f
+EOF
d9d99f
+}
d9d99f
+
d9d99f
+machine=`uname -m`
d9d99f
+case "x$machine" in
d9d99f
+    xi?86 | xx86_64)
d9d99f
+	list=
d9d99f
+	for i in /boot/vmlinuz-* /vmlinuz-* /boot/kernel-* ; do
d9d99f
+	    if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
d9d99f
+	done ;;
d9d99f
+    *)
d9d99f
+	list=
d9d99f
+	for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* /boot/kernel-* ; do
d9d99f
+                  if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
d9d99f
+	done ;;
d9d99f
+esac
d9d99f
+
d9d99f
+if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then
d9d99f
+    for i in /boot/ostree/*/vmlinuz-* ; do
d9d99f
+        if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi
d9d99f
+    done
d9d99f
+fi
d9d99f
+
d9d99f
+case "$machine" in
d9d99f
+    i?86) GENKERNEL_ARCH="x86" ;;
d9d99f
+    mips|mips64) GENKERNEL_ARCH="mips" ;;
d9d99f
+    mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;;
d9d99f
+    arm*) GENKERNEL_ARCH="arm" ;;
d9d99f
+    *) GENKERNEL_ARCH="$machine" ;;
d9d99f
+esac
d9d99f
+
d9d99f
+prepare_boot_cache=
d9d99f
+prepare_root_cache=
d9d99f
+boot_device_id=
d9d99f
+title_correction_code=
d9d99f
+
d9d99f
+# Extra indentation to add to menu entries in a submenu. We're not in a submenu
d9d99f
+# yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
d9d99f
+submenu_indentation=""
d9d99f
+
d9d99f
+is_top_level=true
d9d99f
+while [ "x$list" != "x" ] ; do
d9d99f
+  linux=`version_find_latest $list`
d9d99f
+  if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then
d9d99f
+    gettext_printf "Found linux image: %s\n" "$linux" >&2
d9d99f
+  fi
d9d99f
+
d9d99f
+  basename=`basename $linux`
d9d99f
+  dirname=`dirname $linux`
d9d99f
+  rel_dirname=`make_system_path_relative_to_its_root $dirname`
d9d99f
+  version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
d9d99f
+  alt_version=`echo $version | sed -e "s,\.old$,,g"`
d9d99f
+  linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
d9d99f
+
d9d99f
+  initrd_early=
d9d99f
+  for i in ${GRUB_EARLY_INITRD_LINUX_STOCK} \
d9d99f
+	   ${GRUB_EARLY_INITRD_LINUX_CUSTOM}; do
d9d99f
+    if test -e "${dirname}/${i}" ; then
d9d99f
+      initrd_early="${initrd_early} ${i}"
d9d99f
+    fi
d9d99f
+  done
d9d99f
+
d9d99f
+  initrd_real=
d9d99f
+  for i in "initrd.img-${version}" "initrd-${version}.img" "initrd-${version}.gz" \
d9d99f
+	   "initrd-${version}" "initramfs-${version}.img" \
d9d99f
+	   "initrd.img-${alt_version}" "initrd-${alt_version}.img" \
d9d99f
+	   "initrd-${alt_version}" "initramfs-${alt_version}.img" \
d9d99f
+	   "initramfs-genkernel-${version}" \
d9d99f
+	   "initramfs-genkernel-${alt_version}" \
d9d99f
+	   "initramfs-genkernel-${GENKERNEL_ARCH}-${version}" \
d9d99f
+	   "initramfs-genkernel-${GENKERNEL_ARCH}-${alt_version}"; do
d9d99f
+    if test -e "${dirname}/${i}" ; then
d9d99f
+      initrd_real="${i}"
d9d99f
+      break
d9d99f
+    fi
d9d99f
+  done
d9d99f
+
d9d99f
+  initrd=
d9d99f
+  if test -n "${initrd_early}" || test -n "${initrd_real}"; then
d9d99f
+    initrd="${initrd_early} ${initrd_real}"
d9d99f
+
d9d99f
+    initrd_display=
d9d99f
+    for i in ${initrd}; do
d9d99f
+      initrd_display="${initrd_display} ${dirname}/${i}"
d9d99f
+    done
d9d99f
+    if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then
d9d99f
+      gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
d9d99f
+    fi
d9d99f
+  fi
d9d99f
+
d9d99f
+  fdt=
d9d99f
+  for i in "dtb-${version}" "dtb-${alt_version}"; do
d9d99f
+    if test -f "${dirname}/${i}/${GRUB_DEFAULT_DTB}" ; then
d9d99f
+      fdt="${i}/${GRUB_DEFAULT_DTB}"
d9d99f
+      break
d9d99f
+    fi
d9d99f
+  done
d9d99f
+
d9d99f
+  config=
d9d99f
+  for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do
d9d99f
+    if test -e "${i}" ; then
d9d99f
+      config="${i}"
d9d99f
+      break
d9d99f
+    fi
d9d99f
+  done
d9d99f
+
d9d99f
+  initramfs=
d9d99f
+  if test -n "${config}" ; then
d9d99f
+      initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr -d \"`
d9d99f
+  fi
d9d99f
+
d9d99f
+  if test -z "${initramfs}" && test -z "${initrd_real}" ; then
d9d99f
+    # "UUID=" and "ZFS=" magic is parsed by initrd or initramfs.  Since there's
d9d99f
+    # no initrd or builtin initramfs, it can't work here.
d9d99f
+    if [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] \
d9d99f
+	|| [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ]; then
d9d99f
+
d9d99f
+	linux_root_device_thisversion=${GRUB_DEVICE}
d9d99f
+    else
d9d99f
+	linux_root_device_thisversion=PARTUUID=${GRUB_DEVICE_PARTUUID}
d9d99f
+    fi
d9d99f
+  fi
d9d99f
+
d9d99f
+  if [ "x${GRUB_DISABLE_SUBMENU}" = "xyes" ] || [ "x${GRUB_DISABLE_SUBMENU}" = "xy" ]; then
d9d99f
+    GRUB_DISABLE_SUBMENU="true"
d9d99f
+  fi
d9d99f
+
d9d99f
+  if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then
d9d99f
+    linux_entry "${OS}" "${version}" simple standard \
d9d99f
+    "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
d9d99f
+    if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
d9d99f
+      linux_entry "${OS}" "${version}" simple debug \
d9d99f
+        "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} ${GRUB_CMDLINE_LINUX_DEBUG}"
d9d99f
+    fi
d9d99f
+
d9d99f
+    submenu_indentation="$grub_tab"
d9d99f
+
d9d99f
+    if [ -z "$boot_device_id" ]; then
d9d99f
+	boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
d9d99f
+    fi
d9d99f
+    # TRANSLATORS: %s is replaced with an OS name
d9d99f
+    echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {"
d9d99f
+    is_top_level=false
d9d99f
+  fi
d9d99f
+
d9d99f
+  linux_entry "${OS}" "${version}" advanced standard \
d9d99f
+              "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
d9d99f
+  if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
d9d99f
+    linux_entry "${OS}" "${version}" advanced debug \
d9d99f
+                "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} ${GRUB_CMDLINE_LINUX_DEBUG}"
d9d99f
+  fi
d9d99f
+
d9d99f
+  if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
d9d99f
+    linux_entry "${OS}" "${version}" recovery standard \
d9d99f
+                "single ${GRUB_CMDLINE_LINUX}"
d9d99f
+  fi
d9d99f
+
d9d99f
+  list=`echo $list | tr ' ' '\n' | fgrep -vx "$linux" | tr '\n' ' '`
d9d99f
+done
d9d99f
+
d9d99f
+# If at least one kernel was found, then we need to
d9d99f
+# add a closing '}' for the submenu command.
d9d99f
+if [ x"$is_top_level" != xtrue ]; then
d9d99f
+  echo '}'
d9d99f
+fi
d9d99f
+
d9d99f
+echo "$title_correction_code"