Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package grub2 for openSUSE:Factory checked 
in at 2024-06-09 20:18:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/grub2 (Old)
 and      /work/SRC/openSUSE:Factory/.grub2.new.19518 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "grub2"

Sun Jun  9 20:18:50 2024 rev:331 rq:1179115 version:2.12

Changes:
--------
--- /work/SRC/openSUSE:Factory/grub2/grub2.changes      2024-05-21 
18:33:18.359532247 +0200
+++ /work/SRC/openSUSE:Factory/.grub2.new.19518/grub2.changes   2024-06-09 
20:18:58.054877493 +0200
@@ -1,0 +2,14 @@
+Fri Jun  7 02:13:08 UTC 2024 - Michael Chang <mch...@suse.com>
+
+- Add blscfg support
+  * 0001-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch
+  * 0002-Add-BLS-support-to-grub-mkconfig.patch
+  * 0003-Add-grub2-switch-to-blscfg.patch
+  * 0004-blscfg-Don-t-root-device-in-emu-builds.patch
+  * 0005-blscfg-check-for-mounted-boot-in-emu.patch
+  * 0006-Follow-the-device-where-blscfg-is-discovered.patch
+  * 0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch
+  * 0008-blscfg-reading-bls-fragments-if-boot-present.patch
+  * 0009-10_linux-Some-refinement-for-BLS.patch
+
+-------------------------------------------------------------------

New:
----
  0001-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch
  0002-Add-BLS-support-to-grub-mkconfig.patch
  0003-Add-grub2-switch-to-blscfg.patch
  0004-blscfg-Don-t-root-device-in-emu-builds.patch
  0005-blscfg-check-for-mounted-boot-in-emu.patch
  0006-Follow-the-device-where-blscfg-is-discovered.patch
  0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch
  0008-blscfg-reading-bls-fragments-if-boot-present.patch
  0009-10_linux-Some-refinement-for-BLS.patch

BETA DEBUG BEGIN:
  New:- Add blscfg support
  * 0001-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch
  * 0002-Add-BLS-support-to-grub-mkconfig.patch
  New:  * 0001-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch
  * 0002-Add-BLS-support-to-grub-mkconfig.patch
  * 0003-Add-grub2-switch-to-blscfg.patch
  New:  * 0002-Add-BLS-support-to-grub-mkconfig.patch
  * 0003-Add-grub2-switch-to-blscfg.patch
  * 0004-blscfg-Don-t-root-device-in-emu-builds.patch
  New:  * 0003-Add-grub2-switch-to-blscfg.patch
  * 0004-blscfg-Don-t-root-device-in-emu-builds.patch
  * 0005-blscfg-check-for-mounted-boot-in-emu.patch
  New:  * 0004-blscfg-Don-t-root-device-in-emu-builds.patch
  * 0005-blscfg-check-for-mounted-boot-in-emu.patch
  * 0006-Follow-the-device-where-blscfg-is-discovered.patch
  New:  * 0005-blscfg-check-for-mounted-boot-in-emu.patch
  * 0006-Follow-the-device-where-blscfg-is-discovered.patch
  * 0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch
  New:  * 0006-Follow-the-device-where-blscfg-is-discovered.patch
  * 0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch
  * 0008-blscfg-reading-bls-fragments-if-boot-present.patch
  New:  * 0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch
  * 0008-blscfg-reading-bls-fragments-if-boot-present.patch
  * 0009-10_linux-Some-refinement-for-BLS.patch
  New:  * 0008-blscfg-reading-bls-fragments-if-boot-present.patch
  * 0009-10_linux-Some-refinement-for-BLS.patch
BETA DEBUG END:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ grub2.spec ++++++
--- /var/tmp/diff_new_pack.sYjgBs/_old  2024-06-09 20:19:01.210987588 +0200
+++ /var/tmp/diff_new_pack.sYjgBs/_new  2024-06-09 20:19:01.210987588 +0200
@@ -395,6 +395,15 @@
 Patch205:       0001-10_linux-Ensure-persistence-of-root-file-system-moun.patch
 Patch206:       0001-util-bash-completion-Fix-for-bash-completion-2.12.patch
 Patch207:       0001-util-enable-grub-protect-only-for-EFI-systems.patch
+Patch208:       0001-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch
+Patch209:       0002-Add-BLS-support-to-grub-mkconfig.patch
+Patch210:       0003-Add-grub2-switch-to-blscfg.patch
+Patch211:       0004-blscfg-Don-t-root-device-in-emu-builds.patch
+Patch212:       0005-blscfg-check-for-mounted-boot-in-emu.patch
+Patch213:       0006-Follow-the-device-where-blscfg-is-discovered.patch
+Patch214:       0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch
+Patch215:       0008-blscfg-reading-bls-fragments-if-boot-present.patch
+Patch216:       0009-10_linux-Some-refinement-for-BLS.patch
 
 Requires:       gettext-runtime
 %if 0%{?suse_version} >= 1140
@@ -697,7 +706,7 @@
 PXE_MODULES="tftp http"
 CRYPTO_MODULES="luks luks2 gcry_rijndael gcry_sha1 gcry_sha256 gcry_sha512 
crypttab"
 %ifarch %{efi}
-CD_MODULES="${CD_MODULES} chain efifwsetup efinet read tpm tpm2 memdisk tar 
squash4 xzio"
+CD_MODULES="${CD_MODULES} chain efifwsetup efinet read tpm tpm2 memdisk tar 
squash4 xzio blscfg"
 PXE_MODULES="${PXE_MODULES} efinet"
 %else
 CD_MODULES="${CD_MODULES} net ofnet"
@@ -1180,6 +1189,7 @@
 %{_sbindir}/%{name}-probe
 %{_sbindir}/%{name}-reboot
 %{_sbindir}/%{name}-set-default
+%{_sbindir}/%{name}-switch-to-blscfg
 %{_sbindir}/%{name}-check-default
 %{_bindir}/%{name}-editenv
 %{_bindir}/%{name}-file
@@ -1232,6 +1242,7 @@
 %{_mandir}/man8/%{name}-probe.8.*
 %{_mandir}/man8/%{name}-reboot.8.*
 %{_mandir}/man8/%{name}-set-default.8.*
+%{_mandir}/man8/%{name}-switch-to-blscfg.8.*
 %if %{emu}
 %{_bindir}/%{name}-emu
 %{_mandir}/man1/%{name}-emu.1.*

++++++ 0001-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch ++++++
++++ 1614 lines (skipped)

++++++ 0002-Add-BLS-support-to-grub-mkconfig.patch ++++++
>From 439de947262b0d8d4a02ca5afb1ef4f15853962c Mon Sep 17 00:00:00 2001
From: Peter Jones <pjo...@redhat.com>
Date: Fri, 9 Dec 2016 15:40:29 -0500
Subject: [PATCH 2/9] Add BLS support to grub-mkconfig

GRUB now has BootLoaderSpec support, the user can choose to use this by
setting GRUB_ENABLE_BLSCFG to true in /etc/default/grub. On this setup,
the boot menu entries are not added to the grub.cfg, instead BLS config
files are parsed by blscfg command and the entries created dynamically.

A 10_linux_bls grub.d snippet to generate menu entries from BLS files
is also added that can be used on platforms where the bootloader doesn't
have BLS support and only can parse a normal grub configuration file.

Portions of the 10_linux_bls were taken from the ostree-grub-generator
script that's included in the OSTree project.

Fixes to support multi-devices and generate a BLS section even if no
kernels are found in the boot directory were proposed by Yclept Nemo
and Tom Gundersen respectively.

Signed-off-by: Peter Jones <pjo...@redhat.com>
[javierm: remove outdated URL for BLS document]
Signed-off-by: Javier Martinez Canillas <javi...@redhat.com>
[iwien...@redhat.com: skip machine ID check when updating entries]
Signed-off-by: Ian Wienand <iwien...@redhat.com>
[rharwood: commit message composits, drop man pages]
Signed-off-by: Robbie Harwood <rharw...@redhat.com>
---
 util/grub-mkconfig.in     |   9 +-
 util/grub-mkconfig_lib.in |  22 +++-
 util/grub.d/10_linux.in   | 244 +++++++++++++++++++++++++++++++++++++-
 3 files changed, 269 insertions(+), 6 deletions(-)

diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
index cf5b79342..7af15df94 100644
--- a/util/grub-mkconfig.in
+++ b/util/grub-mkconfig.in
@@ -49,6 +49,8 @@ grub_script_check="${bindir}/@grub_script_check@"
 export TEXTDOMAIN=@PACKAGE@
 export TEXTDOMAINDIR="@localedir@"
 
+export GRUB_GRUBENV_UPDATE="yes"
+
 . "${pkgdatadir}/grub-mkconfig_lib"
 
 # Usage: usage
@@ -58,6 +60,7 @@ usage () {
     gettext "Generate a grub config file"; echo
     echo
     print_option_help "-o, --output=$(gettext FILE)" "$(gettext "output 
generated config to FILE [default=stdout]")"
+    print_option_help "--no-grubenv-update" "$(gettext "do not update 
variables in the grubenv file")"
     print_option_help "-h, --help" "$(gettext "print this message and exit")"
     print_option_help "-V, --version" "$(gettext "print the version 
information and exit")"
     echo
@@ -93,6 +96,9 @@ do
     --output=*)
        grub_cfg=`echo "$option" | sed 's/--output=//'`
        ;;
+    --no-grubenv-update)
+       GRUB_GRUBENV_UPDATE="no"
+       ;;
     -*)
        gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
        usage
@@ -300,7 +306,8 @@ export GRUB_DEFAULT \
   GRUB_DISABLE_SUBMENU \
   SUSE_BTRFS_SNAPSHOT_BOOTING \
   SUSE_CMDLINE_XENEFI \
-  SUSE_REMOVE_LINUX_ROOT_PARAM
+  SUSE_REMOVE_LINUX_ROOT_PARAM \
+  GRUB_ENABLE_BLSCFG
 
 if test "x${grub_cfg}" != "x"; then
   rm -f "${grub_cfg}.new"
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
index 22fb7668f..5db4337c6 100644
--- a/util/grub-mkconfig_lib.in
+++ b/util/grub-mkconfig_lib.in
@@ -30,6 +30,9 @@ fi
 if test "x$grub_file" = x; then
   grub_file="${bindir}/@grub_file@"
 fi
+if test "x$grub_editenv" = x; then
+  grub_editenv="${bindir}/@grub_editenv@"
+fi
 if test "x$grub_mkrelpath" = x; then
   grub_mkrelpath="${bindir}/@grub_mkrelpath@"
 fi
@@ -123,8 +126,19 @@ EOF
   fi
 }
 
+prepare_grub_to_access_device_with_variable ()
+{
+  device_variable="$1"
+  shift
+  prepare_grub_to_access_device "$@"
+  unset "device_variable"
+}
+
 prepare_grub_to_access_device ()
 {
+  if [ -z "$device_variable" ]; then
+    device_variable="root"
+  fi
   old_ifs="$IFS"
   IFS='
 '
@@ -159,18 +173,18 @@ prepare_grub_to_access_device ()
   # otherwise set root as per value in device.map.
   fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`"
   if [ "x$fs_hint" != x ]; then
-    echo "set root='$fs_hint'"
+    echo "set ${device_variable}='$fs_hint'"
   fi
   if [ "x${GRUB_DISABLE_UUID}" != "xtrue" ] && fs_uuid="`"${grub_probe}" 
--device $@ --target=fs_uuid 2> /dev/null`" ; then
     hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" 
|| hints=
     if [ "x$hints" != x ]; then
       echo "if [ x\$feature_platform_search_hint = xy ]; then"
-      echo "  search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"
+      echo "  search --no-floppy --fs-uuid --set=${device_variable} ${hints} 
${fs_uuid}"
       echo "else"
-      echo "  search --no-floppy --fs-uuid --set=root ${fs_uuid}"
+      echo "  search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}"
       echo "fi"
     else
-      echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}"
+      echo "search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}"
     fi
   fi
   IFS="$old_ifs"
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
index 5531239eb..49eccbeaf 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
@@ -91,6 +91,244 @@ if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then
   LINUX_ROOT_DEVICE=""
 fi
 
+populate_header_warn()
+{
+if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then
+  bls_parser="10_linux script"
+else
+  bls_parser="blscfg command"
+fi
+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 $bls_parser 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://systemd.io/BOOT_LOADER_SPECIFICATION/.
+
+EOF
+}
+
+read_config()
+{
+    config_file=${1}
+    title=""
+    initrd=""
+    options=""
+    linux=""
+    grub_arg=""
+
+    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}
+                ;;
+            "grub_arg")
+                grub_arg=${value}
+                ;;
+        esac
+    done < ${config_file}
+}
+
+blsdir="/boot/loader/entries"
+
+get_sorted_bls()
+{
+    if ! [ -d "${blsdir}" ]; then
+        return
+    fi
+
+    local IFS=$'\n'
+
+    files=($(for bls in ${blsdir}/*.conf; do
+        if ! [[ -e "${bls}" ]] ; then
+            continue
+        fi
+        bls="${bls%.conf}"
+        bls="${bls##*/}"
+        echo "${bls}"
+    done | ${kernel_sort} 2>/dev/null | tac)) || :
+
+    echo "${files[@]}"
+}
+
+update_bls_cmdline()
+{
+    local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} 
${GRUB_CMDLINE_LINUX_DEFAULT}"
+    local -a files=($(get_sorted_bls))
+
+    for bls in "${files[@]}"; do
+        local options="${cmdline}"
+        if [ -z "${bls##*debug*}" ]; then
+            options="${options} ${GRUB_CMDLINE_LINUX_DEBUG}"
+        fi
+        options="$(echo "${options}" | sed -e 's/\//\\\//g')"
+        sed -i -e "s/^options.*/options ${options}/" "${blsdir}/${bls}.conf"
+    done
+}
+
+populate_menu()
+{
+    local -a files=($(get_sorted_bls))
+
+    gettext_printf "Generating boot entries from BLS files...\n" >&2
+
+    for bls in "${files[@]}"; do
+        read_config "${blsdir}/${bls}.conf"
+
+        menu="${menu}menuentry '${title}' ${grub_arg} --id=${bls} {\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"
+}
+
+# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not 
installed.
+if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null; 
then
+         GRUB_ENABLE_BLSCFG="true"
+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_with_variable boot ${bootefi_device}
+  else
+      boot_device="`${grub_probe} --target=device /boot/`"
+      prepare_grub_to_access_device_with_variable boot ${boot_device}
+  fi
+
+  arch="$(uname -m)"
+  if [ "x${arch}" = "xppc64le" ] && [ -d /sys/firmware/opal ]; then
+
+      BLS_POPULATE_MENU="true"
+      
petitboot_path="/sys/firmware/devicetree/base/ibm,firmware-versions/petitboot"
+
+      if test -e ${petitboot_path}; then
+          read -r -d '' petitboot_version < ${petitboot_path}
+          petitboot_version="$(echo ${petitboot_version//v})"
+
+         if test -n ${petitboot_version}; then
+              major_version="$(echo ${petitboot_version} | cut -d . -f1)"
+              minor_version="$(echo ${petitboot_version} | cut -d . -f2)"
+
+              re='^[0-9]+$'
+              if [[ $major_version =~ $re ]] && [[ $minor_version =~ $re ]] &&
+                 ([[ ${major_version} -gt 1 ]] ||
+                  [[ ${major_version} -eq 1 &&
+                     ${minor_version} -ge 8  ]]); then
+                  BLS_POPULATE_MENU="false"
+              fi
+          fi
+      fi
+  fi
+
+  populate_header_warn
+
+  cat << EOF
+# The kernelopts variable should be defined in the grubenv file. But to ensure 
that menu
+# entries populated from BootLoaderSpec files that use this variable work 
correctly even
+# without a grubenv file, define a fallback kernelopts variable if this has 
not been set.
+#
+# The kernelopts variable in the grubenv file can be modified using the grubby 
tool or by
+# executing the grub2-mkconfig tool. For the latter, the values of the 
GRUB_CMDLINE_LINUX
+# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used 
to set both
+# the kernelopts variable in the grubenv file and the fallback kernelopts 
variable.
+if [ -z "\${kernelopts}" ]; then
+  set kernelopts="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} 
${GRUB_CMDLINE_LINUX_DEFAULT}"
+fi
+EOF
+
+  update_bls_cmdline
+
+  if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then
+      populate_menu
+  else
+      cat << EOF
+
+insmod blscfg
+blscfg
+EOF
+  fi
+
+  if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then
+      blsdir="/boot/loader/entries"
+      [ -d "${blsdir}" ] && GRUB_BLS_FS="$(${grub_probe} --target=fs 
${blsdir})"
+      if [ "x${GRUB_BLS_FS}" = "xbtrfs" ] || [ "x${GRUB_BLS_FS}" = "xzfs" ]; 
then
+          blsdir=$(make_system_path_relative_to_its_root "${blsdir}")
+          if [ "x${blsdir}" != "x/loader/entries" ] && [ "x${blsdir}" != 
"x/boot/loader/entries" ]; then
+              ${grub_editenv} - set blsdir="${blsdir}"
+          fi
+      fi
+
+      if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then
+          ${grub_editenv} - set 
early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}"
+      fi
+
+      if [ -n "${GRUB_DEFAULT_DTB}" ]; then
+          ${grub_editenv} - set devicetree="${GRUB_DEFAULT_DTB}"
+      fi
+
+      if [ -n "${GRUB_SAVEDEFAULT}" ]; then
+           ${grub_editenv} - set save_default="${GRUB_SAVEDEFAULT}"
+      fi
+  fi
+
+  exit 0
+fi
+
+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=
 
 hotkey=1
@@ -124,6 +362,7 @@ linux_entry ()
   if [ -z "$boot_device_id" ]; then
       boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
   fi
+
   if [ x$type != xsimple ] ; then
       case $type in
          recovery)
@@ -298,6 +537,7 @@ fi
 is_top_level=true
 for linux in ${reverse_sorted_list}; do
   gettext_printf "Found linux image: %s\n" "$linux" >&2
+
   basename=`basename $linux`
   dirname=`dirname $linux`
   rel_dirname=`make_system_path_relative_to_its_root $dirname`
@@ -348,7 +588,9 @@ for linux in ${reverse_sorted_list}; do
     for i in ${initrd}; do
       initrd_display="${initrd_display} ${dirname}/${i}"
     done
-    gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
+    if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then
+      gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
+    fi
   fi
 
   config=
-- 
2.44.0


++++++ 0003-Add-grub2-switch-to-blscfg.patch ++++++
>From 90153f1c9631498723450d84e014e25865fecc1b Mon Sep 17 00:00:00 2001
From: Peter Jones <pjo...@redhat.com>
Date: Thu, 15 Mar 2018 14:12:40 -0400
Subject: [PATCH 3/9] Add grub2-switch-to-blscfg

Signed-off-by: Peter Jones <pjo...@redhat.com>
Signed-off-by: Javier Martinez Canillas <javi...@redhat.com>
[jhlavac: Use ${etcdefaultgrub} instead of /etc/default/grub]
Signed-off-by: Jan Hlavac <jhla...@redhat.com>
[rharwood: skip on ostree installations, migrate man to h2m]
Signed-off-by: Robbie Harwood <rharw...@redhat.com>
---
 Makefile.util.def                  |   7 +
 docs/man/grub-switch-to-blscfg.h2m |   2 +
 util/grub-switch-to-blscfg.in      | 317 +++++++++++++++++++++++++++++
 util/grub.d/10_linux.in            |   2 +-
 4 files changed, 327 insertions(+), 1 deletion(-)
 create mode 100644 docs/man/grub-switch-to-blscfg.h2m
 create mode 100644 util/grub-switch-to-blscfg.in

diff --git a/Makefile.util.def b/Makefile.util.def
index 6bb30c165..ffedea24a 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -1460,6 +1460,13 @@ program = {
   ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
 };
 
+script = {
+  name = grub-switch-to-blscfg;
+  common = util/grub-switch-to-blscfg.in;
+  mansection = 8;
+  installdir = sbin;
+};
+
 program = {
   name = grub-glue-efi;
   mansection = 1;
diff --git a/docs/man/grub-switch-to-blscfg.h2m 
b/docs/man/grub-switch-to-blscfg.h2m
new file mode 100644
index 000000000..fa341426a
--- /dev/null
+++ b/docs/man/grub-switch-to-blscfg.h2m
@@ -0,0 +1,2 @@
+[NAME]
+grub-switch-to-blscfg \- switch to using BLS config files
diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in
new file mode 100644
index 000000000..a851424be
--- /dev/null
+++ b/util/grub-switch-to-blscfg.in
@@ -0,0 +1,317 @@
+#! /bin/sh
+#
+# Set a default boot entry for GRUB.
+# Copyright (C) 2004,2009  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/>.
+
+#set -eu
+
+# Initialize some variables.
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+bindir=@bindir@
+sysconfdir="@sysconfdir@"
+PACKAGE_NAME=@PACKAGE_NAME@
+PACKAGE_VERSION=@PACKAGE_VERSION@
+datarootdir="@datarootdir@"
+datadir="@datadir@"
+if [ ! -v pkgdatadir ]; then
+    pkgdatadir="${datadir}/@PACKAGE@"
+fi
+
+self=`basename $0`
+
+grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@"
+grub_editenv=${bindir}/@grub_editenv@
+etcdefaultgrub=/etc/default/grub
+
+eval "$("${grub_get_kernel_settings}")" || true
+
+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 
's/\"//g')
+if [ -d /sys/firmware/efi/efivars/ ]; then
+    startlink=/etc/grub2-efi.cfg
+    grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'`
+else
+    startlink=/etc/grub2.cfg
+    grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
+fi
+
+blsdir=`echo "/@bootdirname@/loader/entries" | sed 's,//*,/,g'`
+
+backupsuffix=.bak
+
+arch="$(uname -m)"
+
+export TEXTDOMAIN=@PACKAGE@
+export TEXTDOMAINDIR="@localedir@"
+
+. "${pkgdatadir}/grub-mkconfig_lib"
+
+# Usage: usage
+# Print the usage.
+usage () {
+    gettext_printf "Usage: %s\n" "$self"
+    gettext "Switch to BLS config files.\n"; echo
+    echo
+    print_option_help "-h, --help" "$(gettext "print this message and exit")"
+    print_option_help "-V, --version" "$(gettext "print the version 
information and exit")"
+    echo
+    print_option_help "--backup-suffix=$(gettext "SUFFIX")" "$backupsuffix"
+    print_option_help "--bls-directory=$(gettext "DIR")" "$blsdir"
+    print_option_help "--config-file=$(gettext "FILE")" "$startlink"
+    print_option_help "--grub-defaults=$(gettext "FILE")" "$etcdefaultgrub"
+    print_option_help "--grub-directory=$(gettext "DIR")" "$grubdir"
+    # echo
+    # gettext "Report bugs to <bug-g...@gnu.org>."; echo
+}
+
+argument () {
+    opt=$1
+    shift
+
+    if test $# -eq 0; then
+        gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" 
"$opt" 1>&2
+        exit 1
+    fi
+    echo $1
+}
+
+# Check the arguments.
+while test $# -gt 0
+do
+    option=$1
+    shift
+
+    case "$option" in
+    -h | --help)
+        usage
+        exit 0 ;;
+    -V | --version)
+        echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
+        exit 0 ;;
+
+    --backup-suffix)
+        backupsuffix=`argument $option "$@"`
+        shift
+        ;;
+    --backup-suffix=*)
+        backupsuffix=`echo "$option" | sed 's/--backup-suffix=//'`
+        ;;
+
+    --bls-directory)
+        blsdir=`argument $option "$@"`
+        shift
+        ;;
+    --bls-directory=*)
+        blsdir=`echo "$option" | sed 's/--bls-directory=//'`
+        ;;
+
+    --config-file)
+        startlink=`argument $option "$@"`
+        shift
+        ;;
+    --config-file=*)
+        startlink=`echo "$option" | sed 's/--config-file=//'`
+        ;;
+
+    --grub-defaults)
+        etcdefaultgrub=`argument $option "$@"`
+        shift
+        ;;
+    --grub-defaults=*)
+        etcdefaultgrub=`echo "$option" | sed 's/--grub-defaults=//'`
+        ;;
+
+    --grub-directory)
+        grubdir=`argument $option "$@"`
+        shift
+        ;;
+    --grub-directory=*)
+        grubdir=`echo "$option" | sed 's/--grub-directory=//'`
+        ;;
+
+    *)
+        gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
+        usage
+        exit 1
+        ;;
+    esac
+done
+
+find_grub_cfg() {
+    local candidate=""
+    while [ -e "${candidate}" -o $# -gt 0 ]
+    do
+        if [ ! -e "${candidate}" ] ; then
+            candidate="$1"
+            shift
+        fi
+
+        if [ -L "${candidate}" ]; then
+            candidate="$(realpath "${candidate}")"
+        fi
+
+        if [ -f "${candidate}" ]; then
+            export GRUB_CONFIG_FILE="${candidate}"
+            return 0
+        fi
+    done
+    return 1
+}
+
+if ! find_grub_cfg ${startlink} ${grubdir}/grub.cfg ; then
+  gettext_printf "Couldn't find config file\n" 1>&2
+  exit 1
+fi
+
+if [ ! -d "${blsdir}" ]; then
+    install -m 700 -d "${blsdir}"
+fi
+
+if [ -f /etc/machine-id ]; then
+    MACHINE_ID=$(cat /etc/machine-id)
+else
+    MACHINE_ID=$(dmesg | sha256sum)
+fi
+
+mkbls() {
+    local kernelver=$1 && shift
+    local datetime=$1 && shift
+    local kernelopts=$1 && shift
+
+    local debugname=""
+    local debugid=""
+    local flavor=""
+
+    if [ "$kernelver" == *\+* ] ; then
+        local flavor=-"${kernelver##*+}"
+        if [ "${flavor}" == "-debug" ]; then
+            local debugname=" with debugging"
+            local debugid="-debug"
+        fi
+    fi
+    (
+        source /etc/os-release
+
+        cat <<EOF
+title ${NAME} (${kernelver}) ${VERSION}${debugname}
+version ${kernelver}${debugid}
+linux /vmlinuz-${kernelver}
+initrd /initramfs-${kernelver}.img
+options ${kernelopts}
+grub_users \$grub_users
+grub_arg --unrestricted
+grub_class kernel${flavor}
+EOF
+    ) | cat
+}
+
+copy_bls() {
+    for kernelver in $(cd /lib/modules/ ; ls -1) "" ; do
+       bls_target="${blsdir}/${MACHINE_ID}-${kernelver}.conf"
+       linux="/vmlinuz-${kernelver}"
+       linux_path="/boot${linux}"
+       kernel_dir="/lib/modules/${kernelver}"
+
+       if [ ! -d "${kernel_dir}" ] ; then
+            continue
+       fi
+       if [ ! -f "${linux_path}" ]; then
+            continue
+       fi
+
+       linux_relpath="$("${grub_mkrelpath}" "${linux_path}")"
+       bootprefix="${linux_relpath%%"${linux}"}"
+       cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} 
${GRUB_CMDLINE_LINUX_DEFAULT}"
+
+       mkbls "${kernelver}" \
+             "$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${kernel_dir}")")" \
+             "${bootprefix}" "${cmdline}" >"${bls_target}"
+
+       if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
+            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]*//')"
+            options="$(echo "${cmdline} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 
's/\//\\\//g')"
+            sed -i -e "s/^title.*/title 
${title}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${bls_debug}"
+            sed -i -e "s/^options.*/options ${options}/" "${bls_debug}"
+       fi
+    done
+
+    if [ -f "/boot/vmlinuz-0-rescue-${MACHINE_ID}" ]; then
+       mkbls "0-rescue-${MACHINE_ID}" "0" "${bootprefix}" 
>"${blsdir}/${MACHINE_ID}-0-rescue.conf"
+    fi
+}
+
+# The grub2 EFI binary is not copied to the ESP as a part of an ostree
+# transaction. Make sure a grub2 version with BLS support is installed
+# but only do this if the blsdir is not set, to make sure that the BLS
+# parsing module will search for the BLS snippets in the default path.
+if test -f /run/ostree-booted && test -d /sys/firmware/efi/efivars && \
+   ! ${grub_editenv} - list | grep -q blsdir && \
+   mountpoint -q /boot; then
+    grub_binary="$(find /usr/lib/ostree-boot/efi/EFI/${EFIDIR}/ -name 
grub*.efi)"
+    install -m 700 ${grub_binary} ${grubdir} || exit 1
+    # Create a hidden file to indicate that grub2 now has BLS support.
+    touch /boot/grub2/.grub2-blscfg-supported
+fi
+
+GENERATE=0
+if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \
+        | grep -vq '^GRUB_ENABLE_BLSCFG="*true"*\s*$' ; then
+    if ! sed -i"${backupsuffix}" \
+            -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=true,' \
+            "${etcdefaultgrub}" ; then
+        gettext_printf "Updating %s failed\n" "${etcdefaultgrub}"
+        exit 1
+    fi
+    GENERATE=1
+elif ! grep -q '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" ; then
+    if ! echo 'GRUB_ENABLE_BLSCFG=true' >> "${etcdefaultgrub}" ; then
+        gettext_printf "Updating %s failed\n" "${etcdefaultgrub}"
+        exit 1
+    fi
+    GENERATE=1
+fi
+
+if [ "${GENERATE}" -eq 1 ] ; then
+    copy_bls
+
+    if [ $arch = "x86_64" ] && [ ! -d /sys/firmware/efi ]; then
+       mod_dir="i386-pc"
+    elif [ $arch = "ppc64" -o $arch = "ppc64le" ] && [ ! -d /sys/firmware/opal 
]; then
+       mod_dir="powerpc-ieee1275"
+    fi
+
+    if [ -n "${mod_dir}" ]; then
+       for mod in blscfg increment; do
+           install -m 700 ${prefix}/lib/grub/${mod_dir}/${mod}.mod 
${grubdir}/$mod_dir/ || exit 1
+       done
+    fi
+
+    cp -af "${GRUB_CONFIG_FILE}" "${GRUB_CONFIG_FILE}${backupsuffix}"
+    if ! grub2-mkconfig -o "${GRUB_CONFIG_FILE}" ; then
+        install -m 700 "${GRUB_CONFIG_FILE}${backupsuffix}" 
"${GRUB_CONFIG_FILE}"
+        sed -i"${backupsuffix}" \
+            -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=false,' \
+            "${etcdefaultgrub}"
+        gettext_printf "Updating %s failed\n" "${GRUB_CONFIG_FILE}"
+        exit 1
+    fi
+fi
+
+# Bye.
+exit 0
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
index 49eccbeaf..45eefb332 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
@@ -147,7 +147,7 @@ blsdir="/boot/loader/entries"
 
 get_sorted_bls()
 {
-    if ! [ -d "${blsdir}" ]; then
+    if ! [ -d "${blsdir}" ] || [ -f /run/ostree-booted ] || [ -d /ostree/repo 
]; then
         return
     fi
 
-- 
2.44.0


++++++ 0004-blscfg-Don-t-root-device-in-emu-builds.patch ++++++
>From 2fccb958910afaaf03cbec1a6b98ad197d088ad4 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharw...@redhat.com>
Date: Thu, 25 Aug 2022 17:57:55 -0400
Subject: [PATCH 4/9] blscfg: Don't root device in emu builds

Otherwise, we end up looking for kernel/initrd in /boot/boot which
doesn't work at all.  Non-emu builds need to be looking in
($root)/boot/, which is what this is for.

Signed-off-by: Robbie Harwood <rharw...@redhat.com>
---
 grub-core/commands/blscfg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
index 7132555df..150ca96f4 100644
--- a/grub-core/commands/blscfg.c
+++ b/grub-core/commands/blscfg.c
@@ -41,7 +41,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
 
 #define GRUB_BLS_CONFIG_PATH "/loader/entries/"
 #ifdef GRUB_MACHINE_EMU
-#define GRUB_BOOT_DEVICE "/boot"
+#define GRUB_BOOT_DEVICE ""
 #else
 #define GRUB_BOOT_DEVICE "($root)"
 #endif
-- 
2.44.0


++++++ 0005-blscfg-check-for-mounted-boot-in-emu.patch ++++++
>From 6d33393fd3c538aaead2698777c02d6d6d0221c9 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharw...@redhat.com>
Date: Tue, 7 Mar 2023 18:59:40 -0500
Subject: [PATCH 5/9] blscfg: check for mounted /boot in emu

Irritatingly, BLS defines paths relatives to the mountpoint of the
filesystem which contains its snippets, not / or any other fixed
location.  So grub2-emu needs to know whether /boot is a separate
filesysem from / and conditionally prepend a path.

Signed-off-by: Robbie Harwood <rharw...@redhat.com>
---
 grub-core/commands/blscfg.c | 54 +++++++++++++++++++++++++++++++++----
 1 file changed, 49 insertions(+), 5 deletions(-)

diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
index 150ca96f4..6495891b9 100644
--- a/grub-core/commands/blscfg.c
+++ b/grub-core/commands/blscfg.c
@@ -40,8 +40,9 @@ GRUB_MOD_LICENSE ("GPLv3+");
 #include "loadenv.h"
 
 #define GRUB_BLS_CONFIG_PATH "/loader/entries/"
+
 #ifdef GRUB_MACHINE_EMU
-#define GRUB_BOOT_DEVICE ""
+#define GRUB_BOOT_DEVICE "/boot"
 #else
 #define GRUB_BOOT_DEVICE "($root)"
 #endif
@@ -54,8 +55,50 @@ struct keyval
 
 static struct bls_entry *entries = NULL;
 
+/* Cache probing in frob_boot_device().  Used for linux entry also.
+ * Always true in non-emu, meaning to prefix things with GRUB_BOOT_DEVICE. */
+static int separate_boot = -1;
+
 #define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
 
+/* BLS appears to make paths relative to the filesystem that snippets are
+ * on, not /.  Attempt to cope. */
+static char *frob_boot_device(char *tmp)
+{
+#ifdef GRUB_MACHINE_EMU
+  grub_file_t f;
+  char *line = NULL;
+
+  if (separate_boot != -1)
+    goto probed;
+
+  separate_boot = 0;
+
+  f = grub_file_open ("/proc/mounts", GRUB_FILE_TYPE_CONFIG);
+  if (f == NULL)
+    goto probed;
+
+  while ((line = grub_file_getline (f)))
+    {
+      if (grub_strstr (line, " " GRUB_BOOT_DEVICE " "))
+       {
+         separate_boot = 1;
+         grub_free (line);
+         break;
+       }
+
+      grub_free(line);
+    }
+
+  grub_file_close (f);
+ probed:
+  if (!separate_boot)
+    return grub_stpcpy (tmp, " ");
+#endif
+
+  return grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
+}
+
 static int bls_add_keyval(struct bls_entry *entry, char *key, char *val)
 {
   char *k, *v;
@@ -842,7 +885,7 @@ static void create_entry (struct bls_entry *entry)
       for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
        {
          grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]);
-         tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
+         tmp = frob_boot_device (tmp);
          tmp = grub_stpcpy (tmp, initrd_prefix);
          tmp = grub_stpcpy (tmp, early_initrds[i]);
          grub_free(early_initrds[i]);
@@ -851,7 +894,7 @@ static void create_entry (struct bls_entry *entry)
       for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
        {
          grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]);
-         tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
+         tmp = frob_boot_device (tmp);
          tmp = grub_stpcpy (tmp, initrds[i]);
        }
       tmp = grub_stpcpy (tmp, "\n");
@@ -888,7 +931,7 @@ static void create_entry (struct bls_entry *entry)
         }
       char *tmp = dt;
       tmp = grub_stpcpy (dt, "devicetree");
-      tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
+      tmp = frob_boot_device (tmp);
       if (add_dt_prefix)
         tmp = grub_stpcpy (tmp, prefix);
       tmp = grub_stpcpy (tmp, devicetree);
@@ -907,7 +950,8 @@ static void create_entry (struct bls_entry *entry)
                        "linux %s%s%s%s\n"
                        "%s%s",
                        savedefault ? "savedefault\n" : "",
-                       GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? 
options : "",
+                       separate_boot ? GRUB_BOOT_DEVICE : "",
+                       clinux, options ? " " : "", options ? options : "",
                        initrd ? initrd : "", dt ? dt : "");
 
   grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, 
src, 0, 0, &index, entry);
-- 
2.44.0


++++++ 0006-Follow-the-device-where-blscfg-is-discovered.patch ++++++
>From 6523d493b0772316a3fbb249eb070ada5d266a98 Mon Sep 17 00:00:00 2001
From: Michael Chang <mch...@suse.com>
Date: Wed, 28 Jun 2023 14:32:40 +0800
Subject: [PATCH 6/9] Follow the device where blscfg is discovered

Previously, the code assumed that GRUB_BOOT_DEVICE "($root)" was always
the correct device for the discovered bls menu. However, this assumption
could lead to inaccuracies when attempting to load bls for devices other
than $root.

This patch introduces a more robust approach by utilizing the `struct
find_entry_info *info->devid` parameter, representing the device used to
discover the bls directory. This change ensures consistency in
subsequent translations to native GRUB commands, eliminating potential
discrepancies in device identification during the blscfg process.

Signed-off-by: Michael Chang <mch...@suse.com>
---
 grub-core/commands/blscfg.c | 40 +++++++++++++++++++++++++------------
 include/grub/menu.h         |  1 +
 2 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
index 6495891b9..c872bcef0 100644
--- a/grub-core/commands/blscfg.c
+++ b/grub-core/commands/blscfg.c
@@ -55,15 +55,18 @@ struct keyval
 
 static struct bls_entry *entries = NULL;
 
-/* Cache probing in frob_boot_device().  Used for linux entry also.
- * Always true in non-emu, meaning to prefix things with GRUB_BOOT_DEVICE. */
-static int separate_boot = -1;
-
 #define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
 
 /* BLS appears to make paths relative to the filesystem that snippets are
  * on, not /.  Attempt to cope. */
-static char *frob_boot_device(char *tmp)
+#ifdef GRUB_MACHINE_EMU
+/* Cache probing in frob_boot_device().  Used for linux entry also.
+ * Unused in non-emu, meaning to prefix things with device of parent blsdir. */
+static int separate_boot = -1;
+static char *frob_boot_device(char *tmp, const char *bootdev UNUSED)
+#else
+static char *frob_boot_device(char *tmp, const char *bootdev)
+#endif
 {
 #ifdef GRUB_MACHINE_EMU
   grub_file_t f;
@@ -94,9 +97,11 @@ static char *frob_boot_device(char *tmp)
  probed:
   if (!separate_boot)
     return grub_stpcpy (tmp, " ");
-#endif
-
   return grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
+#else
+  tmp = grub_stpcpy (tmp, " ");
+  return grub_stpcpy (tmp, bootdev);
+#endif
 }
 
 static int bls_add_keyval(struct bls_entry *entry, char *key, char *val)
@@ -568,6 +573,9 @@ static int read_entry (
       if (rc < 0)
        break;
     }
+  
+    if (info->devid)
+      entry->devid = grub_strdup(info->devid);
 
     if (!rc)
       bls_add_entry(entry);
@@ -772,6 +780,7 @@ static void create_entry (struct bls_entry *entry)
   char *id = entry->filename;
   char *dotconf = id;
   char *hotkey = NULL;
+  char *bootdev = entry->devid ? grub_xasprintf("(%s)", entry->devid) : 
grub_strdup (GRUB_BOOT_DEVICE);
 
   char *users = NULL;
   char **classes = NULL;
@@ -865,12 +874,12 @@ static void create_entry (struct bls_entry *entry)
       char *tmp;
 
       for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
-       initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \
+       initrd_size += sizeof (" ") + grub_strlen (bootdev) \
                       + grub_strlen(initrd_prefix)  \
                       + grub_strlen (early_initrds[i]) + 1;
 
       for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
-       initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \
+       initrd_size += sizeof (" ") + grub_strlen (bootdev) \
                       + grub_strlen (initrds[i]) + 1;
       initrd_size += 1;
 
@@ -885,7 +894,7 @@ static void create_entry (struct bls_entry *entry)
       for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
        {
          grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]);
-         tmp = frob_boot_device (tmp);
+         tmp = frob_boot_device (tmp, bootdev);
          tmp = grub_stpcpy (tmp, initrd_prefix);
          tmp = grub_stpcpy (tmp, early_initrds[i]);
          grub_free(early_initrds[i]);
@@ -894,7 +903,7 @@ static void create_entry (struct bls_entry *entry)
       for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
        {
          grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]);
-         tmp = frob_boot_device (tmp);
+         tmp = frob_boot_device (tmp, bootdev);
          tmp = grub_stpcpy (tmp, initrds[i]);
        }
       tmp = grub_stpcpy (tmp, "\n");
@@ -916,7 +925,7 @@ static void create_entry (struct bls_entry *entry)
            }
        }
 
-      dt_size = sizeof("devicetree " GRUB_BOOT_DEVICE) + 
grub_strlen(devicetree) + 1;
+      dt_size = sizeof("devicetree ") + grub_strlen(bootdev) + 
grub_strlen(devicetree) + 1;
 
       if (add_dt_prefix)
        {
@@ -931,7 +940,7 @@ static void create_entry (struct bls_entry *entry)
         }
       char *tmp = dt;
       tmp = grub_stpcpy (dt, "devicetree");
-      tmp = frob_boot_device (tmp);
+      tmp = frob_boot_device (tmp, bootdev);
       if (add_dt_prefix)
         tmp = grub_stpcpy (tmp, prefix);
       tmp = grub_stpcpy (tmp, devicetree);
@@ -950,7 +959,11 @@ static void create_entry (struct bls_entry *entry)
                        "linux %s%s%s%s\n"
                        "%s%s",
                        savedefault ? "savedefault\n" : "",
+#ifdef GRUB_MACHINE_EMU
                        separate_boot ? GRUB_BOOT_DEVICE : "",
+#else
+                       bootdev,
+#endif
                        clinux, options ? " " : "", options ? options : "",
                        initrd ? initrd : "", dt ? dt : "");
 
@@ -969,6 +982,7 @@ finish:
   grub_free (args);
   grub_free (argv);
   grub_free (src);
+  grub_free (bootdev);
 }
 
 struct find_entry_info {
diff --git a/include/grub/menu.h b/include/grub/menu.h
index 43080828c..76b191c33 100644
--- a/include/grub/menu.h
+++ b/include/grub/menu.h
@@ -28,6 +28,7 @@ struct bls_entry
   int nkeyvals;
   char *filename;
   int visible;
+  const char *devid;
 };
 
 struct grub_menu_entry_class
-- 
2.44.0


++++++ 0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch ++++++
>From 855b3e5cd4d672e961a366ff0f53e3a09a1ad0cc Mon Sep 17 00:00:00 2001
From: Michael Chang <mch...@suse.com>
Date: Fri, 30 Jun 2023 14:37:41 +0800
Subject: [PATCH 7/9] grub-switch-to-blscfg: adapt to openSUSE

A few tweaks to make it 'just works' for openSUSE:

- remove RHEL specific $grub_get_kernel_settings and all reference to it.
- make $grubdir and $startlink to the path in openSUSE
- change the bls template to openSUSE
- make $cmdline account for btrfs subvolumes, among others
- remove RHEL specific $GRUB_LINUX_MAKE_DEBUG and all related code
- remove ostree specific hack
- ignore increment.mod

Signed-off-by: Michael Chang <mch...@suse.com>
---
 util/grub-switch-to-blscfg.in | 144 ++++++++++++++++++++--------------
 1 file changed, 87 insertions(+), 57 deletions(-)

diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in
index a851424be..66ecc0cae 100644
--- a/util/grub-switch-to-blscfg.in
+++ b/util/grub-switch-to-blscfg.in
@@ -34,21 +34,18 @@ fi
 
 self=`basename $0`
 
-grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@"
 grub_editenv=${bindir}/@grub_editenv@
-etcdefaultgrub=/etc/default/grub
+grub_probe="${sbindir}/@grub_probe@"
+etcdefaultgrub=${sysconfdir}/default/grub
 
-eval "$("${grub_get_kernel_settings}")" || true
-
-EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 
's/\"//g')
-if [ -d /sys/firmware/efi/efivars/ ]; then
-    startlink=/etc/grub2-efi.cfg
-    grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'`
-else
-    startlink=/etc/grub2.cfg
-    grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
+if test -f "$etcdefaultgrub" ; then
+    # shellcheck source=/etc/default/grub
+    . "$etcdefaultgrub"
 fi
 
+grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
+startlink="${grubdir}/grub.cfg"
+
 blsdir=`echo "/@bootdirname@/loader/entries" | sed 's,//*,/,g'`
 
 backupsuffix=.bak
@@ -58,19 +55,80 @@ arch="$(uname -m)"
 export TEXTDOMAIN=@PACKAGE@
 export TEXTDOMAINDIR="@localedir@"
 
+# shellcheck source=/usr/share/grub2/grub-mkconfig_lib
 . "${pkgdatadir}/grub-mkconfig_lib"
 
+# FIXME: Abort if grub_probe fails
+
+GRUB_DEVICE="`${grub_probe} --target=device /`"
+GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> 
/dev/null`" || true
+GRUB_DEVICE_PARTUUID="`${grub_probe} --device ${GRUB_DEVICE} --target=partuuid 
2> /dev/null`" || true
+GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || 
echo unknown`"
+
+# 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
+
+if [ "x$GRUB_CONMODE" != "x" ]; then
+  GRUB_CMDLINE_LINUX="conmode=${GRUB_CONMODE} ${GRUB_CMDLINE_LINUX}"
+fi
+
+case x"$GRUB_FS" in
+    xbtrfs)
+       if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" != "xtrue" ]; then
+           rootsubvol="`make_system_path_relative_to_its_root /`"
+           rootsubvol="${rootsubvol#/}"
+           if [ "x${rootsubvol}" != x ] && [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" 
!= "xtrue" ]; 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
+
+if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then
+  LINUX_ROOT_DEVICE=""
+fi
+
 # Usage: usage
 # Print the usage.
 usage () {
     gettext_printf "Usage: %s\n" "$self"
-    gettext "Switch to BLS config files.\n"; echo
+    gettext "Switch to BLS config files. Only for testing purpose !!!\n"; echo
     echo
     print_option_help "-h, --help" "$(gettext "print this message and exit")"
     print_option_help "-V, --version" "$(gettext "print the version 
information and exit")"
     echo
     print_option_help "--backup-suffix=$(gettext "SUFFIX")" "$backupsuffix"
-    print_option_help "--bls-directory=$(gettext "DIR")" "$blsdir"
+    print_option_help "--bls-directory=$(gettext "DIR")" "Noop, always $blsdir"
     print_option_help "--config-file=$(gettext "FILE")" "$startlink"
     print_option_help "--grub-defaults=$(gettext "FILE")" "$etcdefaultgrub"
     print_option_help "--grub-directory=$(gettext "DIR")" "$grubdir"
@@ -112,11 +170,15 @@ do
         ;;
 
     --bls-directory)
-        blsdir=`argument $option "$@"`
+        # blsdir=`argument $option "$@"`
+        gettext_printf "WARN: --bls-directory is currently disabled, it's 
always $blsdir !!!\n"
+        gettext_printf "WARN: use kernel-install instead if you want to test 
bls directory on ESP !!!\n"
         shift
         ;;
     --bls-directory=*)
-        blsdir=`echo "$option" | sed 's/--bls-directory=//'`
+        # blsdir=`echo "$option" | sed 's/--bls-directory=//'`
+        gettext_printf "WARN: --bls-directory is currently disabled, it's 
always $blsdir !!!\n"
+        gettext_printf "WARN: use kernel-install instead if you want to test 
bls directory on ESP !!!\n"
         ;;
 
     --config-file)
@@ -172,7 +234,7 @@ find_grub_cfg() {
     return 1
 }
 
-if ! find_grub_cfg ${startlink} ${grubdir}/grub.cfg ; then
+if ! find_grub_cfg "${startlink}" ; then
   gettext_printf "Couldn't find config file\n" 1>&2
   exit 1
 fi
@@ -190,27 +252,22 @@ fi
 mkbls() {
     local kernelver=$1 && shift
     local datetime=$1 && shift
+    local prefix=$1 && shift
     local kernelopts=$1 && shift
 
-    local debugname=""
-    local debugid=""
     local flavor=""
 
     if [ "$kernelver" == *\+* ] ; then
         local flavor=-"${kernelver##*+}"
-        if [ "${flavor}" == "-debug" ]; then
-            local debugname=" with debugging"
-            local debugid="-debug"
-        fi
     fi
     (
         source /etc/os-release
 
         cat <<EOF
-title ${NAME} (${kernelver}) ${VERSION}${debugname}
-version ${kernelver}${debugid}
-linux /vmlinuz-${kernelver}
-initrd /initramfs-${kernelver}.img
+title ${NAME} (${kernelver}) ${VERSION}
+version ${kernelver}$
+linux ${prefix}/vmlinuz-${kernelver}
+initrd ${prefix}/initrd-${kernelver}
 options ${kernelopts}
 grub_users \$grub_users
 grub_arg --unrestricted
@@ -233,42 +290,15 @@ copy_bls() {
             continue
        fi
 
-       linux_relpath="$("${grub_mkrelpath}" "${linux_path}")"
-       bootprefix="${linux_relpath%%"${linux}"}"
+       bootprefix="$(make_system_path_relative_to_its_root /boot)"
        cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} 
${GRUB_CMDLINE_LINUX_DEFAULT}"
 
        mkbls "${kernelver}" \
              "$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${kernel_dir}")")" \
              "${bootprefix}" "${cmdline}" >"${bls_target}"
-
-       if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
-            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]*//')"
-            options="$(echo "${cmdline} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 
's/\//\\\//g')"
-            sed -i -e "s/^title.*/title 
${title}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${bls_debug}"
-            sed -i -e "s/^options.*/options ${options}/" "${bls_debug}"
-       fi
     done
-
-    if [ -f "/boot/vmlinuz-0-rescue-${MACHINE_ID}" ]; then
-       mkbls "0-rescue-${MACHINE_ID}" "0" "${bootprefix}" 
>"${blsdir}/${MACHINE_ID}-0-rescue.conf"
-    fi
 }
 
-# The grub2 EFI binary is not copied to the ESP as a part of an ostree
-# transaction. Make sure a grub2 version with BLS support is installed
-# but only do this if the blsdir is not set, to make sure that the BLS
-# parsing module will search for the BLS snippets in the default path.
-if test -f /run/ostree-booted && test -d /sys/firmware/efi/efivars && \
-   ! ${grub_editenv} - list | grep -q blsdir && \
-   mountpoint -q /boot; then
-    grub_binary="$(find /usr/lib/ostree-boot/efi/EFI/${EFIDIR}/ -name 
grub*.efi)"
-    install -m 700 ${grub_binary} ${grubdir} || exit 1
-    # Create a hidden file to indicate that grub2 now has BLS support.
-    touch /boot/grub2/.grub2-blscfg-supported
-fi
-
 GENERATE=0
 if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \
         | grep -vq '^GRUB_ENABLE_BLSCFG="*true"*\s*$' ; then
@@ -297,9 +327,7 @@ if [ "${GENERATE}" -eq 1 ] ; then
     fi
 
     if [ -n "${mod_dir}" ]; then
-       for mod in blscfg increment; do
-           install -m 700 ${prefix}/lib/grub/${mod_dir}/${mod}.mod 
${grubdir}/$mod_dir/ || exit 1
-       done
+       install -m 700 "${pkgdatadir}/${mod_dir}/blscfg.mod" 
"${grubdir}/$mod_dir/" || exit 1
     fi
 
     cp -af "${GRUB_CONFIG_FILE}" "${GRUB_CONFIG_FILE}${backupsuffix}"
@@ -311,6 +339,8 @@ if [ "${GENERATE}" -eq 1 ] ; then
         gettext_printf "Updating %s failed\n" "${GRUB_CONFIG_FILE}"
         exit 1
     fi
+else
+    gettext_printf "Do nothing because \$GRUB_ENABLE_BLSCFG is already true in 
%s\n" "${GRUB_CONFIG_FILE}"
 fi
 
 # Bye.
-- 
2.44.0


++++++ 0008-blscfg-reading-bls-fragments-if-boot-present.patch ++++++
>From 2b0e6effc31ec166bbbe35a3cd2b4c73051f38bb Mon Sep 17 00:00:00 2001
From: Michael Chang <mch...@suse.com>
Date: Fri, 16 Jun 2023 15:54:50 +0800
Subject: [PATCH 8/9] blscfg: reading bls fragments if boot present

The Boot Loader Specification (BLS) designates the EFI System Partition
(ESP) as a primary location for $BOOT, where boot menu entries can be
stored. The specification encourages boot loaders to retrieve menu
entries from the ESP, even when XBOOTLDR is present.

This commit aligns with the BLS specification by introducing the
capability to search for the ESP in addition to the default root
partition or any specified location via blscfg's command line. The $boot
environment variable is utilized as a reference to the ESP device for
the blscfg command. Initialization of $boot in grub.cfg is demonstrated
as follows:

  insmod part_gpt
  insmod fat
  search --no-floppy --fs-uuid --set=boot F414-5A9F

If $boot is unset, no additional search for the BLS location will be
performed.

Signed-off-by: Michael Chang <mch...@suse.com>
---
 grub-core/commands/blscfg.c | 10 ++++++++++
 util/grub.d/10_linux.in     |  3 ++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
index c872bcef0..cbe2a289e 100644
--- a/grub-core/commands/blscfg.c
+++ b/grub-core/commands/blscfg.c
@@ -1186,6 +1186,7 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
   char *entry_id = NULL;
   bool show_default = true;
   bool show_non_default = true;
+  const char *boot = NULL;
 
   if (argc == 1) {
     if (grub_strcmp (args[0], "default") == 0) {
@@ -1205,6 +1206,15 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
   if (r)
     return r;
 
+  boot = grub_env_get("boot");
+  path = (boot) ? grub_xasprintf("(%s)" GRUB_BLS_CONFIG_PATH, boot) : NULL;
+  if (path)
+    {
+      bls_load_entries(path);
+      grub_print_error();
+    }
+  grub_free(path);
+
   return bls_create_entries(show_default, show_non_default, entry_id);
 }
 
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
index 45eefb332..edf0fca55 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
@@ -201,7 +201,8 @@ populate_menu()
 }
 
 # Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not 
installed.
-if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null; 
then
+# FIXME: The test should be aligned to openSUSE, grubby is not our default 
tool  
+if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null && 
false; then
          GRUB_ENABLE_BLSCFG="true"
 fi
 
-- 
2.44.0


++++++ 0009-10_linux-Some-refinement-for-BLS.patch ++++++
>From 72a72facc6cbaf58fda136286af78bbbd48bd88c Mon Sep 17 00:00:00 2001
From: Michael Chang <mch...@suse.com>
Date: Wed, 13 Mar 2024 15:26:42 +0800
Subject: [PATCH 9/9] 10_linux: Some refinement for BLS

Remove BLS_POPULATE_MENU as it is not being used currently and removing
kernelopts assignment in the grub boot config itself to fully delegate
the responsibility of generating kernel options to a functioning BLS
generator.

Signed-off-by: Michael Chang <mch...@suse.com>
---
 util/grub.d/10_linux.in | 29 -----------------------------
 1 file changed, 29 deletions(-)

diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
index edf0fca55..7cbff7466 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
@@ -93,11 +93,7 @@ fi
 
 populate_header_warn()
 {
-if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then
-  bls_parser="10_linux script"
-else
   bls_parser="blscfg command"
-fi
 cat <<EOF
 
 # This section was generated by a script. Do not modify the generated file - 
all changes
@@ -200,11 +196,6 @@ populate_menu()
     printf "$menu"
 }
 
-# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not 
installed.
-# FIXME: The test should be aligned to openSUSE, grubby is not our default 
tool  
-if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null && 
false; then
-         GRUB_ENABLE_BLSCFG="true"
-fi
 
 if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then
   if [ x$dirname = x/ ]; then
@@ -252,31 +243,11 @@ if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then
 
   populate_header_warn
 
-  cat << EOF
-# The kernelopts variable should be defined in the grubenv file. But to ensure 
that menu
-# entries populated from BootLoaderSpec files that use this variable work 
correctly even
-# without a grubenv file, define a fallback kernelopts variable if this has 
not been set.
-#
-# The kernelopts variable in the grubenv file can be modified using the grubby 
tool or by
-# executing the grub2-mkconfig tool. For the latter, the values of the 
GRUB_CMDLINE_LINUX
-# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used 
to set both
-# the kernelopts variable in the grubenv file and the fallback kernelopts 
variable.
-if [ -z "\${kernelopts}" ]; then
-  set kernelopts="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} 
${GRUB_CMDLINE_LINUX_DEFAULT}"
-fi
-EOF
-
-  update_bls_cmdline
-
-  if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then
-      populate_menu
-  else
       cat << EOF
 
 insmod blscfg
 blscfg
 EOF
-  fi
 
   if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then
       blsdir="/boot/loader/entries"
-- 
2.44.0

Reply via email to