Current File : //proc/self/root/usr/local/jetapps/usr/share/rear/layout/save/default/445_guess_bootloader.sh |
# Determine or guess the used bootloader if not specified by the user
# and save this information into /var/lib/rear/recovery/bootloader
local bootloader_file="$VAR_DIR/recovery/bootloader"
local sysconfig_bootloader
local block_device
local blockd
local disk_device
local bootloader_area_strings_file
local block_size
local known_bootloader
# When BOOTLOADER is specified use that:
if test "$BOOTLOADER" ; then
# case-insensitive match, as later we convert all to uppercase
if [[ "$BOOTLOADER" == [Gg][Rr][Uu][Bb] ]] ; then
if is_grub2_installed ; then
LogPrintError "BOOTLOADER=GRUB used to mean GRUB 2 if GRUB 2 is installed and GRUB Legacy if not"
Error "BOOTLOADER set to '$BOOTLOADER', set it to 'GRUB2' explicitly to avoid the ambiguity"
fi
# we should add an ErrorIfDeprecated call here or later for GRUB Legacy deprecation
fi
LogPrint "Using specified bootloader '$BOOTLOADER' for 'rear recover'"
echo "$BOOTLOADER" | tr '[a-z]' '[A-Z]' >$bootloader_file
return
fi
# When a bootloader is specified in /etc/sysconfig/bootloader use that:
if test -f /etc/sysconfig/bootloader ; then
# SUSE uses LOADER_TYPE, and others?
# Getting values from sysconfig files is like sourcing shell scripts so that the last setting wins:
sysconfig_bootloader=$( grep ^LOADER_TYPE /etc/sysconfig/bootloader | cut -d= -f2 | tail -n1 | sed -e 's/"//g' )
if test "$sysconfig_bootloader" ; then
LogPrint "Using sysconfig bootloader '$sysconfig_bootloader' for 'rear recover'"
echo "$sysconfig_bootloader" | tr '[a-z]' '[A-Z]' >$bootloader_file
return
fi
fi
# On ARM, guess the dummy bootloader:
if [ "$ARCH" = "Linux-arm" ] ; then
BOOTLOADER=ARM
# Inform the user that we do nothing:
LogPrint "Using guessed bootloader 'ARM'. Skipping bootloader backup, see default.conf about 'BOOTLOADER'"
echo "$BOOTLOADER" >$bootloader_file
return
fi
# Finally guess the used bootloader by inspecting the first bytes on all disks
# and use the first one that matches a known bootloader string:
for block_device in /sys/block/* ; do
blockd=${block_device#/sys/block/}
# Continue with the next block device when the current block device is not a disk that can be used for booting:
[[ $blockd = hd* || $blockd = sd* || $blockd = cciss* || $blockd = vd* || $blockd = xvd* || $blockd = nvme* || $blockd = mmcblk* || $blockd = dasd* ]] || continue
disk_device=$( get_device_name $block_device )
# Check if the disk contains a PPC PreP boot partition (ID=0x41):
if file -s $disk_device | grep -q "ID=0x41" ; then
LogPrint "Using guessed bootloader 'PPC' for 'rear recover' (found PPC PreP boot partition 'ID=0x41' on $disk_device)"
echo "PPC" >$bootloader_file
return
fi
# Get all strings in the first 512*4=2048 bytes on the disk:
bootloader_area_strings_file="$TMP_DIR/bootloader_area_strings"
block_size=$( get_block_size ${disk_device##*/} )
dd if=$disk_device bs=$block_size count=4 | strings >$bootloader_area_strings_file
# Examine the strings in the first bytes on the disk to guess the used bootloader,
# see layout/save/default/450_check_bootloader_files.sh for the known bootloaders.
# Test the more specific strings first because the first match wins.
# Skip LUKS encrypted disks when guessing bootloader:
if grep -q "LUKS" $bootloader_area_strings_file ; then
LogPrint "Cannot autodetect bootloader on LUKS encrypted disk (found 'LUKS' in first bytes on $disk_device)"
# Continue guessing the used bootloader by inspecting the first bytes on the next disk:
continue
fi
# Check the default cases of known bootloaders.
# IBM Z (s390) uses zipl boot loader for RHEL and Ubuntu
# cf. https://github.com/rear/rear/issues/2137
for known_bootloader in GRUB2 GRUB LILO ZIPL ; do
if grep -q -i "$known_bootloader" $bootloader_area_strings_file ; then
# If we find "GRUB" (which means GRUB Legacy)
# do not unconditionally trust that because https://github.com/rear/rear/pull/589
# reads (excerpt):
# Problems found:
# The ..._install_grub.sh checked for GRUB2 which is not part
# of the first 2048 bytes of a disk - only GRUB was present -
# thus the check for grub-probe/grub2-probe
# and https://github.com/rear/rear/commit/079de45b3ad8edcf0e3df54ded53fe955abded3b
# reads (excerpt):
# replace grub-install by grub-probe
# as grub-install also exist in legacy grub
# so that if actually GRUB 2 is used, the string in the bootloader area
# is "GRUB" so that another test is needed to detect if actually GRUB 2 is used.
# When GRUB 2 is installed we assume GRUB 2 is used as boot loader.
if [ "$known_bootloader" = "GRUB" ] && is_grub2_installed ; then
known_bootloader=GRUB2
LogPrint "GRUB found in first bytes on $disk_device and GRUB 2 is installed, using GRUB2 as a guessed bootloader for 'rear recover'"
else
LogPrint "Using guessed bootloader '$known_bootloader' for 'rear recover' (found in first bytes on $disk_device)"
fi
echo "$known_bootloader" >$bootloader_file
return
fi
done
# When no known bootloader matches the first bytes on the current disk
# log all strings in the first bytes on the current disk
# so that the user can see the results in the log file:
Log "No known bootloader matches the first bytes on $disk_device"
Log "Begin of strings in the first bytes on $disk_device"
cat $bootloader_area_strings_file >&2
Log "End of strings in the first bytes on $disk_device"
done
# No bootloader detected, but we are using UEFI - there is probably an EFI bootloader
if is_true $USING_UEFI_BOOTLOADER ; then
if is_grub2_installed ; then
echo "GRUB2-EFI" >$bootloader_file
elif test -f /sbin/elilo ; then
echo "ELILO" >$bootloader_file
else
# There is an EFI bootloader, we don't know which one exactly.
# The value "EFI" is a bit redundant with USING_UEFI_BOOTLOADER=1,
# which already indicates that there is an EFI bootloader. We use it as a placeholder
# to not leave $bootloader_file empty.
# Note that it is legal to have USING_UEFI_BOOTLOADER=1 and e.g. known_bootloader=GRUB2
# (i.e. a non-EFI bootloader). This will happen in BIOS/UEFI hybrid boot scenarios.
# known_bootloader=GRUB2 indicates that there is a BIOS bootloader and USING_UEFI_BOOTLOADER=1
# indicates that there is also an EFI bootloader. Only the EFI one is being used at this
# time, but both will need to be restored.
echo "EFI" >$bootloader_file
fi
return 0
fi
# Error out when no bootloader was specified or could be autodetected:
Error "Cannot autodetect what is used as bootloader, see default.conf about 'BOOTLOADER'"