SlackwareThis Forum is for the discussion of Slackware Linux.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Nobody here complain about not able to boot, login, or whatever else after a Slackware-current upgrade?
+
Quote:
Originally Posted by volkerdi
I'm not terribly surprised, since it won't even compile as released. There was no way it was going anywhere other than /testing... if it doesn't even build, what other bugs were included?
Anyway, from my point of view, if something is automated during an upgrade (via doinst.sh), the rollback (downgrade) must also be the same way. No matter the reason
During my grub test, I noticed that grub-mkconfig was reporting errors.
As I know how to do a chroot, I chose to reboot anyway
But, after noticing these errors, if I don't know how to deal with chroot, I could also have chosen to reinstall the previous version, which would have led to a non-bootable computer anyway
If the upgrade of a specific package is the culprit, the downgrade must be the first solution, not chroot
Side note:
It could be interesting to have something similar to arch-chroot on the ISO ;-)
Code:
mount $ROOT_PART /mnt
mount -t devtmpfs /dev /mnt/dev
mount -t devpts /dev/pts /mnt/dev/pts
mount -t sysfs /sys /mnt/sys
mount -t proc /proc /mnt/proc
chroot /mnt
Anyway, from my point of view, if something is automated during an upgrade (via doinst.sh), the rollback (downgrade) must also be the same way. No matter the reason
You probably won't need to worry about that
Quote:
Side note:
It could be interesting to have something similar to arch-chroot on the ISO ;-)
Code:
mount $ROOT_PART /mnt
mount -t devtmpfs /dev /mnt/dev
mount -t devpts /dev/pts /mnt/dev/pts
mount -t sysfs /sys /mnt/sys
mount -t proc /proc /mnt/proc
chroot /mnt
Yes, but the script would need to ask the user which is the root partition and the options needed to mount it. For instance here and now that would be:
Code:
mount /dev/sda5 /mnt -o subvol=/@
that a script can't guess AFAIK. Also some more commands can be needed once in the chroot, like "mount /boot/efi" and "mount -t efivarfs none /sys/firmware/efi/efivars" before running grub-install in EFI mode.
Yes, but the script would need to ask the user which is the root partition and the options needed to mount it. For instance here and now that would be:
Code:
mount /dev/sda5 /mnt -o subvol=/@
that a script can't guess AFAIK. Also some more commands can be needed once in the chroot, like "mount /boot/efi" and "mount -t efivarfs none /sys/firmware/efi/efivars" before running grub-install in EFI mode.
In the case of the mkbindmounts script on the installer, *you* need to mount the partition on /mnt however that needs to be done. The script adds the usually-needed bind mounts for you. Then you can chroot into it. If you need to add other mounts (such as for /boot/efi) that's on you.
efivarfs is always mounted on EFI systems in -current now, so that shouldn't be an issue moving forward.
All done and exited from the chroot? Then you need umount -R /mnt to unmount everything.
So far 2.12 working well for me on both an MBR install and an UEFI install. However, both of these computers are basic setups: ext4 fs, early microcode enabled, and generic kernel using an initramfs.
I did reinstall via a grub-install on both systems.
I had to delete the .orig files to prevent double grub menu entries, but it looks like that is resolved in the 2nd build of it.
linux=$(echo "$mylist" | version_sort -r | head -n 1)
Thanks ;-)
Today I needed to test something on Slackware 15.0 (32bit) and I got an error with the 09_slackware_linux script I tweaked to fix the deprecation warnings with 2.12. It works fine in 64bit, but was throwing errors in 32bit Slackware. Anyway I was annoyed enough where I went back and did a couple of things to the script, specifically the process_list function. Basically I wanted three things, get rid of the deprecated warnings with 2.12, fix the 32bit error, and prioritize the smp kernels first in the grub menu. With a little help from stackoverflow and chatGPT I got it working the way I want, but I thought I would post it here since even though I consider myself competent in bash I am no guru. I have zero ego on this so if you guys see something that is not right, could be done better, ugly, or just pain wrong please point it out so I can make the script better.
Code:
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
#
# Save this file in /etc/grub.d/09_slackware_linux
prefix="/usr"
exec_prefix="${prefix}"
datarootdir="${prefix}/share"
. "${datarootdir}/grub/grub-mkconfig_lib"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
CLASS="--class gnu-linux --class gnu --class os"
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
OS=GNU/Linux
else
OS="${GRUB_DISTRIBUTOR} GNU/Linux"
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]') ${CLASS}"
fi
# loop-AES arranges things so that /dev/loop/X can be our root device, but
# the initrds that Linux uses don't like that.
case ${GRUB_DEVICE} in
/dev/loop/*|/dev/loop[0-9])
GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
;;
esac
if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
|| ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
else
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
fi
linux_entry ()
{
os="$1"
tag="$2"
version="$3"
recovery="$4"
args="$5"
if ${recovery} ; then
title="$(gettext "%s, with Linux %s [%s] (recovery mode)")"
else
title="$(gettext "%s, with Linux %s [%s]")"
fi
printf "menuentry \"${title}\" ${CLASS} {\n" "${os}" "${version}" "${tag}"
save_default_entry | sed -e "s/^/\t/"
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then
if grep -qx "CONFIG_FB_EFI=y" /boot/config-${version} 2> /dev/null \
&& grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" /boot/config-${version} 2> /dev/null; then
cat << EOF
set gfxpayload=keep
EOF
fi
else
cat << EOF
set gfxpayload=$GRUB_GFXPAYLOAD_LINUX
EOF
fi
if [ -z "${prepare_boot_cache}" ]; then
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")"
fi
printf '%s\n' "${prepare_boot_cache}"
cat << EOF
echo $(printf "$(gettext "Loading Linux %s ...")" ${version})
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
EOF
if test -n "${initrd}" ; then
cat << EOF
echo $(gettext "Loading initial ramdisk ...")
initrd ${rel_dirname}/${initrd}
EOF
fi
cat << EOF
}
EOF
}
process_list ()
{
mylist="$1"
tag="$2"
initrd_allowed="$3"
IFS=' ' read -r -a kernels <<< "$mylist"
# Separate SMP and non-SMP kernels
smp_kernels=()
non_smp_kernels=()
for kernel in "${kernels[@]}"; do
basename=$(basename "$kernel")
if [[ $basename == *"-smp"* ]]; then
smp_kernels+=("$kernel")
else
non_smp_kernels+=("$kernel")
fi
done
# Combine SMP kernels first, followed by non-SMP kernels
sorted_kernels=("${smp_kernels[@]}" "${non_smp_kernels[@]}")
for kernel in "${sorted_kernels[@]}"; do
# Skip symbolic links
if [ -L "$kernel" ]; then
continue
fi
echo "Found linux image: $kernel" >&2
basename=$(basename "$kernel")
dirname=$(dirname "$kernel")
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")
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
initrd=
if [ "x${initrd_allowed}" = "xtrue" ]; then
for i in "initrd-${version}.gz" "initrd.gz" \
"initrd.img-${version}" "initrd-${version}.img" \
"initrd-${version}" "initrd.img-${alt_version}" \
"initrd-${alt_version}.img" "initrd-${alt_version}"; do
if test -e "${dirname}/${i}" ; then
initrd="$i"
break
fi
done
if test -n "${initrd}" ; then
echo "Found initrd image: ${dirname}/${initrd}" >&2
else
# "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here.
linux_root_device_thisversion=${GRUB_DEVICE}
fi
else
# "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here.
linux_root_device_thisversion=${GRUB_DEVICE}
fi
linux_entry "${OS}" "${tag}" "${version}" false \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
linux_entry "${OS}" "${tag}" "${version}" true \
"single ${GRUB_CMDLINE_LINUX}"
fi
done
}
prepare_boot_cache=
list=`for i in /boot/vmlinu[xz]-generic-* /vmlinu[xz]-generic-* ; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
process_list "${list}" "generic" "true"
list=`for i in /boot/vmlinu[xz]-custom-* /vmlinu[xz]-custom-* ; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
process_list "${list}" "custom" "true"
list=`for i in /boot/vmlinu[xz]-huge-* /vmlinu[xz]-huge-* ; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
process_list "${list}" "huge" "false"
EDIT: The only thing I am thinking I may have forgot is to priortize new kernels first if multiple kernels are installed. Working on that now...
Ok last time I am going to spam the screen with the full code, but I added version_sort to sort the kernels with newest first.
Code:
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
#
# Save this file in /etc/grub.d/09_slackware_linux
prefix="/usr"
exec_prefix="${prefix}"
datarootdir="${prefix}/share"
. "${datarootdir}/grub/grub-mkconfig_lib"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
CLASS="--class gnu-linux --class gnu --class os"
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
OS=GNU/Linux
else
OS="${GRUB_DISTRIBUTOR} GNU/Linux"
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]') ${CLASS}"
fi
# loop-AES arranges things so that /dev/loop/X can be our root device, but
# the initrds that Linux uses don't like that.
case ${GRUB_DEVICE} in
/dev/loop/*|/dev/loop[0-9])
GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
;;
esac
if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
|| ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
else
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
fi
linux_entry ()
{
os="$1"
tag="$2"
version="$3"
recovery="$4"
args="$5"
if ${recovery} ; then
title="$(gettext "%s, with Linux %s [%s] (recovery mode)")"
else
title="$(gettext "%s, with Linux %s [%s]")"
fi
printf "menuentry "${title}" ${CLASS} {\n" "${os}" "${version}" "${tag}"
save_default_entry | sed -e "s/^/\t/"
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then
if grep -qx "CONFIG_FB_EFI=y" /boot/config-${version} 2> /dev/null \
&& grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" /boot/config-${version} 2> /dev/null; then
cat << EOF
set gfxpayload=keep
EOF
fi
else
cat << EOF
set gfxpayload=$GRUB_GFXPAYLOAD_LINUX
EOF
fi
if [ -z "${prepare_boot_cache}" ]; then
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")"
fi
printf '%s\n' "${prepare_boot_cache}"
cat << EOF
echo $(printf "$(gettext "Loading Linux %s ...")" ${version})
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
EOF
if test -n "${initrd}" ; then
cat << EOF
echo $(gettext "Loading initial ramdisk ...")
initrd ${rel_dirname}/${initrd}
EOF
fi
cat << EOF
}
EOF
}
process_list ()
{
mylist="$1"
tag="$2"
initrd_allowed="$3"
# Version-sort the kernels
sorted_kernels=$(echo "$mylist" | version_sort -r)
# Separate smp and non-smp kernels
smp_kernels=()
non_smp_kernels=()
IFS=' ' read -r -a kernels <<< "$sorted_kernels"
for kernel in "${kernels[@]}"; do
if [[ $kernel == *"smp"* ]]; then
smp_kernels+=("$kernel")
else
non_smp_kernels+=("$kernel")
fi
done
# Process smp kernels first
for kernel in "${smp_kernels[@]}"; do
process_kernel "$kernel" "$tag" "$initrd_allowed"
done
# Process non-smp kernels
for kernel in "${non_smp_kernels[@]}"; do
process_kernel "$kernel" "$tag" "$initrd_allowed"
done
}
process_kernel ()
{
kernel="$1"
tag="$2"
initrd_allowed="$3"
# Skip symbolic links
if [ -L "$kernel" ]; then
return
fi
echo "Found linux image: $kernel" >&2
basename=$(basename "$kernel")
dirname=$(dirname "$kernel")
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")
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
initrd=
if [ "x${initrd_allowed}" = "xtrue" ]; then
for i in "initrd-${version}.gz" "initrd.gz" \
"initrd.img-${version}" "initrd-${version}.img" \
"initrd-${version}" "initrd.img-${alt_version}" \
"initrd-${alt_version}.img" "initrd-${alt_version}"; do
if test -e "${dirname}/${i}" ; then
initrd="$i"
break
fi
done
if test -n "${initrd}" ; then
echo "Found initrd image: ${dirname}/${initrd}" >&2
else
# "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here.
linux_root_device_thisversion=${GRUB_DEVICE}
fi
else
# "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here.
linux_root_device_thisversion=${GRUB_DEVICE}
fi
linux_entry "${OS}" "${tag}" "${version}" false \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
linux_entry "${OS}" "${tag}" "${version}" true \
"single ${GRUB_CMDLINE_LINUX}"
fi
}
prepare_boot_cache=
list=`for i in /boot/vmlinu[xz]-generic-* /vmlinu[xz]-generic-* ; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
process_list "${list}" "generic" "true"
list=`for i in /boot/vmlinu[xz]-custom-* /vmlinu[xz]-custom-* ; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
process_list "${list}" "custom" "true"
list=`for i in /boot/vmlinu[xz]-huge-* /vmlinu[xz]-huge-* ; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
process_list "${list}" "huge" "false"
Ok last time I am going to spam the screen with the full code, but I added version_sort to sort the kernels with newest first.
Code:
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
#
# Save this file in /etc/grub.d/09_slackware_linux
prefix="/usr"
exec_prefix="${prefix}"
datarootdir="${prefix}/share"
. "${datarootdir}/grub/grub-mkconfig_lib"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
CLASS="--class gnu-linux --class gnu --class os"
if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then
OS=GNU/Linux
else
OS="${GRUB_DISTRIBUTOR} GNU/Linux"
CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr '[A-Z]' '[a-z]') ${CLASS}"
fi
# loop-AES arranges things so that /dev/loop/X can be our root device, but
# the initrds that Linux uses don't like that.
case ${GRUB_DEVICE} in
/dev/loop/*|/dev/loop[0-9])
GRUB_DEVICE=`losetup ${GRUB_DEVICE} | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/"`
;;
esac
if [ "x${GRUB_DEVICE_UUID}" = "x" ] || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
|| ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
else
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
fi
linux_entry ()
{
os="$1"
tag="$2"
version="$3"
recovery="$4"
args="$5"
if ${recovery} ; then
title="$(gettext "%s, with Linux %s [%s] (recovery mode)")"
else
title="$(gettext "%s, with Linux %s [%s]")"
fi
printf "menuentry \"${title}\" ${CLASS} {\n" "${os}" "${version}" "${tag}"
save_default_entry | sed -e "s/^/\t/"
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then
if grep -qx "CONFIG_FB_EFI=y" /boot/config-${version} 2> /dev/null \
&& grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" /boot/config-${version} 2> /dev/null; then
cat << EOF
set gfxpayload=keep
EOF
fi
else
cat << EOF
set gfxpayload=$GRUB_GFXPAYLOAD_LINUX
EOF
fi
if [ -z "${prepare_boot_cache}" ]; then
prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/")"
fi
printf '%s\n' "${prepare_boot_cache}"
cat << EOF
echo $(printf "$(gettext "Loading Linux %s ...")" ${version})
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
EOF
if test -n "${initrd}" ; then
cat << EOF
echo $(gettext "Loading initial ramdisk ...")
initrd ${rel_dirname}/${initrd}
EOF
fi
cat << EOF
}
EOF
}
process_list ()
{
mylist="$1"
tag="$2"
initrd_allowed="$3"
# Version-sort the kernels
sorted_kernels=$(echo "$mylist" | version_sort -r)
IFS=' ' read -r -a kernels <<< "$sorted_kernels"
for kernel in "${kernels[@]}"; do
# Skip symbolic links
if [ -L "$kernel" ]; then
continue
fi
echo "Found linux image: $kernel" >&2
basename=$(basename "$kernel")
dirname=$(dirname "$kernel")
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")
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
initrd=
if [ "x${initrd_allowed}" = "xtrue" ]; then
for i in "initrd-${version}.gz" "initrd.gz" \
"initrd.img-${version}" "initrd-${version}.img" \
"initrd-${version}" "initrd.img-${alt_version}" \
"initrd-${alt_version}.img" "initrd-${alt_version}"; do
if test -e "${dirname}/${i}" ; then
initrd="$i"
break
fi
done
if test -n "${initrd}" ; then
echo "Found initrd image: ${dirname}/${initrd}" >&2
else
# "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here.
linux_root_device_thisversion=${GRUB_DEVICE}
fi
else
# "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here.
linux_root_device_thisversion=${GRUB_DEVICE}
fi
linux_entry "${OS}" "${tag}" "${version}" false \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
linux_entry "${OS}" "${tag}" "${version}" true \
"single ${GRUB_CMDLINE_LINUX}"
fi
done
}
prepare_boot_cache=
list=`for i in /boot/vmlinu[xz]-generic-* /vmlinu[xz]-generic-* ; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
process_list "${list}" "generic" "true"
list=`for i in /boot/vmlinu[xz]-custom-* /vmlinu[xz]-custom-* ; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
process_list "${list}" "custom" "true"
list=`for i in /boot/vmlinu[xz]-huge-* /vmlinu[xz]-huge-* ; do
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
done`
process_list "${list}" "huge" "false"
IMHO all files in /etc/grub.d should be POSIX compliant as run by grub-mkconfig which is itself a POSIX compliant script but this one has a few bashisms. Excerpts of the outing of "shellcheck 09_slackware_linux":
Code:
In 09_slackware_linux line 112:
IFS=' ' read -r -a kernels <<< "$sorted_kernels"
^-- SC2039: In POSIX sh, read -a is undefined.
^-^ SC2039: In POSIX sh, here-strings are undefined.
In 09_slackware_linux line 114:
for kernel in "${kernels[@]}"; do
^-----------^ SC2039: In POSIX sh, array references are undefined.
In 09_slackware_linux line 161:
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
^-- SC2039: In POSIX sh, echo flags are undefined.
In 09_slackware_linux line 167:
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
^-- SC2039: In POSIX sh, echo flags are undefined.
In 09_slackware_linux line 172:
if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi
^-- SC2039: In POSIX sh, echo flags are undefined.
Last edited by Didier Spaier; 01-13-2024 at 04:02 PM.
Reason: rewording
EDIT: It also seems I forgot to add back logic to prioritize SMP kernels first in 32bit. But I am thinking why bother since that is going to be a thing of the past now that Pat has dropped the -smp label.
Thanks again Didier, I went back and got the script POSIX compliant and tested it with 32/64 15.0 and current. It now works without errors or deprecation warnings. I think it is in a good place.
Code:
#! /bin/sh
set -e
# grub-mkconfig helper script.
# Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
#
# Save this file in /etc/grub.d/09_slackware_linux
prefix="/usr"
exec_prefix="${prefix}"
datarootdir="${prefix}/share"
. "${datarootdir}/grub/grub-mkconfig_lib"
export TEXTDOMAIN=grub
export TEXTDOMAINDIR="${datarootdir}/locale"
CLASS="--class gnu-linux --class gnu --class os"
if [ "${GRUB_DISTRIBUTOR}" = "" ] ; then
OS=GNU/Linux
else
OS="${GRUB_DISTRIBUTOR} GNU/Linux"
CLASS="--class $(echo "${GRUB_DISTRIBUTOR}" | tr '[:upper:]' '[:lower:]') ${CLASS}"
fi
# loop-AES arranges things so that /dev/loop/X can be our root device, but
# the initrds that Linux uses don't like that.
case ${GRUB_DEVICE} in
/dev/loop/*|/dev/loop[0-9])
GRUB_DEVICE=$(losetup "${GRUB_DEVICE}" | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/")
;;
esac
if [ "${GRUB_DEVICE_UUID}" = "" ] || [ "${GRUB_DISABLE_LINUX_UUID}" = "true" ] \
|| ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ; then
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
else
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
fi
linux_entry ()
{
os="$1"
tag="$2"
version="$3"
recovery="$4"
args="$5"
if ${recovery} ; then
title="$(gettext "%s, with Linux %s [%s] (recovery mode)")"
else
title="$(gettext "%s, with Linux %s [%s]")"
fi
printf "menuentry \"${title}\" ${CLASS} {\n" "${os}" "${version}" "${tag}"
save_default_entry | sed -e "s/^/\t/"
# Use ELILO's generic "efifb" when it's known to be available.
# FIXME: We need an interface to select vesafb in case efifb can't be used.
if [ "$GRUB_GFXPAYLOAD_LINUX" = "" ]; then
if grep -qx "CONFIG_FB_EFI=y" /boot/config-"${version}" 2> /dev/null \
&& grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" /boot/config-"${version}" 2> /dev/null; then
cat << EOF
set gfxpayload=keep
EOF
fi
else
cat << EOF
set gfxpayload=$GRUB_GFXPAYLOAD_LINUX
EOF
fi
if [ -z "${prepare_boot_cache}" ]; then
prepare_boot_cache="$(prepare_grub_to_access_device "${GRUB_DEVICE_BOOT}" | sed -e "s/^/\t/")"
fi
printf '%s\n' "${prepare_boot_cache}"
cat << EOF
echo $(printf "$(gettext "Loading Linux %s ...")" "${version}")
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
EOF
if test -n "${initrd}" ; then
cat << EOF
echo $(gettext "Loading initial ramdisk ...")
initrd ${rel_dirname}/${initrd}
EOF
fi
cat << EOF
}
EOF
}
process_list() {
mylist="$1"
tag="$2"
initrd_allowed="$3"
# Version-sort the kernels
sorted_kernels=$(echo "$mylist" | version_sort -r)
# Use portable command substitution
kernels=$(echo "$sorted_kernels" | tr ' ' '\n')
for kernel in $kernels; do
# Skip symbolic links
if [ -L "$kernel" ]; then
continue
fi
printf "Found linux image: %s\n" "$kernel" >&2
basename=$(basename "$kernel")
dirname=$(dirname "$kernel")
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")
linux_root_device_thisversion="${LINUX_ROOT_DEVICE}"
initrd=
if [ "${initrd_allowed}" = "true" ]; then
for i in "initrd-${version}.gz" "initrd.gz" \
"initrd.img-${version}" "initrd-${version}.img" \
"initrd-${version}" "initrd.img-${alt_version}" \
"initrd-${alt_version}.img" "initrd-${alt_version}"; do
if [ -e "${dirname}/${i}" ]; then
initrd="$i"
break
fi
done
if [ -n "${initrd}" ]; then
printf "Found initrd image: %s/%s\n" "${dirname}" "${initrd}" >&2
else
# "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here.
linux_root_device_thisversion=${GRUB_DEVICE}
fi
else
# "UUID=" magic is parsed by initrds. Since there's no initrd, it can't work here.
linux_root_device_thisversion=${GRUB_DEVICE}
fi
linux_entry "${OS}" "${tag}" "${version}" false \
"${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then
linux_entry "${OS}" "${tag}" "${version}" true \
"single ${GRUB_CMDLINE_LINUX}"
fi
done
}
prepare_boot_cache=
list=$(for i in /boot/vmlinu[xz]-generic-* /vmlinu[xz]-generic-* ; do
if grub_file_is_not_garbage "$i" ; then printf "%s " "$i"; fi
done)
process_list "${list}" "generic" "true"
list=$(for i in /boot/vmlinu[xz]-custom-* /vmlinu[xz]-custom-* ; do
if grub_file_is_not_garbage "$i" ; then printf "%s " "$i"; fi
done)
process_list "${list}" "custom" "true"
list=$(for i in /boot/vmlinu[xz]-huge-* /vmlinu[xz]-huge-* ; do
if grub_file_is_not_garbage "$i" ; then printf "%s " "$i"; fi
done)
process_list "${list}" "huge" "false"
Thanks again Didier, I went back and got the script POSIX compliant and tested it with 32/64 15.0 and current. It now works without errors or deprecation warnings. I think it is in a good place.
Well, I have tried it in a Slackware64-current in a Qemu VM, with lilo as boot loader.
<digression>As I had setup a gpt without efi, at first grub refused to work. No big deal, I shut down the system, did a "qemu-img resize +2G", restarted the VM, added a BIOSBoot partition, which made grub-mkconfig happy. Then I rebooted and got the grub menus grub-1.1.png (main) and grub-1.2.png (advanced options). I had kernel huge and generic 6.1.62.</digression>
After that I updated the system using slackpkg and ran geninitrd, not running grub-mkconfig at first. The grub menu did not change, but as the kernel 6.1.62 had been replaced by 6.6.11 as you can see in boot.txt which is the output "ls -1 /boot". As expected all the boot entries mentioning the kernel version were ineffective.
I rebooted, then ran grub-mkconfig again. This time of course all boot entries worked (see grub2.1 and grub2.2).
Opinion
Yes we have a safety net after a kernel upgrade with the symlinks in case the user:
uses slackpkg-upgrade to upgrade the kernel instead of just installing the new one
forget to run geninitrd
forget to run grub-mkconfig
This is a good thing as this forum is full of post like "I can't reboot" for one or several of these reasons.
But this is at the price of grub menus cluttered with redundant boot entries, of which not all are effective. Maybe acceptable for sighted users, but not nice for my blind "customers"
Conclusion
I suggest to adapt Slackware to GRUB (instead of adapting GRUB to Slackware), doing what most other distributions do since a long time:
drop the huge kernels for good and provide only generic ones
build an initramfs for each new kernel
keep the running kernel when upgrading just in case
adopt a naming scheme handled by grub-mkconfig
build a new grub.cfg, possibly keeping the previous one as a backup.
All this being done automatically after a kernel upgrade, maybe after authorization by the user "Do you want to..."
Last edited by Didier Spaier; 01-17-2024 at 09:16 AM.
Reason: keep the running kernel ***when upgrading*** just in case
This is what I am using right now on all of my computers and vm's (VirtualBox). All are BIOS except for one VM that is EFI. I am using kernel-generic on all installs. For the -current installs, no initrd is used, for the my 14.2 and 15.0 installs an initrd is used. The BIOS installs have a BIOS Boot partition, of course the EFI install has an EFI partition.
I am including a screenshot of of my Slackware64-current VM. This is the 09_slackware section for that screenshot:
Code:
### BEGIN /etc/grub.d/09_slackware ###
menuentry 'Slackware-15.0+ with Generic Kernel (6.1.66)' --class slackware_15_0_ --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-vmlinuz-advanced-generic-af779a17-fb23-47e6-ae5c-efcd75c188d7' {
savedefault
load_video
set gfxpayload=800x600x32
insmod gzio
insmod part_gpt
insmod ext2
set root='hd0,gpt2'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt2 --hint-efi=hd0,gpt2 --hint-baremetal=ahci0,gpt2 af779a17-fb23-47e6-ae5c-efcd75c188d7
else
search --no-floppy --fs-uuid --set=root af779a17-fb23-47e6-ae5c-efcd75c188d7
fi
echo 'Loading Linux vmlinuz ...'
linux /boot/vmlinuz root=/dev/sda2 ro logo.nologo
}
### END /etc/grub.d/09_slackware ###
On this computer I have a "stock" kernel and a "last working" kernel installed. In /etc/grub.d/ I use an unmodified 00_header file and a custom 09_slackware file (a modified 10_linux). All other files are non executable except in the case of EFI, 25_bli and 30_uefi-firmware are executable.
This computer has two kernels installed, one is the latest (stock), the other is the last working backup (working). This is /etc/boot:
Code:
# ls -l /boot/vmlinuz*
lrwxrwxrwx 1 root root 22 Jan 11 21:46 /boot/vmlinuz -> vmlinuz-generic-6.6.11
lrwxrwxrwx 1 root root 22 Jan 11 21:46 /boot/vmlinuz-generic -> vmlinuz-generic-6.6.11
-rw-r--r-- 1 root root 12297792 Jan 6 03:11 /boot/vmlinuz-generic-6.6.10
-rw-r--r-- 1 root root 12309568 Jan 11 03:23 /boot/vmlinuz-generic-6.6.11
-rw-r--r-- 1 root root 12292928 Dec 21 03:49 /boot/vmlinuz-generic-6.6.8
-rw-r--r-- 1 root root 12291104 Jan 2 03:18 /boot/vmlinuz-generic-6.6.9
lrwxrwxrwx 1 root root 22 Jan 11 21:48 /boot/vmlinuz-generic-stock -> vmlinuz-generic-6.6.11
lrwxrwxrwx 1 root root 22 Jan 11 21:48 /boot/vmlinuz-generic-working -> vmlinuz-generic-6.6.10
As you may have notice above there are actually four kernels installed (need to fix that ). Only the two "stock" and "working" are picked up, if there were no "stock" or "working" symlink, then the kernel linked to vmlinuz is picked up.
This is the 09_slackware section of grub.cfg (I don't have a screenshot):
Code:
### BEGIN /etc/grub.d/09_slackware ###
menuentry 'Slackware-15.0+ with Generic Kernel [Working] (6.6.10)' --class slackware_15_0_ --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-working-advanced-generic-601df5bd-43a7-400e-834e-47045df436d0' {
savedefault
load_video
set gfxpayload=1366x768x32
insmod gzio
insmod part_gpt
insmod ext2
set root='hd0,gpt1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt1 --hint-efi=hd0,gpt1 --hint-baremetal=ahci0,gpt1 601df5bd-43a7-400e-834e-47045df436d0
else
search --no-floppy --fs-uuid --set=root 601df5bd-43a7-400e-834e-47045df436d0
fi
echo 'Loading Linux working ...'
linux /boot/vmlinuz-generic-working root=/dev/sda1 ro nvidia-drm.modeset=1 logo.nologo
}
menuentry 'Slackware-15.0+ with Generic Kernel [Stock] (6.6.11)' --class slackware_15_0_ --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-stock-advanced-generic-601df5bd-43a7-400e-834e-47045df436d0' {
savedefault
load_video
set gfxpayload=1366x768x32
insmod gzio
insmod part_gpt
insmod ext2
set root='hd0,gpt1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,gpt1 --hint-efi=hd0,gpt1 --hint-baremetal=ahci0,gpt1 601df5bd-43a7-400e-834e-47045df436d0
else
search --no-floppy --fs-uuid --set=root 601df5bd-43a7-400e-834e-47045df436d0
fi
echo 'Loading Linux stock ...'
linux /boot/vmlinuz-generic-stock root=/dev/sda1 ro nvidia-drm.modeset=1 logo.nologo
}
### END /etc/grub.d/09_slackware ###
I have attach my 09_slackware and /etc/default/grub. The kernel version is optional and grub-mkconfig has to be run to change it for a new kernel. If you don't want the kernel version included, then running grub-mkconfig is not necessary as the vmlinuz symlink is used or the "stock", "working" symlinks. For my "stock" and "working" setup, you do have to change the syslinks to match the kernel versions. With the standard install of Slackware running grub-mkconfig after a new kernel is not required. If you are using an initrd (of course that will have to be updated for the new kernel) there is an option in /etc/default/grub to enable it (by default disabled).
Edit: As an after thought I am adding the output of grub-mkconfig for this computer.
Code:
grub-mkconfig -o /boot/grub/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-generic-working
Found linux image: /boot/vmlinuz-generic-stock
Found linux image: /boot/vmlinuz
done
I have to give credit to marav and LuckyCyborg for give me the idea to come up with this.
Last edited by chrisretusn; 01-16-2024 at 01:17 AM.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.