HACK: Void kernel management – vkpurge modification

For those that don’t know about Void and kernels, Void offers many of them at any single period and updates them within 24hr of a new edition.  The kernel pkg name for each edition stays the same, but the versions have an extended naming that is also used in making the bootable images.   For example, let’s say you are following “linux4.19” and it is currently linux4.19.39-1.  Then there might be 4.19.40-1, 4.19.40-2 and so on.  If you use vkpurge to list the editions it will show you all except for the current.  Let’s say you also follow linux4.14, linux4.20, and linux5.0.  You may end up having to remove many kernel editions within a week.  When a command “vkpurge rm 4.20.1-1 4.20.2-1 4.20.3-1 4.20.3-2” is run, four images will be removed but also for every single one that is being removed grub reconfigures itself.  Os-prober is also a pkg required by grub (unless you remove it along using the -F option, which disregards dependencies) and let’s say hypothetically you have 3 installations on the same machine.  None with systemd ofcourse (let’s not forget), and to do the above clearing of kernels, grub will run 4 times and will take time to identify those 2 other installations.  So with 4 kernels to remove and 2 more installations to identify and write entries for, you may be stuck there for 15′ looking at the screen.

Sometime last year I was questioning why vkpurge had to run grub each time it removed a single kernel, even though the instruction was to remove 5.  That was in the old Void forum and one of the developers/maintainers (I believe if I remember right) told me to hack the vkpurge script for grub to only run once after all kernels on the list are removed.  Well, I kept making mistakes so he actually went and wrote the specific alteration and placed it on the forum.  The change was simple, you take the grub hook out of the loop, so once all kernels on your list are removed, the loop ends, and then grub runs before the script ends.

I have used it for about a year now and it worked perfect every time.  Since there is no evidence of the forum archived anywhere on the net, I though it would have been a lost resource, so I am publishing it here (I don’t have my own git space) so others who may think of it being useful can use it.  Instead of modifying the original I called it vkpurge2 (chmod 0755 /usr/bin/vkpurge2 to make it executable) and save yourself some time during upgrades.

I hope it helps:

#!/bin/sh
#
# A simple script to remove old kernel files/modules.
# Brought to you by yours truly Juan RP in the Public Domain.
# revised by void forum user March 2018 (sorry can't remember the name)
#
: ${progname:=$(basename $0)}

case "$(xbps-uhelper arch)" in
    aarch64*) KIMAGE="vmlinux";;
    *) KIMAGE="vmlinuz";;
esac

usage()
{
	cat <<_EOF
Usage: $progname <target> [<version>]
Targets:
 list			Lists old installed kernels.
 rm <version...|all>	Remove kernel <version> or all old kernels.
Example:
	$ $progname list
	$ $progname rm 2.6.39.2
_EOF
	exit 1
}

list_kernels()
{
	local k kpkg installed kver _f

	for k in /boot/$KIMAGE-*; do
		_f=$(basename $k)
		kver=$(echo ${_f}|sed -e 's|-rc|rc|')
		installed=$(xbps-query -o "$k" 2>/dev/null)
		[ -n "$installed" ] && continue
		kpkg="$(xbps-uhelper getpkgversion ${_f} 2>/dev/null)"
		[ "$(uname -r)" = "$kpkg" ] && continue
		[ -n "$kpkg" ] && echo "$kpkg"
	done
}

run_hooks()
{
	local dir="$1"
	local kver="$2"
	local d

	for d in /etc/kernel.d/${dir}/*; do
		[ ! -x "$d" ] && continue
		[ "$d" = /etc/kernel.d/post-remove/50-grub ] && continue
		echo "Running ${dir} kernel hook: $(basename $d)..."
		$d kernel $kver
	done
}

remove_kernel()
{
	local rmkver="$1"
	local installed f kfile

	if [ ! -f /boot/$KIMAGE-${rmkver} -a ! -d /lib/modules/${rmkver} ]; then
		echo "Kernel ${rmkver} not installed."
		exit 0
	fi

	installed=$(xbps-uhelper version "linux${rmkver%*.*}" 2>/dev/null)
	if [ -n "$installed" -a "$installed" = "$rmkver" ]; then
		echo "Kernel $rmkver is currently installed."
		exit 0
	fi

	# Execute pre-remove kernel hooks.
	run_hooks pre-remove $rmkver
	# Remove kernel files in /boot.
	for f in config System.map $KIMAGE; do
		kfile="/boot/${f}-${rmkver}"
		[ ! -f "${kfile}" ] && continue
		echo "Removing ${kfile}..."
		rm -f ${kfile}
	done
	# Remove kernel modules
	if [ -d "/lib/modules/${rmkver}" ]; then
		echo "Removing /lib/modules/${rmkver}..."
		rm -rf /lib/modules/${rmkver}
	fi
	# Execute post-remove kernel hooks.
	run_hooks post-remove $rmkver
	# Remove kernel-headers.
	if [ -d /usr/src/kernel-headers-${rmkver} ]; then
		rm -rf /usr/src/kernel-headers-${rmkver}
	fi
	# Remove debugging symbols.
	dfile=/usr/lib/debug/boot/vmlinux-${rmkver}
	if [ -f "${dfile}" ]; then
		echo "Removing ${dfile}..."
		rm -f ${dfile}
	fi
	if [ -d /usr/lib/debug/usr/lib/modules/${rmkver} ]; then
                echo "Removing /usr/lib/debug/usr/lib/modules/${rmkver}..."
                rm -rf /usr/lib/debug/usr/lib/modules/${rmkver}
	fi
}

if [ "$1" = "list" ]; then
	list_kernels
elif [ "$1" = "rm" ]; then
	if [ "$(id -u)" -ne 0 ]; then
		echo "You have to run this script as root!"
		exit 1
	fi

	if [ -z "$2" ]; then
		usage
	elif [ "$2" = "all" ]; then
		kernels=$(list_kernels)
		for k in ${kernels}; do
			echo "Removing kernel $k files ..."
			remove_kernel "$k"
		done
		echo "Updating GRUB..."
		grub-mkconfig -o /boot/grub/grub.cfg
	else
		shift
		for k; do
			echo "Removing kernel $k files ..."
			remove_kernel "$k"
		done
		echo "Updating GRUB..."
		grub-mkconfig -o /boot/grub/grub.cfg
	fi
else
	usage
fi

exit 0%

One thought on “HACK: Void kernel management – vkpurge modification

If your comment is considered off-topic a new topic will be created with your comment to continue a different discussion. This community is based on open and free communication, meaning we must all respect all in minimizing the exercise of freedom to disrupt such communication. Feel free to post what you think but keep in mind the subject matter discussed. It is just as easy to start a new topic as it is to dilute the content of an existing discussion.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.