grub2/20-grub.install
Javier Martinez Canillas 4a742183a3
Store cmdline in BLS snippets instead of using a grubenv variable
The kernel cmdline was stored as a kernelopts variable in the grubenv file
and the BLS snippets used that. But this turned out to be fragile since the
grubenv file could be removed or get corrupted easily.

To prevent the entries to not have a cmdline if the grubenv can't be read,
a fallback variable was set in the GRUB config file. But this still caused
issues since the config needs to be re-generated to change the parameters.

Instead, let's store the cmdline in the BLS snippets. This will make the
configuration more robust, since it will work even without the grubenv
file and the BLS entries will contain all the information needed to boot.

Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
2020-05-13 20:03:20 +02:00

176 lines
6.8 KiB
Bash
Executable file

#!/bin/bash
if ! [[ $KERNEL_INSTALL_MACHINE_ID ]]; then
exit 0
fi
[[ -f /etc/default/grub ]] && . /etc/default/grub
[[ -f /etc/os-release ]] && . /etc/os-release
COMMAND="$1"
KERNEL_VERSION="$2"
BOOT_DIR_ABS="$3"
KERNEL_IMAGE="$4"
KERNEL_DIR="${KERNEL_IMAGE%/*}"
MACHINE_ID=$KERNEL_INSTALL_MACHINE_ID
# If ${BOOT_DIR_ABS} exists, some other boot loader is active.
[[ -d "${BOOT_DIR_ABS}" ]] && exit 0
BLS_DIR="/boot/loader/entries"
mkbls() {
local kernelver=$1 && shift
local datetime=$1 && shift
local kernelopts=$1 && shift
local debugname=""
local debugid=""
local flavor=""
if [[ "$kernelver" == *\+* ]] ; then
local flavor=-"${kernelver##*+}"
if [[ "${flavor}" == "-debug" ]]; then
local debugname=" with debugging"
local debugid="-debug"
fi
fi
cat <<EOF
title ${NAME} (${kernelver}) ${VERSION}${debugname}
version ${kernelver}${debugid}
linux /vmlinuz-${kernelver}
initrd /initramfs-${kernelver}.img
options ${kernelopts}
grub_users \$grub_users
grub_arg --unrestricted
grub_class kernel${flavor}
EOF
}
[[ "$KERNEL_VERSION" == *\+* ]] && flavor=-"${KERNEL_VERSION##*+}"
case "$COMMAND" in
add)
if [[ "${KERNEL_DIR}" != "/boot" ]]; then
for i in \
"$KERNEL_IMAGE" \
"$KERNEL_DIR"/System.map \
"$KERNEL_DIR"/config \
"$KERNEL_DIR"/zImage.stub \
"$KERNEL_DIR"/dtb
do
[[ -e "$i" ]] || continue
rm -f "/boot/${i##*/}-${KERNEL_VERSION}"
cp -aT "$i" "/boot/${i##*/}-${KERNEL_VERSION}"
command -v restorecon &>/dev/null && \
restorecon -R "/boot/${i##*/}-${KERNEL_VERSION}"
done
# hmac is .vmlinuz-<version>.hmac so needs a special treatment
i="$KERNEL_DIR/.${KERNEL_IMAGE##*/}.hmac"
if [[ -e "$i" ]]; then
rm -f "/boot/.${KERNEL_IMAGE##*/}-${KERNEL_VERSION}.hmac"
cp -a "$i" "/boot/.${KERNEL_IMAGE##*/}-${KERNEL_VERSION}.hmac"
command -v restorecon &>/dev/null && \
restorecon "/boot/.${KERNEL_IMAGE##*/}-${KERNEL_VERSION}.hmac"
fi
fi
if [[ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]] || [[ ! -f /sbin/new-kernel-pkg ]]; then
if [[ -f /etc/kernel/cmdline ]]; then
read -r -d '' -a BOOT_OPTIONS < /etc/kernel/cmdline
elif [[ -f /usr/lib/kernel/cmdline ]]; then
read -r -d '' -a BOOT_OPTIONS < /usr/lib/kernel/cmdline
else
declare -a BOOT_OPTIONS
read -r -d '' -a line < /proc/cmdline
for i in "${line[@]}"; do
[[ "${i#initrd=*}" != "$i" ]] && continue
[[ "${i#BOOT_IMAGE=*}" != "$i" ]] && continue
BOOT_OPTIONS+=("$i")
done
fi
eval "$(grub2-get-kernel-settings)" || true
[[ -d "$BLS_DIR" ]] || mkdir -m 0700 -p "$BLS_DIR"
BLS_ID="${MACHINE_ID}-${KERNEL_VERSION}"
BLS_TARGET="${BLS_DIR}/${BLS_ID}.conf"
mkbls "${KERNEL_VERSION}" \
"$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${KERNEL_DIR}")")" \
"${BOOT_OPTIONS[*]}" >"${BLS_TARGET}"
command -v restorecon &>/dev/null && restorecon -R "${BLS_TARGET}"
LINUX="$(grep '^linux[ \t]' "${BLS_TARGET}" | sed -e 's,^linux[ \t]*,,')"
INITRD="$(grep '^initrd[ \t]' "${BLS_TARGET}" | sed -e 's,^initrd[ \t]*,,')"
LINUX_RELPATH="$(grub2-mkrelpath /boot${LINUX})"
BOOTPREFIX="$(dirname ${LINUX_RELPATH})"
ROOTPREFIX="$(dirname "/boot${LINUX}")"
if [[ $LINUX != $LINUX_RELPATH ]]; then
sed -i -e "s,^linux.*,linux ${BOOTPREFIX}${LINUX},g" "${BLS_TARGET}"
sed -i -e "s,^initrd.*,initrd ${BOOTPREFIX}${INITRD},g" "${BLS_TARGET}"
fi
if [[ "$KERNEL_VERSION" == *\+* ]] && [ "x$GRUB_DEFAULT_TO_DEBUG" != "xtrue" ]; then
GRUB_UPDATE_DEFAULT_KERNEL=false
fi
if [ "x$GRUB_UPDATE_DEFAULT_KERNEL" = "xtrue" ]; then
NEWDEFAULT="${BLS_ID}"
fi
if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
BLS_DEBUG="$(echo ${BLS_TARGET} | sed -e "s/${KERNEL_VERSION}/${KERNEL_VERSION}~debug/")"
cp -aT "${BLS_TARGET}" "${BLS_DEBUG}"
TITLE="$(grep '^title[ \t]' "${BLS_DEBUG}" | sed -e 's/^title[ \t]*//')"
OPTIONS="$(echo "${BOOT_OPTIONS[*]} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 's/\//\\\//g')"
sed -i -e "s/^title.*/title ${TITLE}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${BLS_DEBUG}"
sed -i -e "s/^options.*/options ${OPTIONS}/" "${BLS_DEBUG}"
if [ -n "$NEWDEFAULT" -a "x$GRUB_DEFAULT_TO_DEBUG" = "xtrue" ]; then
NEWDEFAULT="${BLS_DEBUG_ID}"
fi
fi
if [ -n "$NEWDEFAULT" ]; then
grub2-editenv - set "saved_entry=${NEWDEFAULT}"
fi
# this probably isn't the best place to do this, but it will do for now.
if [ -e "${ROOTPREFIX}${INITRD}" -a -e "${ROOTPREFIX}${LINUX}" -a \
"${ROOTPREFIX}${INITRD}" -ot "${ROOTPREFIX}${LINUX}" -a \
-x /usr/lib/kernel/install.d/50-dracut.install ]; then
rm -f "${ROOTPREFIX}${INITRD}"
fi
exit 0
fi
/sbin/new-kernel-pkg --package "kernel${flavor}" --install "$KERNEL_VERSION" || exit $?
/sbin/new-kernel-pkg --package "kernel${flavor}" --mkinitrd --dracut --depmod --update "$KERNEL_VERSION" || exit $?
/sbin/new-kernel-pkg --package "kernel${flavor}" --rpmposttrans "$KERNEL_VERSION" || exit $?
# If grubby is used there's no need to run other installation plugins
exit 77
;;
remove)
if [[ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]] || [[ ! -f /sbin/new-kernel-pkg ]]; then
BLS_TARGET="${BLS_DIR}/${MACHINE_ID}-${KERNEL_VERSION}.conf"
BLS_DEBUG="$(echo ${BLS_TARGET} | sed -e "s/${KERNEL_VERSION}/${KERNEL_VERSION}~debug/")"
rm -f "${BLS_TARGET}" "${BLS_DEBUG}"
for i in vmlinuz System.map config zImage.stub dtb; do
rm -rf "/boot/${i}-${KERNEL_VERSION}"
done
# hmac is .vmlinuz-<version>.hmac so needs a special treatment
rm -f "/boot/.vmlinuz-${KERNEL_VERSION}.hmac"
exit 0
fi
/sbin/new-kernel-pkg --package "kernel${flavor+-$flavor}" --rminitrd --rmmoddep --remove "$KERNEL_VERSION" || exit $?
# If grubby is used there's no need to run other installation plugins
exit 77
;;
*)
;;
esac