#!/bin/bash ############################################################################ # # # This file is part of the IPFire Firewall. # # # # IPFire 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 2 of the License, or # # (at your option) any later version. # # # # IPFire 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 IPFire; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # # Copyright (C) 2014 IPFire Team . # # # ############################################################################ GRUB_INSTALL_ARGS="--no-floppy --recheck --force" function find_bootloader_device() { local mp for mp in /boot /; do if find_device "${mp}"; then return 0 fi done return 1 } function find_device() { local mountpoint="${1}" local root local dev mp fs flags rest while read -r dev mp fs flags rest; do # Skip unwanted entries [ "${dev}" = "rootfs" ] && continue if [ "${mp}" = "${mountpoint}" ] && [ -b "${dev}" ]; then root="$(basename "${dev}")" break fi done < /proc/mounts # Get the actual device from the partition that holds / while [ -n "${root}" ]; do if [ -e "/sys/block/${root}" ]; then echo "/dev/${root}" return 0 fi # Remove last character root="${root::-1}" done return 1 } function device_is_mdraid() { local device="${1}" [ -d "/sys/block/${device/\/dev/}/md" ] } function mdraid_get_slaves() { local device="${1}" local slave for slave in /sys/block/${device/\/dev/}/slaves/*; do echo "/dev/$(basename "${slave}")" done 2>/dev/null } function grub_update_config() { echo "Updating configuration..." if ! grub-mkconfig -o /boot/grub/grub.cfg &>/dev/null; then echo "Could not update configuration. Aborting." >&2 return 1 fi return 0 } function grub_install() { local device="${1}" echo "Installing GRUB on ${device}..." if [ ! -b "${device}" ]; then echo "${device} does not exist or is not a block device" >&2 return 1 fi local arches case "$(uname -m)" in aarch64) arches="arm64-efi" ;; i?86) arches="i386-pc" ;; x86_64) arches="i386-pc x86_64-efi" ;; esac local arch for arch in ${arches}; do local args="--target=${arch}" case "${arch}" in *-efi) # Skip all EFI architectures if no EFI partition exists if [ ! -d "/boot/efi" ]; then continue fi args="${args} --efi-directory=/boot/efi" # Don't try to modify the BIOS when we are # not running on EFI right now if [ ! -d "/sys/firmware/efi" ]; then args="${args} --no-nvram" fi ;; esac local removable for removable in "" "--removable"; do if ! grub-install ${GRUB_INSTALL_ARGS} ${args} \ ${removable} "${device}" &>/dev/null; then echo "Could not install GRUB on ${device}" >&2 return 1 fi # Do not try to install with --removable for non-efi architectures [[ "${arch}" =~ \-efi$ ]] || break done done return 0 } function main() { local device="${1}" # Find the root device if [ -z "${device}" ]; then device="$(find_bootloader_device)" if [ -z "${device}" ]; then echo "Could not find root device. Aborting." >&2 return 1 fi echo "Found bootloader device: ${device}" fi if [ ! -b "${device}" ]; then echo "${device} does not exist" >&2 return 2 fi # Update configuration files grub_update_config || return $? # Handle mdraid devices if device_is_mdraid "${device}"; then local slave for slave in $(mdraid_get_slaves "${device}"); do grub_install "${slave}" done # Handle normal block devices else grub_install "${device}" fi return 0 } # Run main function main "$@" || exit $?