Skip to content

Instantly share code, notes, and snippets.

@pepa65
Last active August 25, 2017 17:35
Show Gist options
  • Save pepa65/85d5fcd1e12bc6028501c746258ac8cf to your computer and use it in GitHub Desktop.
Save pepa65/85d5fcd1e12bc6028501c746258ac8cf to your computer and use it in GitHub Desktop.
Improving update-grub (grub-mkconfig), only include versions that are included in the root partition's /lib/modules
10_linux
10_linux.new
10_linux.old
30_os-prober
30_os-prober.new
30_os-prober.old
--- 10_linux 2016-12-02 20:50:42.694551531 +0700
+++ 10_linux.new 2016-12-02 23:01:24.196539487 +0700
@@ -274,6 +274,7 @@
submenu_indentation=""
is_top_level=true
+gettext_printf "On %s\n" "$(sed 's/ \\.//g' /etc/issue)" >&2
while [ "x$list" != "x" ] ; do
linux=`version_find_latest $list`
case $linux in
@@ -283,12 +284,18 @@
continue
;;
esac
- gettext_printf "Found linux image: %s\n" "$linux" >&2
basename=`basename $linux`
dirname=`dirname $linux`
rel_dirname=`make_system_path_relative_to_its_root $dirname`
version=`echo $basename | sed -e "s,^[^0-9]*-,,g"`
alt_version=`echo $version | sed -e "s,\.old$,,g"`
+ ## Only if version is in /lib/modules
+ if [ "x$(echo /lib/modules/* |grep $version)" = "x" ]
+ then
+ list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '`
+ continue
+ fi
+ gettext_printf "Found kernel %s\n" "$linux" >&2
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
initrd=
@@ -320,7 +327,7 @@
fi
if test -n "${initrd}" ; then
- gettext_printf "Found initrd image: %s\n" "${dirname}/${initrd}" >&2
+ gettext_printf "Found initrd %s\n" "${dirname}/${initrd}" >&2
elif test -z "${initramfs}" ; then
# "UUID=" and "ZFS=" magic is parsed by initrd or initramfs. Since there's
# no initrd or builtin initramfs, it can't work here.
--- 30_os-prober 2016-12-02 21:37:07.677467196 +0700
+++ 30_os-prober.new 2016-12-03 08:08:49.735992607 +0700
@@ -59,19 +59,19 @@
found_other_os=1
if [ x$2 = x32 ]; then
# TRANSLATORS: it refers to kernel architecture (32-bit)
- bitstr="$(gettext "(32-bit)")"
+ bitstr="$(gettext "(32-bit)")"
else
# TRANSLATORS: it refers to kernel architecture (64-bit)
- bitstr="$(gettext "(64-bit)")"
+ bitstr="$(gettext "(64-bit)")"
fi
# TRANSLATORS: it refers on the OS residing on device %s
onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
cat << EOF
menuentry '$(echo "${LONGNAME} $bitstr $onstr" | grub_quote)' --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${DEVICE}")' {
EOF
- save_default_entry | grub_add_tab
- prepare_grub_to_access_device ${DEVICE} | grub_add_tab
- cat << EOF
+ save_default_entry | grub_add_tab
+ prepare_grub_to_access_device ${DEVICE} | grub_add_tab
+ cat << EOF
load_video
set do_resume=0
if [ /var/vm/sleepimage -nt10 / ]; then
@@ -144,8 +144,8 @@
BTRFS="`echo ${OS} | cut -d ':' -f 5`"
if [ "x$BTRFS" = "xbtrfs" ]; then
- BTRFSuuid="`echo ${OS} | cut -d ':' -f 6`"
- BTRFSsubvol="`echo ${OS} | cut -d ':' -f 7`"
+ BTRFSuuid="`echo ${OS} | cut -d ':' -f 6`"
+ BTRFSsubvol="`echo ${OS} | cut -d ':' -f 7`"
fi
if [ -z "${LONGNAME}" ] ; then
@@ -158,24 +158,24 @@
chain)
case ${LONGNAME} in
- Windows*)
- if [ -z "$wubi" ]; then
- if [ -x /usr/share/lupin-support/grub-mkimage ] && \
- /usr/share/lupin-support/grub-mkimage --test; then
- wubi=yes
- else
- wubi=no
- fi
- fi
- if [ "$wubi" = yes ]; then
- echo "Skipping ${LONGNAME} on Wubi system" >&2
- continue
- fi
- ;;
+ Windows*)
+ if [ -z "$wubi" ]; then
+ if [ -x /usr/share/lupin-support/grub-mkimage ] && \
+ /usr/share/lupin-support/grub-mkimage --test; then
+ wubi=yes
+ else
+ wubi=no
+ fi
+ fi
+ if [ "$wubi" = yes ]; then
+ echo "Skipping ${LONGNAME} on Wubi system" >&2
+ continue
+ fi
+ ;;
esac
found_other_os=1
- onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
+ onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
cat << EOF
menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class windows --class os \$menuentry_id_option 'osprober-chain-$(grub_get_device_id "${DEVICE}")' {
EOF
@@ -183,32 +183,32 @@
prepare_grub_to_access_device ${DEVICE} | grub_add_tab
if [ x"`${grub_probe} --device ${DEVICE} --target=partmap`" = xmsdos ]; then
- cat << EOF
- parttool \${root} hidden-
+ cat << EOF
+ parttool \${root} hidden-
EOF
fi
case ${LONGNAME} in
- Windows\ Vista*|Windows\ 7*|Windows\ Server\ 2008*)
- ;;
- *)
- cat << EOF
- drivemap -s (hd0) \${root}
+ Windows\ Vista*|Windows\ 7*|Windows\ Server\ 2008*)
+ ;;
+ *)
+ cat << EOF
+ drivemap -s (hd0) \${root}
EOF
- ;;
+ ;;
esac
cat <<EOF
- chainloader +1
+ chainloader +1
}
EOF
;;
efi)
- found_other_os=1
- EFIPATH=${DEVICE#*@}
- DEVICE=${DEVICE%@*}
- onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
+ found_other_os=1
+ EFIPATH=${DEVICE#*@}
+ DEVICE=${DEVICE%@*}
+ onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
cat << EOF
menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class windows --class os \$menuentry_id_option 'osprober-efi-$(grub_get_device_id "${DEVICE}")' {
EOF
@@ -216,7 +216,7 @@
prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
cat <<EOF
- chainloader ${EFIPATH}
+ chainloader ${EFIPATH}
}
EOF
;;
@@ -226,100 +226,115 @@
else
LINUXPROBED="`linux-boot-prober ${DEVICE} 2> /dev/null | tr ' ' '^' | paste -s -d ' '`"
fi
+ ## os-prober (linux-boot-prober) gets it wrong by parsing grub.cfg
+ LROOT="`echo ${LINUXPROBED} | cut -d ':' -f 1`"
+ LBOOT="`echo ${LINUXPROBED} | cut -d ':' -f 2`"
+ label="`echo ${LINUXPROBED} | cut -d ':' -f 3 | tr '^' ' '`, with Linux"
+ LPARAMS="`echo ${LINUXPROBED} | cut -d ':' -f 6 | tr '^' ' ' |sed "s#^root=[^ ]*#root=$DEVICE#"`"
+ ## Get versions in /lib/modules
+ mnt=$(mktemp -dp .)
+ mount $DEVICE $mnt
+ versions=$(ls -r1 $mnt/lib/modules)
+ umount $mnt
+ ## Mount /boot for kernels and initrds
+ mount $LBOOT $mnt
prepare_boot_cache=
boot_device_id=
is_top_level=true
title_correction_code=
OS="${LONGNAME}"
- for LINUX in ${LINUXPROBED} ; do
- LROOT="`echo ${LINUX} | cut -d ':' -f 1`"
- LBOOT="`echo ${LINUX} | cut -d ':' -f 2`"
- LLABEL="`echo ${LINUX} | cut -d ':' -f 3 | tr '^' ' '`"
- LKERNEL="`echo ${LINUX} | cut -d ':' -f 4`"
- LINITRD="`echo ${LINUX} | cut -d ':' -f 5`"
- LPARAMS="`echo ${LINUX} | cut -d ':' -f 6- | tr '^' ' '`"
+ for version in $versions; do
+ LLABEL="$label $version"
+ [ -f $mnt/vmlinuz*$version ] || continue
+ LKERNEL=/boot/$(cd $mnt && find vmlinuz*$version 2>/dev/null |head -1)
+ [ "x$LKERNEL" = "x" ] && continue
+ echo "Found kernel $LKERNEL" >&2
+ LINITRD=/boot/$(cd $mnt && find initrd*$version 2>/dev/null |head -1)
+ [ x"$LINITRD" = "x" ] || echo "Found initrd $LINITRD" >&2
if [ -z "${LLABEL}" ] ; then
LLABEL="${LONGNAME}"
fi
- if [ "${LROOT}" != "${LBOOT}" ]; then
- LKERNEL="${LKERNEL#/boot}"
- LINITRD="${LINITRD#/boot}"
- fi
-
- if [ -z "${prepare_boot_cache}" ]; then
- prepare_boot_cache="$(prepare_grub_to_access_device ${LBOOT} | grub_add_tab)"
- [ "${prepare_boot_cache}" ] || continue
- fi
-
- found_other_os=1
- onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
- recovery_params="$(echo "${LPARAMS}" | grep 'single\|recovery')" || true
- 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'"
+ if [ "${LROOT}" != "${LBOOT}" ]; then
+ LKERNEL="${LKERNEL#/boot}"
+ LINITRD="${LINITRD#/boot}"
+ fi
+
+ if [ -z "${prepare_boot_cache}" ]; then
+ prepare_boot_cache="$(prepare_grub_to_access_device ${LBOOT} | grub_add_tab)"
+ [ "${prepare_boot_cache}" ] || continue
+ fi
+
+ found_other_os=1
+ onstr="$(gettext_printf "(on %s)" "${DEVICE}")"
+ recovery_params="$(echo "${LPARAMS}" | grep 'single\|recovery')" || true
+ 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'"
- if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
+ if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then
cat << EOF
menuentry '$(echo "$OS $onstr" | grub_quote)' --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux-simple-$boot_device_id' {
EOF
- save_default_entry | grub_add_tab
- printf '%s\n' "${prepare_boot_cache}"
- cat << EOF
- linux ${LKERNEL} ${LPARAMS}
+ save_default_entry | grub_add_tab
+ printf '%s\n' "${prepare_boot_cache}"
+ cat << EOF
+ linux ${LKERNEL} ${LPARAMS}
EOF
if [ -n "${LINITRD}" ] ; then
cat << EOF
- initrd ${LINITRD}
+ initrd ${LINITRD}
EOF
fi
cat << EOF
}
EOF
- echo "submenu '$(gettext_printf "Advanced options for %s" "${OS} $onstr" | grub_quote)' \$menuentry_id_option 'osprober-gnulinux-advanced-$boot_device_id' {"
- is_top_level=false
- fi
- title="${LLABEL} $onstr"
+ echo "submenu '$(gettext_printf "Advanced options for %s" "${OS} $onstr" | grub_quote)' \$menuentry_id_option 'osprober-gnulinux-advanced-$boot_device_id' {"
+ is_top_level=false
+ fi
+ title="${LLABEL} $onstr"
cat << EOF
- menuentry '$(echo "$title" | grub_quote)' --class gnu-linux --class gnu --class os \$menuentry_id_option 'osprober-gnulinux-$LKERNEL-${recovery_params}-$boot_device_id' {
+ menuentry '$(echo "$title" | grub_quote)' --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/^/$grub_tab$grub_tab/"
- printf '%s\n' "${prepare_boot_cache}" | grub_add_tab
- cat << EOF
- linux ${LKERNEL} ${LPARAMS}
+ save_default_entry | sed -e "s/^/$grub_tab$grub_tab/"
+ printf '%s\n' "${prepare_boot_cache}" | grub_add_tab
+ cat << EOF
+ linux ${LKERNEL} ${LPARAMS}
EOF
if [ -n "${LINITRD}" ] ; then
cat << EOF
- initrd ${LINITRD}
+ initrd ${LINITRD}
EOF
fi
cat << EOF
- }
+ }
EOF
- if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
- replacement_title="$(echo "Advanced options for ${OS} $onstr" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
- quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
- title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;"
- grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")"
- fi
+ if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then
+ replacement_title="$(echo "Advanced options for ${OS} $onstr" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')"
+ quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)"
+ title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;"
+ grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")"
+ fi
done
if [ x"$is_top_level" != xtrue ]; then
- echo '}'
+ echo '}'
fi
echo "$title_correction_code"
+ umount $mnt
+ rmdir $mnt
;;
macosx)
if [ "${UUID}" ]; then
- OSXUUID="${UUID}"
- osx_entry xnu_kernel 32
- osx_entry xnu_kernel64 64
+ OSXUUID="${UUID}"
+ osx_entry xnu_kernel 32
+ osx_entry xnu_kernel64 64
fi
;;
hurd)
@@ -334,29 +349,29 @@
mach_device="`echo "${grub_device}" | sed -e 's/(\(hd.*\),msdos\(.*\))/\1s\2/'`"
grub_fs="`${grub_probe} --device ${DEVICE} --target=fs`"
case "${grub_fs}" in
- *fs) hurd_fs="${grub_fs}" ;;
- *) hurd_fs="${grub_fs}fs" ;;
+ *fs) hurd_fs="${grub_fs}" ;;
+ *) hurd_fs="${grub_fs}fs" ;;
esac
cat << EOF
- multiboot /boot/gnumach.gz root=device:${mach_device}
- module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\
- --multiboot-command-line='\${kernel-command-line}' \\
- --host-priv-port='\${host-port}' \\
- --device-master-port='\${device-port}' \\
- --exec-server-task='\${exec-task}' -T typed '\${root}' \\
- '\$(task-create)' '\$(task-resume)'
- module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)'
+ multiboot /boot/gnumach.gz root=device:${mach_device}
+ module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\
+ --multiboot-command-line='\${kernel-command-line}' \\
+ --host-priv-port='\${host-port}' \\
+ --device-master-port='\${device-port}' \\
+ --exec-server-task='\${exec-task}' -T typed '\${root}' \\
+ '\$(task-create)' '\$(task-resume)'
+ module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)'
}
EOF
;;
minix)
- cat << EOF
+ cat << EOF
menuentry "${LONGNAME} (on ${DEVICE}, Multiboot)" {
EOF
save_default_entry | sed -e "s/^/\t/"
prepare_grub_to_access_device ${DEVICE} | sed -e "s/^/\t/"
- cat << EOF
- multiboot /boot/image_latest
+ cat << EOF
+ multiboot /boot/image_latest
}
EOF
;;

Patch grub-mkconfig files 10_linux and 30_os-prober in /etc/grub.d

grub-mkconfig is part of the package grub-common and is called by update-grub

Usage

GITDIR=$HOME/git/grub-mkconfig  ## the location of this repo

Apply patches

cd /etc/grub.d
# patch options: -N only normal direction (-R only reverse); -b backup; -r - no rejects file
cat $GITDIR/*.patch |sudo patch -N -b -r -
# deactivate the resulting .orig file(s)
sudo chmod -x *.orig

Make patches

10_linux.new and 30_os-prober.new are the correct/patched files

cd $GITDIR
diff -u 10_linux 10_linux.new >10_linux.patch
diff -u 30_os-prober 30_os-prober.new >30_os-prober.patch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment