Blame SOURCES/rear-bz1737042.patch

129f2e
diff --git a/usr/share/rear/lib/uefi-functions.sh b/usr/share/rear/lib/uefi-functions.sh
129f2e
index 95e6292d..c583e044 100644
129f2e
--- a/usr/share/rear/lib/uefi-functions.sh
129f2e
+++ b/usr/share/rear/lib/uefi-functions.sh
129f2e
@@ -37,20 +37,76 @@ function trim {
129f2e
 }
129f2e
 
129f2e
 function build_bootx86_efi {
129f2e
-    local gmkimage
129f2e
-    if has_binary grub-mkimage; then
129f2e
-        gmkimage=grub-mkimage
129f2e
-    elif has_binary grub2-mkimage; then
129f2e
-        gmkimage=grub2-mkimage
129f2e
+    local outfile="$1"
129f2e
+    local embedded_config=""
129f2e
+    local gmkstandalone=""
129f2e
+    local gprobe=""
129f2e
+    local dirs=()
129f2e
+    # modules is the list of modules to load
129f2e
+    local modules=()
129f2e
+
129f2e
+    # Configuration file is optional for image creation.
129f2e
+    shift
129f2e
+    if [[ -n "$1" ]] ; then
129f2e
+        # graft point syntax. $1 will appear as /boot/grub/grub.cfg in the image
129f2e
+        embedded_config="/boot/grub/grub.cfg=$1"
129f2e
+        shift
129f2e
+        # directories that should be accessible by GRUB2 (e.g. because they contain the kernel)
129f2e
+        dirs=( ${@:+"$@"} )
129f2e
+    fi
129f2e
+
129f2e
+    if has_binary grub-mkstandalone ; then
129f2e
+        gmkstandalone=grub-mkstandalone
129f2e
+    elif has_binary grub2-mkstandalone ; then
129f2e
+        # At least SUSE systems use 'grub2' prefixed names for GRUB2 programs:
129f2e
+        gmkstandalone=grub2-mkstandalone
129f2e
     else
129f2e
-        Log "Did not find grub-mkimage (cannot build bootx86.efi)"
129f2e
-        return
129f2e
+        # This build_bootx86_efi function is only called in output/ISO/Linux-i386/250_populate_efibootimg.sh
129f2e
+        # which runs only if UEFI is used so that we simply error out here if we cannot make a bootable EFI image of GRUB2
129f2e
+        # (normally a function should not exit out but return to its caller with a non-zero return code):
129f2e
+        Error "Cannot make bootable EFI image of GRUB2 (neither grub-mkstandalone nor grub2-mkstandalone found)"
129f2e
+    fi
129f2e
+
129f2e
+    # Determine what modules need to be loaded in order to access given directories
129f2e
+    # (if the list of modules is not overriden by GRUB2_MODULES_LOAD)
129f2e
+    if (( ${#dirs[@]} )) && ! (( ${#modules[@]} )) ; then
129f2e
+        if has_binary grub-probe ; then
129f2e
+            gprobe=grub-probe
129f2e
+        elif has_binary grub2-probe ; then
129f2e
+            # At least SUSE systems use 'grub2' prefixed names for GRUB2 programs:
129f2e
+            gprobe=grub2-probe
129f2e
+        else
129f2e
+            LogWarn "Neither grub-probe nor grub2-probe found"
129f2e
+            if test /usr/lib/grub*/x86_64-efi/partmap.lst ; then
129f2e
+                LogWarn "including all partition modules"
129f2e
+                modules=( $(cat /usr/lib/grub*/x86_64-efi/partmap.lst) )
129f2e
+            else
129f2e
+                Error "Can not determine partition modules, ${dirs[*]} would be likely inaccessible in GRUB2"
129f2e
+            fi
129f2e
+        fi
129f2e
+
129f2e
+        if [ -n "$gprobe" ]; then
129f2e
+            # this is unfortunately only a crude approximation of the Grub internal probe_mods() function
129f2e
+            modules=( $( for p in "${dirs[@]}" ; do
129f2e
+                             $gprobe --target=fs "$p"
129f2e
+                             $gprobe --target=partmap "$p" | sed -e 's/^/part_/'
129f2e
+                             $gprobe --target=abstraction "$p"
129f2e
+                         done | sort -u ) )
129f2e
+        fi
129f2e
+    fi
129f2e
+
129f2e
+    # grub-mkimage needs /usr/lib/grub/x86_64-efi/moddep.lst (cf. https://github.com/rear/rear/issues/1193)
129f2e
+    # and at least on SUSE systems grub2-mkimage needs /usr/lib/grub2/x86_64-efi/moddep.lst (in 'grub2' directory)
129f2e
+    # so that we error out if grub-mkimage or grub2-mkimage would fail when its moddep.lst is missing.
129f2e
+    # Careful: usr/sbin/rear sets nullglob so that /usr/lib/grub*/x86_64-efi/moddep.lst gets empty if nothing matches
129f2e
+    # and 'test -f' succeeds with empty argument so that we cannot use 'test -f /usr/lib/grub*/x86_64-efi/moddep.lst'
129f2e
+    # also 'test -n' succeeds with empty argument but (fortunately/intentionally?) plain 'test' fails with empty argument:
129f2e
+    test /usr/lib/grub*/x86_64-efi/moddep.lst || Error "$gmkstandalone would not make bootable EFI image of GRUB2 (no /usr/lib/grub*/x86_64-efi/moddep.lst file)"
129f2e
+
129f2e
+    (( ${#modules[@]} )) && LogPrint "GRUB2 modules to load: ${modules[*]}"
129f2e
+
129f2e
+    if ! $gmkstandalone $v ${modules:+"--modules=${modules[*]}"} -O x86_64-efi -o $outfile $embedded_config ; then
129f2e
+        Error "Failed to make bootable EFI image of GRUB2 (error during $gmkstandalone of $outfile)"
129f2e
     fi
129f2e
-    # as not all Linux distro's have the same grub modules present we verify what we have (see also https://github.com/rear/rear/pull/2001)
129f2e
-    grub_modules=""
129f2e
-    for grub_module in part_gpt part_msdos fat ext2 normal chain boot configfile linux linuxefi multiboot jfs iso9660 usb usbms usb_keyboard video udf ntfs all_video gzio efi_gop reboot search test echo btrfs ; do
129f2e
-        test "$( find /boot -type f -name "$grub_module.mod" 2>/dev/null )" && grub_modules="$grub_modules $grub_module"
129f2e
-    done
129f2e
-    $gmkimage $v -O x86_64-efi -c $TMP_DIR/mnt/EFI/BOOT/embedded_grub.cfg -o $TMP_DIR/mnt/EFI/BOOT/BOOTX64.efi -p "/EFI/BOOT" $grub_modules
129f2e
-    StopIfError "Error occurred during $gmkimage of BOOTX64.efi"
129f2e
 }
129f2e
+
129f2e
diff --git a/usr/share/rear/output/ISO/Linux-i386/250_populate_efibootimg.sh b/usr/share/rear/output/ISO/Linux-i386/250_populate_efibootimg.sh
129f2e
index fdf66039..e9325012 100644
129f2e
--- a/usr/share/rear/output/ISO/Linux-i386/250_populate_efibootimg.sh
129f2e
+++ b/usr/share/rear/output/ISO/Linux-i386/250_populate_efibootimg.sh
129f2e
@@ -2,6 +2,9 @@
129f2e
 
129f2e
 is_true $USING_UEFI_BOOTLOADER || return 0 # empty or 0 means NO UEFI
129f2e
 
129f2e
+local boot_dir="/boot"
129f2e
+local efi_boot_tmp_dir="$TMP_DIR/mnt/EFI/BOOT"
129f2e
+
129f2e
 mkdir $v -p $TMP_DIR/mnt/EFI/BOOT >&2
129f2e
 StopIfError "Could not create $TMP_DIR/mnt/EFI/BOOT"
129f2e
 
129f2e
@@ -56,14 +59,8 @@ title Relax-and-Recover (no Secure Boot)
129f2e
 
129f2e
 EOF
129f2e
 else
129f2e
-# create small embedded grub.cfg file for grub-mkimage
129f2e
-cat > $TMP_DIR/mnt/EFI/BOOT/embedded_grub.cfg <
129f2e
-set prefix=(cd0)/EFI/BOOT
129f2e
-configfile /EFI/BOOT/grub.cfg
129f2e
-EOF
129f2e
-
129f2e
-# create a grub.cfg
129f2e
-    create_grub2_cfg > $TMP_DIR/mnt/EFI/BOOT/grub.cfg
129f2e
+    # create a grub.cfg
129f2e
+    create_grub2_cfg > $efi_boot_tmp_dir/grub.cfg
129f2e
 fi
129f2e
 
129f2e
 # Create BOOTX86.efi but only if we are NOT secure booting.
129f2e
@@ -72,15 +69,15 @@ fi
129f2e
 # See issue #1374
129f2e
 # build_bootx86_efi () can be safely used for other scenarios.
129f2e
 if ! test -f "$SECURE_BOOT_BOOTLOADER" ; then
129f2e
-    build_bootx86_efi
129f2e
+    build_bootx86_efi $TMP_DIR/mnt/EFI/BOOT/BOOTX64.efi $efi_boot_tmp_dir/grub.cfg "$boot_dir" "$UEFI_BOOTLOADER"
129f2e
 fi
129f2e
 
129f2e
 # We will be using grub-efi or grub2 (with efi capabilities) to boot from ISO.
129f2e
 # Because usr/sbin/rear sets 'shopt -s nullglob' the 'echo -n' command
129f2e
 # outputs nothing if nothing matches the bash globbing pattern '/boot/grub*'
129f2e
-local grubdir="$( echo -n /boot/grub* )"
129f2e
+local grubdir="$( echo -n ${boot_dir}/grub* )"
129f2e
 # Use '/boot/grub' as fallback if nothing matches '/boot/grub*'
129f2e
-test -d "$grubdir" || grubdir='/boot/grub'
129f2e
+test -d "$grubdir" || grubdir="${boot_dir}/grub"
129f2e
 
129f2e
 if [ -d $(dirname ${UEFI_BOOTLOADER})/fonts ]; then
129f2e
     cp $v $(dirname ${UEFI_BOOTLOADER})/fonts/* $TMP_DIR/mnt/EFI/BOOT/fonts/ >&2
129f2e
diff --git a/usr/share/rear/output/default/940_grub2_rescue.sh b/usr/share/rear/output/default/940_grub2_rescue.sh
129f2e
index a94957de..fbbd7074 100644
129f2e
--- a/usr/share/rear/output/default/940_grub2_rescue.sh
129f2e
+++ b/usr/share/rear/output/default/940_grub2_rescue.sh
129f2e
@@ -144,13 +144,18 @@ if is_true $USING_UEFI_BOOTLOADER ; then
129f2e
     # probably a bug, as I was able to boot with value set to root=anything
129f2e
     root_uuid=$(mount | grep -w 'on /' | awk '{print $1}' | xargs blkid -s UUID -o value)
129f2e
 
129f2e
-    # Grub2 modules that will be used for booting "Relax-and-Recover"
129f2e
-    # It might be useful to make this variable global in the future
129f2e
-    grub2_modules="linux echo all_video part_gpt ext2 btrfs search configfile"
129f2e
-
129f2e
     # Create configuration file for "Relax-and-Recover" UEFI boot entry.
129f2e
     # This file will not interact with existing Grub2 configuration in any way.
129f2e
-    (   echo "menuentry '$grub_rear_menu_entry_name' --class os {"
129f2e
+    (   echo "set btrfs_relative_path=y"
129f2e
+        echo "insmod efi_gop"
129f2e
+        echo "insmod efi_uga"
129f2e
+        echo "insmod video_bochs"
129f2e
+        echo "insmod video_cirrus"
129f2e
+        echo "insmod all_video"
129f2e
+        echo ""
129f2e
+        echo "set gfxpayload=keep"
129f2e
+        echo ""
129f2e
+        echo "menuentry '$grub_rear_menu_entry_name' --class os {"
129f2e
         echo "          search --no-floppy --fs-uuid --set=root $grub_boot_uuid"
129f2e
         echo "          echo 'Loading kernel $boot_kernel_file ...'"
129f2e
         echo "          linux $grub_boot_dir/$boot_kernel_name root=UUID=$root_uuid $KERNEL_CMDLINE"
129f2e
@@ -159,19 +164,8 @@ if is_true $USING_UEFI_BOOTLOADER ; then
129f2e
         echo "}"
129f2e
     ) > $grub_config_dir/rear.cfg
129f2e
 
129f2e
-    # Tell rear.efi which configuration file to load
129f2e
-    (   echo "search --no-floppy --fs-uuid --set=root $grub_boot_uuid"
129f2e
-        echo ""
129f2e
-        echo "set btrfs_relative_path=y"
129f2e
-        echo "set prefix=(\$root)${grub_boot_dir}/grub${grub_num}"
129f2e
-        echo ""
129f2e
-        echo "configfile (\$root)${grub_boot_dir}/grub${grub_num}/rear.cfg"
129f2e
-    ) > $grub_config_dir/rear_embed.cfg
129f2e
-
129f2e
     # Create rear.efi at UEFI default boot directory location.
129f2e
-    if ! grub${grub_num}-mkimage -o $boot_dir/efi/EFI/BOOT/rear.efi -O x86_64-efi -c $grub_config_dir/rear_embed.cfg -p /EFI/BOOT $grub2_modules ; then
129f2e
-        Error "Could not create UEFI boot image"
129f2e
-    fi
129f2e
+    build_bootx86_efi $boot_dir/efi/EFI/BOOT/rear.efi $grub_config_dir/rear.cfg "$boot_dir" "$UEFI_BOOTLOADER"
129f2e
 
129f2e
     # If UEFI boot entry for "Relax-and-Recover" does not exist, create it.
129f2e
     # This will also add "Relax-and-Recover" to boot order because if UEFI entry is not listed in BootOrder,