From: Denton Liu <liu.denton@gmail.com>
To: grub-devel@gnu.org
Cc: Daniel Kiper <daniel.kiper@oracle.com>,
Oskari Pirhonen <xxc3ncoredxx@gmail.com>,
mathieu.desnoyers@efficios.com, rharwood@redhat.com,
samuel.thibault@ens-lyon.org, debian-bsd@lists.debian.org,
xen-devel@lists.xenproject.org, Olaf Hering <olaf@aepfle.de>
Subject: [PATCH v5] templates: introduce GRUB_TOP_LEVEL_* vars
Date: Mon, 24 Oct 2022 03:46:42 -0700 [thread overview]
Message-ID: <20221024104642.251016-1-liu.denton@gmail.com> (raw)
A user may wish to use an image that is not sorted as the "latest"
version as the top-level entry. For example, in Arch Linux, if a user
has the LTS and regular kernels installed, `/boot/vmlinuz-linux-lts`
gets sorted as the "latest" compared to `/boot/vmlinuz-linux`, meaning
the LTS kernel becomes the top-level entry. However, a user may wish to
use the regular kernel as the top-level default with the LTS only
existing as a backup.
This need can be seen in Arch Linux's AUR with two user-submitted
packages[0][1] providing an update hook which patches
/etc/grub.d/10_linux to move the desired kernel to the top-level. This
patch serves to solve this in a more generic way.
Introduce the GRUB_TOP_LEVEL, GRUB_TOP_LEVEL_XEN and
GRUB_TOP_LEVEL_OS_PROBER variables to allow users to specify the
top-level entry.
Create grub_move_to_front() as a helper function which moves entries to
the front of a list. This function does the heavy lifting of moving
the menu entry to the front in each script.
In 10_netbsd, since there isn't an explicit list variable, extract the
items that are being iterated through into a list so that we can
optionally apply grub_move_to_front() to the list before the loop.
[0]: https://aur.archlinux.org/packages/grub-linux-default-hook
[1]: https://aur.archlinux.org/packages/grub-linux-rt-default-hook
Signed-off-by: Denton Liu <liu.denton@gmail.com>
---
Notes:
The only file that was tested is 10_linux. I do not have access to any
of the other images or systems so they remain untested.
Changes since v4:
* Update docs to specify that GRUB_TOP_LEVEL and GRUB_TOP_LEVEL_XEN take
an absolute path
* Add more justification in the commit message
Changes since v3:
* Fix if formatting nit
* Rebase on top of latest 'master'
Changes since v2:
* Added more detail to GRUB_TOP_LEVEL docs
* Moved GRUB_TOP_LEVEL_OS_PROBER to separate section in docs
* Renamed grub_move_entry_to_front() to grub_move_to_front() and added
code comment
* Give 10_netbsd an intermediate list of images to interact with
Range-diff against v4:
1: d3a693804 ! 1: ee633189b templates: introduce GRUB_TOP_LEVEL_* vars
@@ Commit message
A user may wish to use an image that is not sorted as the "latest"
version as the top-level entry. For example, in Arch Linux, if a user
has the LTS and regular kernels installed, `/boot/vmlinuz-linux-lts`
- gets sorted as the "latest" compared to `/boot/vmlinuz-linux`. However,
- a user may wish to use the regular kernel as the default with the LTS
- only existing as a backup.
+ gets sorted as the "latest" compared to `/boot/vmlinuz-linux`, meaning
+ the LTS kernel becomes the top-level entry. However, a user may wish to
+ use the regular kernel as the top-level default with the LTS only
+ existing as a backup.
+
+ This need can be seen in Arch Linux's AUR with two user-submitted
+ packages[0][1] providing an update hook which patches
+ /etc/grub.d/10_linux to move the desired kernel to the top-level. This
+ patch serves to solve this in a more generic way.
Introduce the GRUB_TOP_LEVEL, GRUB_TOP_LEVEL_XEN and
GRUB_TOP_LEVEL_OS_PROBER variables to allow users to specify the
@@ Commit message
items that are being iterated through into a list so that we can
optionally apply grub_move_to_front() to the list before the loop.
+ [0]: https://aur.archlinux.org/packages/grub-linux-default-hook
+ [1]: https://aur.archlinux.org/packages/grub-linux-rt-default-hook
+
Signed-off-by: Denton Liu <liu.denton@gmail.com>
@@ Notes
The only file that was tested is 10_linux. I do not have access to any
of the other images or systems so they remain untested.
+ Changes since v4:
+
+ * Update docs to specify that GRUB_TOP_LEVEL and GRUB_TOP_LEVEL_XEN take
+ an absolute path
+
+ * Add more justification in the commit message
+
Changes since v3:
* Fix if formatting nit
@@ docs/grub.texi: for all respectively normal entries.
+@item GRUB_TOP_LEVEL
+@item GRUB_TOP_LEVEL_XEN
-+This option should be a path to a kernel image. If provided, the image
-+specified will be made the top-level entry if it is found in the scan.
++This option should be an absolute path to a kernel image. If provided, the
++image specified will be made the top-level entry if it is found in the scan.
+
+@item GRUB_TOP_LEVEL_OS_PROBER
+This option should be a line of output from @command{os-prober}. As
docs/grub.texi | 10 ++++++++++
util/grub-mkconfig.in | 3 +++
util/grub-mkconfig_lib.in | 26 ++++++++++++++++++++++++++
util/grub.d/10_hurd.in | 4 ++++
util/grub.d/10_kfreebsd.in | 4 ++++
util/grub.d/10_linux.in | 4 ++++
util/grub.d/10_netbsd.in | 8 +++++++-
util/grub.d/20_linux_xen.in | 7 +++++++
util/grub.d/30_os-prober.in | 4 ++++
9 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index 0dbbdc374..641fb4ad3 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -1444,6 +1444,16 @@ for all respectively normal entries.
The values of these options replace the values of @samp{GRUB_CMDLINE_LINUX}
and @samp{GRUB_CMDLINE_LINUX_DEFAULT} for Linux and Xen menu entries.
+@item GRUB_TOP_LEVEL
+@item GRUB_TOP_LEVEL_XEN
+This option should be an absolute path to a kernel image. If provided, the
+image specified will be made the top-level entry if it is found in the scan.
+
+@item GRUB_TOP_LEVEL_OS_PROBER
+This option should be a line of output from @command{os-prober}. As
+@samp{GRUB_TOP_LEVEL}, if provided, the image specified will be made the
+top-level entry if it is found in the scan.
+
@item GRUB_EARLY_INITRD_LINUX_CUSTOM
@itemx GRUB_EARLY_INITRD_LINUX_STOCK
List of space-separated early initrd images to be loaded from @samp{/boot}.
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
index 62335d027..32c480dae 100644
--- a/util/grub-mkconfig.in
+++ b/util/grub-mkconfig.in
@@ -233,6 +233,9 @@ export GRUB_DEFAULT \
GRUB_CMDLINE_NETBSD \
GRUB_CMDLINE_NETBSD_DEFAULT \
GRUB_CMDLINE_GNUMACH \
+ GRUB_TOP_LEVEL \
+ GRUB_TOP_LEVEL_XEN \
+ GRUB_TOP_LEVEL_OS_PROBER \
GRUB_EARLY_INITRD_LINUX_CUSTOM \
GRUB_EARLY_INITRD_LINUX_STOCK \
GRUB_TERMINAL_INPUT \
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
index 634bc8a50..08953287c 100644
--- a/util/grub-mkconfig_lib.in
+++ b/util/grub-mkconfig_lib.in
@@ -218,6 +218,32 @@ version_sort ()
esac
}
+# Given an item as the first argument and a list as the subsequent arguments,
+# returns the list with the first argument moved to the front if it exists in
+# the list.
+grub_move_to_front ()
+{
+ item="$1"
+ shift
+
+ item_found=false
+ for i in "$@"; do
+ if [ "x$i" = "x$item" ]; then
+ item_found=true
+ fi
+ done
+
+ if [ "x$item_found" = xtrue ]; then
+ echo "$item"
+ fi
+ for i in "$@"; do
+ if [ "x$i" = "x$item" ]; then
+ continue
+ fi
+ echo "$i"
+ done
+}
+
# One layer of quotation is eaten by "" and the second by sed; so this turns
# ' into \'.
grub_quote () {
diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in
index a021d02c2..b317a4b14 100644
--- a/util/grub.d/10_hurd.in
+++ b/util/grub.d/10_hurd.in
@@ -229,6 +229,10 @@ submenu_indentation=""
reverse_sorted_kernels=$(echo ${kernels} | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//')
+if [ "x$GRUB_TOP_LEVEL" != x ]; then
+ reverse_sorted_kernels=$(grub_move_to_front "$GRUB_TOP_LEVEL" ${reverse_sorted_kernels})
+fi
+
is_top_level=true
for kernel in ${reverse_sorted_kernels}; do
diff --git a/util/grub.d/10_kfreebsd.in b/util/grub.d/10_kfreebsd.in
index 0a67decaa..83e9636e8 100644
--- a/util/grub.d/10_kfreebsd.in
+++ b/util/grub.d/10_kfreebsd.in
@@ -164,6 +164,10 @@ submenu_indentation=""
reverse_sorted_list=$(echo ${list} | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//')
+if [ "x$GRUB_TOP_LEVEL" != x ]; then
+ reverse_sorted_list=$(grub_move_to_front "$GRUB_TOP_LEVEL" ${reverse_sorted_list})
+fi
+
is_top_level=true
for kfreebsd in ${reverse_sorted_list}; do
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
index c6a1ec935..7263f2983 100644
--- a/util/grub.d/10_linux.in
+++ b/util/grub.d/10_linux.in
@@ -202,6 +202,10 @@ submenu_indentation=""
reverse_sorted_list=$(echo $list | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//')
+if [ "x$GRUB_TOP_LEVEL" != x ]; then
+ reverse_sorted_list=$(grub_move_to_front "$GRUB_TOP_LEVEL" ${reverse_sorted_list})
+fi
+
is_top_level=true
for linux in ${reverse_sorted_list}; do
gettext_printf "Found linux image: %s\n" "$linux" >&2
diff --git a/util/grub.d/10_netbsd.in b/util/grub.d/10_netbsd.in
index dc0cd1b17..3154e9e15 100644
--- a/util/grub.d/10_netbsd.in
+++ b/util/grub.d/10_netbsd.in
@@ -146,8 +146,14 @@ pattern="^ELF[^,]*executable.*statically linked"
# yet, so it's empty. In a submenu it will be equal to '\t' (one tab).
submenu_indentation=""
+list="/netbsd $(ls -t /netbsd?* 2>/dev/null)"
+
+if [ "x$GRUB_TOP_LEVEL" != x ]; then
+ list=$(grub_move_to_front "$GRUB_TOP_LEVEL" ${list})
+fi
+
is_top_level=true
-for k in /netbsd $(ls -t /netbsd?* 2>/dev/null) ; do
+for k in ${list}; do
if ! grub_file_is_not_garbage "$k" ; then
continue
fi
diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in
index 626aed40c..386bfb9be 100644
--- a/util/grub.d/20_linux_xen.in
+++ b/util/grub.d/20_linux_xen.in
@@ -245,6 +245,13 @@ submenu_indentation=""
reverse_sorted_xen_list=$(echo ${xen_list} | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//')
reverse_sorted_linux_list=$(echo ${linux_list} | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//')
+if [ "x$GRUB_TOP_LEVEL_XEN" != x ]; then
+ reverse_sorted_xen_list=$(grub_move_to_front "$GRUB_TOP_LEVEL_XEN" ${reverse_sorted_xen_list})
+fi
+if [ "x$GRUB_TOP_LEVEL" != x ]; then
+ reverse_sorted_linux_list=$(grub_move_to_front "$GRUB_TOP_LEVEL" ${reverse_sorted_linux_list})
+fi
+
is_top_level=true
for current_xen in ${reverse_sorted_xen_list}; do
diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in
index daa603778..656301eaf 100644
--- a/util/grub.d/30_os-prober.in
+++ b/util/grub.d/30_os-prober.in
@@ -113,6 +113,10 @@ EOF
used_osprober_linux_ids=
+if [ "x$GRUB_TOP_LEVEL_OS_PROBER" != x ]; then
+ OSPROBED=$(grub_move_to_front "$GRUB_TOP_LEVEL_OS_PROBER" ${OSPROBED})
+fi
+
for OS in ${OSPROBED} ; do
DEVICE="`echo ${OS} | cut -d ':' -f 1`"
LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`"
--
2.38.1
next reply other threads:[~2022-10-24 10:47 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-24 10:46 Denton Liu [this message]
2022-10-25 3:21 ` [PATCH v5] templates: introduce GRUB_TOP_LEVEL_* vars Oskari Pirhonen
2022-11-03 16:39 ` Daniel Kiper
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221024104642.251016-1-liu.denton@gmail.com \
--to=liu.denton@gmail.com \
--cc=daniel.kiper@oracle.com \
--cc=debian-bsd@lists.debian.org \
--cc=grub-devel@gnu.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=olaf@aepfle.de \
--cc=rharwood@redhat.com \
--cc=samuel.thibault@ens-lyon.org \
--cc=xen-devel@lists.xenproject.org \
--cc=xxc3ncoredxx@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.