2N/A#! /bin/sh
2N/Aset -e
2N/A
2N/A# Generate grub.cfg by inspecting /boot contents.
2N/A# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
2N/A# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
2N/A#
2N/A# GRUB is free software: you can redistribute it and/or modify
2N/A# it under the terms of the GNU General Public License as published by
2N/A# the Free Software Foundation, either version 3 of the License, or
2N/A# (at your option) any later version.
2N/A#
2N/A# GRUB is distributed in the hope that it will be useful,
2N/A# but WITHOUT ANY WARRANTY; without even the implied warranty of
2N/A# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2N/A# GNU General Public License for more details.
2N/A#
2N/A# You should have received a copy of the GNU General Public License
2N/A# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
2N/A
2N/Atransform="@program_transform_name@"
2N/A
2N/Aprefix=@prefix@
2N/Aexec_prefix=@exec_prefix@
2N/Asbindir=@sbindir@
2N/Abindir=@bindir@
2N/Alibdir=@libdir@
2N/Asysconfdir=@sysconfdir@
2N/APACKAGE_NAME=@PACKAGE_NAME@
2N/APACKAGE_VERSION=@PACKAGE_VERSION@
2N/Ahost_os=@host_os@
2N/Adatarootdir=@datarootdir@
2N/Adatadir=@datadir@
2N/Apkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"`
2N/Agrub_cfg=""
2N/Agrub_mkconfig_dir=${sysconfdir}/grub.d
2N/A
2N/Aself=`basename $0`
2N/A
2N/Agrub_probe=${sbindir}/`echo grub-probe | sed "${transform}"`
2N/Agrub_script_check="${bindir}/`echo grub-script-check | sed "${transform}"`"
2N/A
2N/AGRUB_PREFIX=`echo '/@bootdirname@/@grubdirname@' | sed "s,//*,/,g"`
2N/A
2N/A# Usage: usage
2N/A# Print the usage.
2N/Ausage () {
2N/A cat <<EOF
2N/AUsage: $self [OPTION]
2N/AGenerate a grub config file
2N/A
2N/A -o, --output=FILE output generated config to FILE [default=stdout]
2N/A -p, --prefix=DIR set the GRUB prefix directory to DIR
2N/A [default=/boot/grub]
2N/A -h, --help print this message and exit
2N/A -v, --version print the version information and exit
2N/A
2N/AReport bugs to <bug-grub@gnu.org>.
2N/AEOF
2N/A}
2N/A
2N/Aargument () {
2N/A opt=$1
2N/A shift
2N/A
2N/A if test $# -eq 0; then
2N/A echo "$0: option requires an argument -- '$opt'" 1>&2
2N/A exit 1
2N/A fi
2N/A echo $1
2N/A}
2N/A
2N/A# Check the arguments.
2N/Awhile test $# -gt 0
2N/Ado
2N/A option=$1
2N/A shift
2N/A
2N/A case "$option" in
2N/A -h | --help)
2N/A usage
2N/A exit 0 ;;
2N/A -v | --version)
2N/A echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
2N/A exit 0 ;;
2N/A -o | --output)
2N/A grub_cfg=`argument $option "$@"`; shift;;
2N/A --output=*)
2N/A grub_cfg=`echo "$option" | sed 's/--output=//'`
2N/A ;;
2N/A -p | --prefix)
2N/A GRUB_PREFIX=`argument $option "$@"`; shift;;
2N/A --prefix=*)
2N/A GRUB_PREFIX=`echo "$option" | sed 's/--prefix=//'`
2N/A ;;
2N/A -*)
2N/A echo "Unrecognized option \`$option'" 1>&2
2N/A usage
2N/A exit 1
2N/A ;;
2N/A # Explicitly ignore non-option arguments, for compatibility.
2N/A esac
2N/Adone
2N/A
2N/Aexport grub_mkdevicemap GRUB_PREFIX
2N/A. ${libdir}/@PACKAGE@/grub-mkconfig_lib
2N/A
2N/Aif [ "x$EUID" = "x" ] ; then
2N/A EUID=`id -u`
2N/Afi
2N/A
2N/Aif [ "$EUID" != 0 ] ; then
2N/A root=f
2N/A case "`uname 2>/dev/null`" in
2N/A CYGWIN*)
2N/A # Cygwin: Assume root if member of admin group
2N/A for g in `id -G 2>/dev/null` ; do
2N/A case $g in
2N/A 0|544) root=t ;;
2N/A esac
2N/A done ;;
2N/A esac
2N/A if [ $root != t ] ; then
2N/A echo "$self: You must run this as root" >&2
2N/A exit 1
2N/A fi
2N/Afi
2N/A
2N/Aset $grub_probe dummy
2N/Aif test -f "$1"; then
2N/A :
2N/Aelse
2N/A echo "$1: Not found." 1>&2
2N/A exit 1
2N/Afi
2N/A
2N/Aif test -d $GRUB_PREFIX ; then : ; else
2N/A mkdir -p ${GRUB_PREFIX}
2N/Afi
2N/A
2N/A# Device containing our userland. Typically used for root= parameter.
2N/AGRUB_DEVICE="`${grub_probe} --target=device /`"
2N/AGRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true
2N/A
2N/A# Device containing our /boot partition. Usually the same as GRUB_DEVICE.
2N/AGRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`"
2N/AGRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true
2N/A
2N/A# Filesystem for the device containing our userland. Used for stuff like
2N/A# choosing Hurd filesystem module.
2N/AGRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`"
2N/A
2N/Aif test -f ${sysconfdir}/default/grub ; then
2N/A . ${sysconfdir}/default/grub
2N/Afi
2N/A
2N/A# XXX: should this be deprecated at some point?
2N/Aif [ "x${GRUB_TERMINAL}" != "x" ] ; then
2N/A GRUB_TERMINAL_INPUT="${GRUB_TERMINAL}"
2N/A GRUB_TERMINAL_OUTPUT="${GRUB_TERMINAL}"
2N/Afi
2N/A
2N/Atermoutdefault=0
2N/Aif [ "x${GRUB_TERMINAL_OUTPUT}" = "x" ]; then
2N/A GRUB_TERMINAL_OUTPUT=gfxterm;
2N/A termoutdefault=1;
2N/Afi
2N/A
2N/Afor x in ${GRUB_TERMINAL_OUTPUT}; do
2N/A if [ "x${x}" = "xgfxterm" ]; then
2N/A if [ -n "$GRUB_FONT" ] ; then
2N/A if is_path_readable_by_grub ${GRUB_FONT} > /dev/null ; then
2N/A GRUB_FONT_PATH=${GRUB_FONT}
2N/A else
2N/A echo "No such font or not readable by grub: ${GRUB_FONT}" >&2
2N/A exit 1
2N/A fi
2N/A else
2N/A for dir in ${GRUB_PREFIX}/.. ${GRUB_PREFIX} ${pkgdatadir} /usr/share/grub ; do
2N/A for basename in unicode unifont ascii; do
2N/A path="${dir}/${basename}.pf2"
2N/A if is_path_readable_by_grub ${path} > /dev/null ; then
2N/A GRUB_FONT_PATH=${path}
2N/A else
2N/A continue
2N/A fi
2N/A if [ "${basename}" = "ascii" ] ; then
2N/A # make sure all our children behave in conformance with ascii..
2N/A export LANG=C
2N/A fi
2N/A break 2
2N/A done
2N/A done
2N/A fi
2N/A if [ -z "${GRUB_FONT_PATH}" -a -z "${GRUB_FONT_PATH_DIRECT}" ] ; then
2N/A if [ "x$termoutdefault" != "x1" ]; then
2N/A echo "No font for gfxterm found." >&2 ; exit 1
2N/A fi
2N/A GRUB_TERMINAL_OUTPUT=
2N/A fi
2N/A fi
2N/Adone
2N/A
2N/Afor x in ${GRUB_TERMINAL_OUTPUT}; do
2N/A case "x${x}" in
2N/A xgfxterm) ;;
2N/A xconsole | xserial | xofconsole)
2N/A # make sure all our children behave in conformance with ascii..
2N/A export LANG=C;;
2N/A *) echo "Invalid output terminal \"${GRUB_TERMINAL_OUTPUT}\"" >&2 ; exit 1 ;;
2N/A esac
2N/Adone
2N/A
2N/A# These are defined in this script, export them here so that user can
2N/A# override them.
2N/Aexport GRUB_DEVICE \
2N/A GRUB_DEVICE_UUID \
2N/A GRUB_DEVICE_BOOT \
2N/A GRUB_DEVICE_BOOT_UUID \
2N/A GRUB_FS \
2N/A GRUB_FONT_PATH \
2N/A GRUB_PRELOAD_MODULES \
2N/A GRUB_PREFIX
2N/A
2N/A# These are optional, user-defined variables.
2N/Aexport GRUB_DEFAULT \
2N/A GRUB_HIDDEN_TIMEOUT \
2N/A GRUB_HIDDEN_TIMEOUT_QUIET \
2N/A GRUB_TIMEOUT \
2N/A GRUB_DEFAULT_BUTTON \
2N/A GRUB_HIDDEN_TIMEOUT_BUTTON \
2N/A GRUB_TIMEOUT_BUTTON \
2N/A GRUB_BUTTON_CMOS_ADDRESS \
2N/A GRUB_BUTTON_CMOS_CLEAN \
2N/A GRUB_DISTRIBUTOR \
2N/A GRUB_CMDLINE_LINUX \
2N/A GRUB_CMDLINE_LINUX_DEFAULT \
2N/A GRUB_CMDLINE_XEN \
2N/A GRUB_CMDLINE_XEN_DEFAULT \
2N/A GRUB_CMDLINE_LINUX_XEN_REPLACE \
2N/A GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT \
2N/A GRUB_CMDLINE_NETBSD \
2N/A GRUB_CMDLINE_NETBSD_DEFAULT \
2N/A GRUB_TERMINAL_INPUT \
2N/A GRUB_TERMINAL_OUTPUT \
2N/A GRUB_SERIAL_COMMAND \
2N/A GRUB_DISABLE_LINUX_UUID \
2N/A GRUB_DISABLE_RECOVERY \
2N/A GRUB_VIDEO_BACKEND \
2N/A GRUB_GFXMODE \
2N/A GRUB_BACKGROUND \
2N/A GRUB_BACKCOLOR \
2N/A GRUB_FORECOLOR \
2N/A GRUB_THEME \
2N/A GRUB_GFXPAYLOAD_LINUX \
2N/A GRUB_GFXPAYLOAD_MODE \
2N/A GRUB_DISABLE_OS_PROBER \
2N/A GRUB_INIT_TUNE \
2N/A GRUB_SAVEDEFAULT \
2N/A GRUB_ENABLE_CRYPTODISK \
2N/A GRUB_BADRAM \
2N/A GRUB_FONT_PATH_DIRECT \
2N/A GRUB_BACKGROUND_DIRECT \
2N/A GRUB_LOCALE_DIR_DIRECT \
2N/A GRUB_DISABLE_MOD_PRESENCE_TEST
2N/A
2N/Aif test "x${grub_cfg}" != "x"; then
2N/A rm -f ${grub_cfg}.new
2N/A exec > ${grub_cfg}.new
2N/A
2N/A # Allow this to fail, since /boot/grub/ might need to be fatfs to support some
2N/A # firmware implementations (e.g. OFW or EFI).
2N/A chmod 400 ${grub_cfg}.new || grub_warn "Could not make ${grub_cfg}.new readable by only root.\
2N/A This means that if the generated config contains a password it is readable by everyone"
2N/Afi
2N/Aecho "Generating grub.cfg ..." >&2
2N/A
2N/Acat << EOF
2N/A#
2N/A# DO NOT EDIT THIS FILE
2N/A#
2N/A# It is automatically generated by $self using templates
2N/A# from ${grub_mkconfig_dir} and settings from ${sysconfdir}/default/grub
2N/A#
2N/AEOF
2N/A
2N/Afor i in ${grub_mkconfig_dir}/* ; do
2N/A case "$i" in
2N/A # emacsen backup files. FIXME: support other editors
2N/A *~) ;;
2N/A # emacsen autosave files. FIXME: support other editors
2N/A \#*\#) ;;
2N/A *)
2N/A if grub_file_is_not_garbage "$i" && test -x "$i" ; then
2N/A echo
2N/A echo "### BEGIN $i ###"
2N/A "$i"
2N/A echo "### END $i ###"
2N/A fi
2N/A ;;
2N/A esac
2N/Adone
2N/A
2N/Aif test "x${grub_cfg}" != "x" ; then
2N/A if ! ${grub_script_check} ${grub_cfg}.new; then
2N/A echo "Syntax errors are detected in generated GRUB config file." >&2
2N/A echo "Ensure that there are no errors in /etc/default/grub" >&2
2N/A echo "and /etc/grub.d/* files or please file a bug report with" >&2
2N/A echo "${grub_cfg}.new file attached." >&2
2N/A else
2N/A # none of the children aborted with error, install the new grub.cfg
2N/A mv -f ${grub_cfg}.new ${grub_cfg}
2N/A fi
2N/Afi
2N/A
2N/Aecho "done" >&2