mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-21 14:59:34 +00:00
When generating grub.cfg using grub-mkconfig and the scripts 10_linux and 20_linux_xen there is no way to add kernel command line parameters _only_ to the recovery entries generated. This is needed to e.g. start a debug shell in installations using systemd using the kernel command line parameter "systemd.debug-shell" or to recover in a system with encrypted root in situations where the decryption of the root filesystem per crypttab in the intiramfs image is broken and the recovery entry should contain information how to decrypt the rootfs (cryptopts=). This patch does not change the default behaviour of the GRUB if GRUB_CMDLINE_LINUX_RECOVERY is not set. If GRUB_CMDLINE_LINUX_RECOVERY is set and the generated recovery entry should include the kernel parameter "single" the parameter must be explicitly included in GRUB_CMDLINE_LINUX_RECOVERY. As far as I know all credits for the idea and the initial implementation go to Kyle Ranking of Purism. Signed-off-by: Kyle Rankin <kyle.rankin@puri.sm> Signed-off-by: Chris Vogel <chris@z9.de> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
311 lines
8.1 KiB
Bash
311 lines
8.1 KiB
Bash
#! /bin/sh
|
|
set -e
|
|
|
|
# Generate grub.cfg by inspecting /boot contents.
|
|
# Copyright (C) 2006,2007,2008,2009,2010 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/>.
|
|
|
|
prefix="@prefix@"
|
|
exec_prefix="@exec_prefix@"
|
|
datarootdir="@datarootdir@"
|
|
|
|
prefix="@prefix@"
|
|
exec_prefix="@exec_prefix@"
|
|
sbindir="@sbindir@"
|
|
bindir="@bindir@"
|
|
sysconfdir="@sysconfdir@"
|
|
PACKAGE_NAME=@PACKAGE_NAME@
|
|
PACKAGE_VERSION=@PACKAGE_VERSION@
|
|
host_os=@host_os@
|
|
datadir="@datadir@"
|
|
if [ "x$pkgdatadir" = x ]; then
|
|
pkgdatadir="${datadir}/@PACKAGE@"
|
|
fi
|
|
# export it for scripts
|
|
export pkgdatadir
|
|
|
|
grub_cfg=""
|
|
grub_mkconfig_dir="${sysconfdir}"/grub.d
|
|
|
|
self=`basename $0`
|
|
|
|
grub_probe="${sbindir}/@grub_probe@"
|
|
grub_file="${bindir}/@grub_file@"
|
|
grub_editenv="${bindir}/@grub_editenv@"
|
|
grub_script_check="${bindir}/@grub_script_check@"
|
|
|
|
export TEXTDOMAIN=@PACKAGE@
|
|
export TEXTDOMAINDIR="@localedir@"
|
|
|
|
. "${pkgdatadir}/grub-mkconfig_lib"
|
|
|
|
# Usage: usage
|
|
# Print the usage.
|
|
usage () {
|
|
gettext_printf "Usage: %s [OPTION]\n" "$self"
|
|
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 "-h, --help" "$(gettext "print this message and exit")"
|
|
print_option_help "-V, --version" "$(gettext "print the version information and exit")"
|
|
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 ;;
|
|
-o | --output)
|
|
grub_cfg=`argument $option "$@"`; shift;;
|
|
--output=*)
|
|
grub_cfg=`echo "$option" | sed 's/--output=//'`
|
|
;;
|
|
-*)
|
|
gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
|
|
usage
|
|
exit 1
|
|
;;
|
|
# Explicitly ignore non-option arguments, for compatibility.
|
|
esac
|
|
done
|
|
|
|
if [ "x$EUID" = "x" ] ; then
|
|
EUID=`id -u`
|
|
fi
|
|
|
|
if [ "$EUID" != 0 ] ; then
|
|
root=f
|
|
case "`uname 2>/dev/null`" in
|
|
CYGWIN*)
|
|
# Cygwin: Assume root if member of admin group
|
|
for g in `id -G 2>/dev/null` ; do
|
|
case $g in
|
|
0|544) root=t ;;
|
|
esac
|
|
done ;;
|
|
esac
|
|
if [ $root != t ] ; then
|
|
gettext_printf "%s: You must run this as root\n" "$self" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
set $grub_probe dummy
|
|
if test -f "$1"; then
|
|
:
|
|
else
|
|
gettext_printf "%s: Not found.\n" "$1" 1>&2
|
|
exit 1
|
|
fi
|
|
|
|
# Device containing our userland. Typically used for root= parameter.
|
|
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
|
|
|
|
# Device containing our /boot partition. Usually the same as GRUB_DEVICE.
|
|
GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`"
|
|
GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true
|
|
|
|
# Disable os-prober by default due to security reasons.
|
|
GRUB_DISABLE_OS_PROBER="true"
|
|
|
|
# Filesystem for the device containing our userland. Used for stuff like
|
|
# choosing Hurd filesystem module.
|
|
GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`"
|
|
|
|
if [ x"$GRUB_FS" = xunknown ]; then
|
|
GRUB_FS="$(stat -f -c %T / || echo unknown)"
|
|
fi
|
|
|
|
# Provide a default set of stock linux early initrd images.
|
|
# Define here so the list can be modified in the sourced config file.
|
|
if [ "x${GRUB_EARLY_INITRD_LINUX_STOCK}" = "x" ]; then
|
|
GRUB_EARLY_INITRD_LINUX_STOCK="intel-uc.img intel-ucode.img amd-uc.img amd-ucode.img early_ucode.cpio microcode.cpio"
|
|
fi
|
|
|
|
if test -f ${sysconfdir}/default/grub ; then
|
|
. ${sysconfdir}/default/grub
|
|
fi
|
|
|
|
if [ "x${GRUB_DISABLE_UUID}" = "xtrue" ]; then
|
|
if [ -z "${GRUB_DISABLE_LINUX_UUID}" ]; then
|
|
GRUB_DISABLE_LINUX_UUID="true"
|
|
fi
|
|
if [ -z "${GRUB_DISABLE_LINUX_PARTUUID}" ]; then
|
|
GRUB_DISABLE_LINUX_PARTUUID="true"
|
|
fi
|
|
fi
|
|
|
|
# XXX: should this be deprecated at some point?
|
|
if [ "x${GRUB_TERMINAL}" != "x" ] ; then
|
|
GRUB_TERMINAL_INPUT="${GRUB_TERMINAL}"
|
|
GRUB_TERMINAL_OUTPUT="${GRUB_TERMINAL}"
|
|
fi
|
|
|
|
termoutdefault=0
|
|
if [ "x${GRUB_TERMINAL_OUTPUT}" = "x" ]; then
|
|
GRUB_TERMINAL_OUTPUT=gfxterm;
|
|
termoutdefault=1;
|
|
fi
|
|
|
|
for x in ${GRUB_TERMINAL_OUTPUT}; do
|
|
case "x${x}" in
|
|
xgfxterm) ;;
|
|
xconsole | xserial | xofconsole | xvga_text)
|
|
# make sure all our children behave in conformance with ascii..
|
|
export LANG=C;;
|
|
*) echo "Invalid output terminal \"${GRUB_TERMINAL_OUTPUT}\"" >&2 ; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
GRUB_ACTUAL_DEFAULT="$GRUB_DEFAULT"
|
|
|
|
if [ "x${GRUB_ACTUAL_DEFAULT}" = "xsaved" ] ; then GRUB_ACTUAL_DEFAULT="`"${grub_editenv}" - list | sed -n '/^saved_entry=/ s,^saved_entry=,,p'`" ; fi
|
|
|
|
|
|
# These are defined in this script, export them here so that user can
|
|
# override them.
|
|
export GRUB_DEVICE \
|
|
GRUB_DEVICE_UUID \
|
|
GRUB_DEVICE_PARTUUID \
|
|
GRUB_DEVICE_BOOT \
|
|
GRUB_DEVICE_BOOT_UUID \
|
|
GRUB_DISABLE_OS_PROBER \
|
|
GRUB_FS \
|
|
GRUB_FONT \
|
|
GRUB_PRELOAD_MODULES \
|
|
GRUB_ACTUAL_DEFAULT
|
|
|
|
# These are optional, user-defined variables.
|
|
export GRUB_DEFAULT \
|
|
GRUB_HIDDEN_TIMEOUT \
|
|
GRUB_HIDDEN_TIMEOUT_QUIET \
|
|
GRUB_TIMEOUT \
|
|
GRUB_TIMEOUT_STYLE \
|
|
GRUB_DEFAULT_BUTTON \
|
|
GRUB_HIDDEN_TIMEOUT_BUTTON \
|
|
GRUB_TIMEOUT_BUTTON \
|
|
GRUB_TIMEOUT_STYLE_BUTTON \
|
|
GRUB_BUTTON_CMOS_ADDRESS \
|
|
GRUB_BUTTON_CMOS_CLEAN \
|
|
GRUB_DISTRIBUTOR \
|
|
GRUB_CMDLINE_LINUX \
|
|
GRUB_CMDLINE_LINUX_DEFAULT \
|
|
GRUB_CMDLINE_LINUX_RECOVERY \
|
|
GRUB_CMDLINE_XEN \
|
|
GRUB_CMDLINE_XEN_DEFAULT \
|
|
GRUB_CMDLINE_LINUX_XEN_REPLACE \
|
|
GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT \
|
|
GRUB_CMDLINE_NETBSD \
|
|
GRUB_CMDLINE_NETBSD_DEFAULT \
|
|
GRUB_CMDLINE_GNUMACH \
|
|
GRUB_EARLY_INITRD_LINUX_CUSTOM \
|
|
GRUB_EARLY_INITRD_LINUX_STOCK \
|
|
GRUB_TERMINAL_INPUT \
|
|
GRUB_TERMINAL_OUTPUT \
|
|
GRUB_SERIAL_COMMAND \
|
|
GRUB_DISABLE_UUID \
|
|
GRUB_DISABLE_LINUX_UUID \
|
|
GRUB_DISABLE_LINUX_PARTUUID \
|
|
GRUB_DISABLE_RECOVERY \
|
|
GRUB_VIDEO_BACKEND \
|
|
GRUB_GFXMODE \
|
|
GRUB_BACKGROUND \
|
|
GRUB_THEME \
|
|
GRUB_GFXPAYLOAD_LINUX \
|
|
GRUB_INIT_TUNE \
|
|
GRUB_SAVEDEFAULT \
|
|
GRUB_ENABLE_CRYPTODISK \
|
|
GRUB_BADRAM \
|
|
GRUB_OS_PROBER_SKIP_LIST \
|
|
GRUB_DISABLE_SUBMENU
|
|
|
|
if test "x${grub_cfg}" != "x"; then
|
|
rm -f "${grub_cfg}.new"
|
|
oldumask=$(umask); umask 077
|
|
exec > "${grub_cfg}.new"
|
|
umask $oldumask
|
|
fi
|
|
gettext "Generating grub configuration file ..." >&2
|
|
echo >&2
|
|
|
|
cat << EOF
|
|
#
|
|
# DO NOT EDIT THIS FILE
|
|
#
|
|
# It is automatically generated by $self using templates
|
|
# from ${grub_mkconfig_dir} and settings from ${sysconfdir}/default/grub
|
|
#
|
|
EOF
|
|
|
|
|
|
for i in "${grub_mkconfig_dir}"/* ; do
|
|
case "$i" in
|
|
# emacsen backup files. FIXME: support other editors
|
|
*~) ;;
|
|
# emacsen autosave files. FIXME: support other editors
|
|
*/\#*\#) ;;
|
|
*)
|
|
if grub_file_is_not_garbage "$i" && test -x "$i" ; then
|
|
echo
|
|
echo "### BEGIN $i ###"
|
|
"$i"
|
|
echo "### END $i ###"
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if test "x${grub_cfg}" != "x" ; then
|
|
if ! ${grub_script_check} ${grub_cfg}.new; then
|
|
# TRANSLATORS: %s is replaced by filename
|
|
gettext_printf "Syntax errors are detected in generated GRUB config file.
|
|
Ensure that there are no errors in /etc/default/grub
|
|
and /etc/grub.d/* files or please file a bug report with
|
|
%s file attached." "${grub_cfg}.new" >&2
|
|
echo >&2
|
|
exit 1
|
|
else
|
|
# none of the children aborted with error, install the new grub.cfg
|
|
cat ${grub_cfg}.new > ${grub_cfg}
|
|
rm -f ${grub_cfg}.new
|
|
fi
|
|
fi
|
|
|
|
gettext "done" >&2
|
|
echo >&2
|