Fix menu title instability bug.

* grub-core/commands/menuentry.c (options): New option --id.
	(grub_normal_add_menu_entry): New argument id. All users updated.
	(grub_cmd_menuentry): Handle --id.
	(grub_menu_init): Accept unknown arguments.
	* grub-core/normal/main.c (features): Add feature_menuentry_id and
	feature_menuentry_options.
	* grub-core/normal/menu.c (grub_menu_execute_entry): Use id for
	saved_entry.
	(get_entry_number): Match with id as well.
	* include/grub/menu.h (grub_menu_entry): New member id.
	* util/grub-mkconfig_lib.in (grub_get_device_id): New function.
	* util/grub.d/00_header.in: Define menuentry_id_option.
	* util/grub.d/10_hurd.in: Define id.
	* util/grub.d/10_illumos.in: Likewise.
	* util/grub.d/10_kfreebsd.in: Likewise.
	* util/grub.d/10_linux.in: Likewise.
	* util/grub.d/10_netbsd.in: Likewise.
	* util/grub.d/10_windows.in: Likewise.
	* util/grub.d/20_linux_xen.in: Likewise.
	* util/grub.d/30_os-prober.in: Likewise.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-03-04 14:55:13 +01:00
parent 0d31b7df86
commit d9bef9bc43
17 changed files with 126 additions and 27 deletions

View file

@ -162,6 +162,16 @@ prepare_grub_to_access_device ()
fi
}
grub_get_device_id ()
{
device="$1"
if fs_uuid="`"${grub_probe}" --device "${device}" --target=fs_uuid 2> /dev/null`" ; then
echo "$fs_uuid";
else
echo "$device"
fi
}
grub_file_is_not_garbage ()
{
if test -f "$1" ; then

View file

@ -63,6 +63,15 @@ set default="${GRUB_DEFAULT}"
EOF
fi
cat <<EOF
if [ x"\${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
else
menuentry_id_option=""
fi
export menuentry_id_option
if [ "\${prev_saved_entry}" ]; then
set saved_entry="\${prev_saved_entry}"
save_env saved_entry

View file

@ -85,9 +85,9 @@ do
KERNEL="using ${kernel_base}"
cat << EOF
menuentry "${OS} ${KERNEL}" ${CLASS} {
menuentry "${OS} ${KERNEL}" ${CLASS} \$menuentry_id_option 'gnuhurd-$kernel-false-$(grub_get_device_id "${GRUB_DEVICE_BOOT}")' {
EOF
prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
prepare_grub_to_access_device "${GRUB_DEVICE_BOOT}" | sed -e "s/^/\t/"
message="$(gettext_printf "Loading GNU Mach ...")"
cat << EOF
echo '$message'

View file

@ -34,9 +34,9 @@ case "${GRUB_DISTRIBUTOR}" in
;;
esac
echo "menuentry '${OS}' ${CLASS} {"
echo "menuentry '${OS}' ${CLASS} \$menuentry_id_option 'illumos-$(grub_get_device_id "${GRUB_DEVICE_BOOT}")' {"
save_default_entry | sed -e "s/^/\t/"
prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
prepare_grub_to_access_device "${GRUB_DEVICE_BOOT}" | sed -e "s/^/\t/"
message="$(gettext_printf "Loading kernel of Illumos ...")"
cat << EOF
insmod gzio

View file

@ -74,7 +74,10 @@ kfreebsd_entry ()
else
title="$(gettext_quoted "%s, with kFreeBSD %s")"
fi
printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}"
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
printf "menuentry '${title}' ${CLASS} \$menuentry_id_option 'kfreebsd-$version-$recovery-$boot_device_id' {\n" "${os}" "${version}"
if ! ${recovery} ; then
save_default_entry | sed -e "s/^/\t/"
fi
@ -132,6 +135,7 @@ list=`for i in /boot/kfreebsd-* /boot/kernel/kernel ; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
prepare_boot_cache=
boot_device_id=
while [ "x$list" != "x" ] ; do
kfreebsd=`version_find_latest $list`

View file

@ -77,7 +77,10 @@ linux_entry ()
else
title="$(gettext_quoted "%s, with Linux %s")"
fi
printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${version}"
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
printf "menuentry '${title}' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$recovery-$boot_device_id' {\n" "${os}" "${version}"
if ! ${recovery} ; then
save_default_entry | sed -e "s/^/\t/"
fi
@ -151,6 +154,7 @@ esac
prepare_boot_cache=
prepare_root_cache=
boot_device_id=
while [ "x$list" != "x" ] ; do
linux=`version_find_latest $list`

View file

@ -99,7 +99,10 @@ netbsd_entry ()
title="$(gettext_quoted "%s, with kernel %s (via %s)")"
fi
printf "menuentry \"${title}\" {\n" \
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
printf "menuentry \"${title}\" \$menuentry_id_option 'netbsd-$kernel-$recovery-$boot_device_id' {\n" \
"${OS}" "$(echo ${kernel} | sed -e 's,^.*/,,')" "${loader}"
printf "%s\n" "${prepare_boot_cache}"
case "${loader}" in
@ -119,6 +122,7 @@ netbsd_entry ()
}
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e 's,^, ,')"
boot_device_id=
# We look for NetBSD kernels in / but not in subdirectories. We simply
# pick all statically linked ELF executable files (or links) in / with a

View file

@ -63,14 +63,16 @@ for drv in $drives ; do
test -n "$dir" || continue
needmap=
osid=
# Check for Vista bootmgr.
if [ -f "$dir"/bootmgr -a -f "$dir"/boot/bcd ] ; then
OS="$(gettext_quoted "Windows Vista/7 (loader)")"
osid=bootmgr
# Check for NTLDR.
elif [ -f "$dir"/ntldr -a -f "$dir"/ntdetect.com -a -f "$dir"/boot.ini ] ; then
OS=`get_os_name_from_boot_ini "$dir"/boot.ini` || OS="$(gettext_quoted "Windows NT/2000/XP (loader)")"
osid=ntldr
needmap=t
else
@ -82,7 +84,7 @@ for drv in $drives ; do
gettext_printf "Found %s on %s (%s)\n" "$OS" "$drv" "$dev" >&2
cat << EOF
menuentry "$OS" {
menuentry "$OS" \$menuentry_id_option '$osid-$(grub_get_device_id "${dev}")' {
EOF
save_default_entry | sed -e 's,^,\t,'

View file

@ -87,7 +87,10 @@ linux_entry ()
else
title="$(gettext_quoted "%s, with Xen %s and Linux %s")"
fi
printf "menuentry '${title}' ${CLASS} {\n" "${os}" "${xen_version}" "${version}"
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
printf "menuentry '${title}' ${CLASS} \$menuentry_id_option 'xen-gnulinux-$version-$recovery-$boot_device_id' {\n" "${os}" "${xen_version}" "${version}"
if ! ${recovery} ; then
save_default_entry | sed -e "s/^/\t/"
fi
@ -139,6 +142,7 @@ xen_list=`for i in /boot/xen*; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
prepare_boot_cache=
boot_device_id=
while [ "x${xen_list}" != "x" ] ; do
list="${linux_list}"
@ -147,7 +151,10 @@ while [ "x${xen_list}" != "x" ] ; do
xen_dirname=`dirname ${current_xen}`
rel_xen_dirname=`make_system_path_relative_to_its_root $xen_dirname`
xen_version=`echo $xen_basename | sed -e "s,.gz$,,g;s,^xen-,,g"`
echo "submenu \"Xen ${xen_version}\" {"
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
fi
echo "submenu \"Xen ${xen_version}\" \$menuentry_id_option 'xen-hypervisor-$xen_version-$boot_device_id' {"
while [ "x$list" != "x" ] ; do
linux=`version_find_latest $list`
gettext_printf "Found linux image: %s\n" "$linux" >&2

View file

@ -52,7 +52,7 @@ osx_entry() {
# TRANSLATORS: it refers on the OS residing on device %s
onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
cat << EOF
menuentry "${LONGNAME} $bitstr $onstr" --class osx --class darwin --class os {
menuentry "${LONGNAME} $bitstr $onstr" --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${DEVICE}")' {
EOF
save_default_entry | sed -e "s/^/\t/"
prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
@ -104,6 +104,8 @@ EOF
EOF
}
used_osprober_linux_ids=
for OS in ${OSPROBED} ; do
DEVICE="`echo ${OS} | cut -d ':' -f 1`"
LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`"
@ -121,7 +123,7 @@ for OS in ${OSPROBED} ; do
onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
cat << EOF
menuentry "${LONGNAME} $onstr" --class windows --class os {
menuentry "${LONGNAME} $onstr" --class windows --class os \$menuentry_id_option 'osprober-chain-$(grub_get_device_id "${DEVICE}")' {
EOF
save_default_entry | sed -e "s/^/\t/"
prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
@ -144,6 +146,7 @@ EOF
linux)
LINUXPROBED="`linux-boot-prober ${DEVICE} 2> /dev/null | tr ' ' '^' | paste -s -d ' '`"
prepare_boot_cache=
boot_device_id=
for LINUX in ${LINUXPROBED} ; do
LROOT="`echo ${LINUX} | cut -d ':' -f 1`"
@ -163,8 +166,17 @@ EOF
fi
onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
recovery_params="$(echo "${LPARAMS}" | grep single)"
counter=1
while echo "$used_osprober_linux_ids" | grep 'osprober-gnulinux-$LKERNEL-${recovery_params}-$counter-$boot_device_id' > /dev/null; do
counter=$((counter+1));
done
if [ -z "$boot_device_id" ]; then
boot_device_id="$(grub_get_device_id "${DEVICE}")"
fi
used_osprober_linux_ids="$used_osprober_linux_ids 'osprober-gnulinux-$LKERNEL-${recovery_params}-$counter-$boot_device_id'"
cat << EOF
menuentry "${LLABEL} $onstr" --class gnu-linux --class gnu --class os {
menuentry "${LLABEL} $onstr" --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux-$LKERNEL-${recovery_params}-$boot_device_id' {
EOF
save_default_entry | sed -e "s/^/\t/"
if [ -z "${prepare_boot_cache}" ]; then
@ -192,7 +204,7 @@ EOF
hurd)
onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
cat << EOF
menuentry "${LONGNAME} $onstr" --class hurd --class gnu --class os {
menuentry "${LONGNAME} $onstr" --class hurd --class gnu --class os \$menuentry_id_option 'osprober-gnuhurd-/boot/gnumach.gz-false-$(grub_get_device_id "${DEVICE}")' {
EOF
save_default_entry | sed -e "s/^/\t/"
prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"