Bug#1087359: grub-mkconfig_lib's version_sort doesn't just sort by version
AP
debian at inml.grue.cc
Tue Nov 12 01:17:15 GMT 2024
Source: grub
Version: 0.97-80
Severity: normal
Tags: patch
Dear Maintainer,
*** Reporter, please consider answering these questions, where appropriate ***
* What led up to the situation?
Finding that my kernel-* symlinks for kernels in the past weren't being put
in their proper place. Primarily the one that is meant to be the default.
* What exactly did you do (or not do) that was effective (or
ineffective)?
I tried using vmlinuz-* symlinks with high enough version numbers to sort
appropriately.
* What was the outcome of this action?
update-initramfs finds them and tries to build their initrd.img files and tends to fail.
* What outcome did you expect instead?
Them to be ignored and everything to go smoothly. Instead update-initramfs considers
the symlinks to be kernels that require initrd.img rebuild.
*** End of the template - remove these template lines ***
Whilst update-initramfs can probably be "fixed" to deal with this by ignoring symlinks
another solution came to mind when I looked into grub's scripts in greater depth.
/etc/grub.d/10_linux gathers linux kernels according to "/boot/vmlinuz-* /boot/vmlinux-*
/vmlinuz-* /vmlinux-* /boot/kernel-*". This is great and what I wanted to utilise BUT
it appears that /usr/lib/grub/grub-mkconfig_lib's version_sort sorts by, effectively,
alphanumeric-version which means that each prefix gets its own version sort and then
they are all put together according to the result of an alphanumeric sorts.
Thus you get this:
$ ls /boot/kernel-* /boot/vmlinuz-* | sort -V
/boot/kernel-99.97.99-test
/boot/kernel-99.99.97-ancient
/boot/kernel-99.99.98-old
/boot/kernel-99.99.99-current
/boot/vmlinuz-6.1.0-26-amd64
/boot/vmlinuz-6.7.0-local.20240108-141500
/boot/vmlinuz-6.8.7-local.20240427-110130
/boot/vmlinuz-6.9.2-local.20240526-193145
/boot/vmlinuz-6.10.0-local.20240715-224153
/boot/vmlinuz-6.10.2-local.20240731-010223
/boot/vmlinuz-6.10.9-local.20240909-171114
/boot/vmlinuz-6.10.11+bpo-amd64
/boot/vmlinuz-6.10.14-local.20241021-023441
/boot/vmlinuz-6.11.0-local.20240926-141105
/boot/vmlinuz-6.11.0-local.20240926-150409
/boot/vmlinuz-6.11.1-local.20241003-204800
/boot/vmlinuz-6.11.2-local.20241008-004432
/boot/vmlinuz-6.11.4-local.20241018-163800
This means the reverse sort of the list that is used to get the menu winds up getting
/boot/vmlinuz-6.11.4-local.20241018-163800 as the default member and not /boot/kernel-99.99.99-current.
The solution here would be to use the fields feature of sort so then you'd get the
kernel list being:
$ ls /boot/kernel-* /boot/vmlinuz-* | sort -V -t - -k 2
/boot/vmlinuz-6.1.0-26-amd64
/boot/vmlinuz-6.7.0-local.20240108-141500
/boot/vmlinuz-6.8.7-local.20240427-110130
/boot/vmlinuz-6.9.2-local.20240526-193145
/boot/vmlinuz-6.10.0-local.20240715-224153
/boot/vmlinuz-6.10.2-local.20240731-010223
/boot/vmlinuz-6.10.9-local.20240909-171114
/boot/vmlinuz-6.10.11+bpo-amd64
/boot/vmlinuz-6.10.14-local.20241021-023441
/boot/vmlinuz-6.11.0-local.20240926-141105
/boot/vmlinuz-6.11.0-local.20240926-150409
/boot/vmlinuz-6.11.1-local.20241003-204800
/boot/vmlinuz-6.11.2-local.20241008-004432
/boot/vmlinuz-6.11.4-local.20241018-163800
/boot/kernel-99.97.99-test
/boot/kernel-99.99.97-ancient
/boot/kernel-99.99.98-old
/boot/kernel-99.99.99-current
This results in the kernels being purely sorted by version and, so, the reverse sort
gets /boot/kernel-99.99.99-current on top as is wanted and THAT becomes the default
menu item.
Hope this makes sense :)
Patch below.
--- grub-mkconfig_lib.old 2024-11-12 12:01:03.394026357 +1100
+++ grub-mkconfig_lib 2024-11-12 12:09:35.611560029 +1100
@@ -226,18 +226,34 @@
version_sort ()
{
- case $version_sort_sort_has_v in
- yes)
+ case $version_sort_sort_has_v.$version_sort_sort_has_tk in
+ yes.yes)
+ LC_ALL=C sort -V -t - -k 2 "$@";;
+ yes.no)
LC_ALL=C sort -V "$@";;
- no)
+ no.yes)
+ LC_ALL=C sort -n -t - -k 2 "$@";;
+ no.no)
LC_ALL=C sort -n "$@";;
*)
if sort -V </dev/null > /dev/null 2>&1; then
version_sort_sort_has_v=yes
- LC_ALL=C sort -V "$@"
+ if sort -V -t 1 -k 2 </dev/null > /dev/null 2>&1; then
+ version_sort_sort_has_tk=yes
+ LC_ALL=C sort -V -t - -k 2 "$@"
+ else
+ version_sort_sort_has_tk=no
+ LC_ALL=C sort -V "$@"
+ fi
else
version_sort_sort_has_v=no
- LC_ALL=C sort -n "$@"
+ if sort -n -t 1 -k 2 </dev/null > /dev/null 2>&1; then
+ version_sort_sort_has_tk=yes
+ LC_ALL=C sort -n -t - -k 2 "$@"
+ else
+ version_sort_sort_has_tk=no
+ LC_ALL=C sort -n "$@"
+ fi
fi;;
esac
}
-- System Information:
Debian Release: 12.7
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 'stable')
Architecture: amd64 (x86_64)
Kernel: Linux 6.11.1-local.20241001-142734 (SMP w/2 CPU threads)
Locale: LANG=en_AU.UTF-8, LC_CTYPE=en_AU.UTF-8 (charmap=UTF-8), LANGUAGE=en_AU:en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
More information about the Pkg-grub-devel
mailing list