Accepting request 1179114 from home:michael-chang:branches:Base:System

- 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

OBS-URL: https://build.opensuse.org/request/show/1179114
OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=506
This commit is contained in:
Michael Chang 2024-06-07 05:34:08 +00:00 committed by Git OBS Bridge
parent e3bfb46960
commit f6435d4e6e
11 changed files with 3171 additions and 1 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,411 @@
From 439de947262b0d8d4a02ca5afb1ef4f15853962c Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@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 <pjones@redhat.com>
[javierm: remove outdated URL for BLS document]
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
[iwienand@redhat.com: skip machine ID check when updating entries]
Signed-off-by: Ian Wienand <iwienand@redhat.com>
[rharwood: commit message composits, drop man pages]
Signed-off-by: Robbie Harwood <rharwood@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

View File

@ -0,0 +1,385 @@
From 90153f1c9631498723450d84e014e25865fecc1b Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@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 <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
[jhlavac: Use ${etcdefaultgrub} instead of /etc/default/grub]
Signed-off-by: Jan Hlavac <jhlavac@redhat.com>
[rharwood: skip on ostree installations, migrate man to h2m]
Signed-off-by: Robbie Harwood <rharwood@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-grub@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

View File

@ -0,0 +1,30 @@
From 2fccb958910afaaf03cbec1a6b98ad197d088ad4 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@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 <rharwood@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

View File

@ -0,0 +1,121 @@
From 6d33393fd3c538aaead2698777c02d6d6d0221c9 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@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 <rharwood@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

View File

@ -0,0 +1,168 @@
From 6523d493b0772316a3fbb249eb070ada5d266a98 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@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 <mchang@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

View File

@ -0,0 +1,264 @@
From 855b3e5cd4d672e961a366ff0f53e3a09a1ad0cc Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@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 <mchang@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

View File

@ -0,0 +1,75 @@
From 2b0e6effc31ec166bbbe35a3cd2b4c73051f38bb Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@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 <mchang@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

View File

@ -0,0 +1,78 @@
From 72a72facc6cbaf58fda136286af78bbbd48bd88c Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@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 <mchang@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

View File

@ -1,3 +1,17 @@
-------------------------------------------------------------------
Fri Jun 7 02:13:08 UTC 2024 - Michael Chang <mchang@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
-------------------------------------------------------------------
Mon May 20 07:22:09 UTC 2024 - Gary Ching-Pang Lin <glin@suse.com>

View File

@ -395,6 +395,15 @@ Patch204: 0001-ofdisk-Enhance-canonical-path-handling-for-bootpath.patch
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 @@ CD_MODULES="all_video boot cat configfile echo true \
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 @@ grep -E ${EXTRA_PATTERN} %{grubarch}-mod-all.lst > %{grubarch}-mod-extras.lst
%{_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 @@ grep -E ${EXTRA_PATTERN} %{grubarch}-mod-all.lst > %{grubarch}-mod-extras.lst
%{_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.*