![](https://seccdn.libravatar.org/avatar/128a7b98d536a9cf9b4d4d5a90d63475.jpg?s=120&d=mm&r=g)
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 <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 + +------------------------------------------------------------------- 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 <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 ++++++ 0003-Add-grub2-switch-to-blscfg.patch ++++++ 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 ++++++ 0004-blscfg-Don-t-root-device-in-emu-builds.patch ++++++ 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 ++++++ 0005-blscfg-check-for-mounted-boot-in-emu.patch ++++++ 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 ++++++ 0006-Follow-the-device-where-blscfg-is-discovered.patch ++++++ 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 ++++++ 0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch ++++++ 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 ++++++ 0008-blscfg-reading-bls-fragments-if-boot-present.patch ++++++ 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 ++++++ 0009-10_linux-Some-refinement-for-BLS.patch ++++++ 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