Automatically archive the modules of the currently running kernel on upgrade on Arch Linux
I don’t reboot my laptop very often. My current uptime is 11 days; that’s quite low, I’m pretty sure the previous one
was at least a month. Yet I often upgrade my system with pacman -Syu
(or more precisely yay -Syu
). As a
consequence, I’m often running a kernel that is older that the one that is currently installed:
~ % uname -sr
Linux 4.20.13-arch1-1-ARCH
~ % pacman -Qi linux | grep Version
Version : 5.0.1.arch1-1
This is usually fine, except when I plug a new device (for example a USB stick or a memory card) that is handled by a kernel module that hasn’t been loaded yet. Since the current kernel and its modules are not available anymore, the device doesn’t work… And I don’t want to reboot just for that.
I found a simple solution using Pacman hooks. The idea is to create a new hook that runs when the linux
package (or
any linux-*
package) is upgraded or removed, and that will archive the corresponding modules as a tarball. This way I
can easily extract the tarball and replug my device to have the running kernel autoload the needed module if needed.
This hook needs 2 files:
- the hook file used by pacman to decide if and when the hook command must be run;
- the actual hook command: a shell script that handles archiving the modules directory.
The hook file installed as /etc/pacman.d/hooks/keep_kernel_modules.hook
:
[Trigger]
Operation = Upgrade
Operation = Remove
Type = Package
Target = linux
Target = linux-*
[Action]
Description = Archive the modules of the currently running kernel
When = PreTransaction
Exec = /usr/local/bin/keep_kernel_modules.sh
And the shell script is installed as /usr/local/bin/keep_kernel_modules.sh
:
#!/usr/bin/env bash
. /usr/share/makepkg/util/message.sh
VERSION=$(uname -r)
if [[ -z "${VERSION}" ]]; then
error "Could not get the running kernel version number"
exit 1
elif [[ -s "/usr/lib/modules/backup_${VERSION}.tar.gz" ]]; then
warning "/usr/lib/modules/backup_${VERSION}.tar.gz already exists: skipping"
elif [[ -d "/usr/lib/modules/${VERSION}" ]]; then
msg "Creating /usr/lib/modules/backup_${VERSION}.tar.gz"
cd /usr/lib/modules
tar czf "backup_${VERSION}.tar.gz" "${VERSION}"
msg "Removing other backups"
find . -\( -type f -and -name 'backup_*.tar.gz' \
-and -not -name "backup_${VERSION}.tar.gz" -\) \
-delete
else
warning "/usr/lib/modules/${VERSION} doesn't exist: skipping"
fi
I’ve been running this for 3 years now without any issue.
Comments
Join the conversation by sending an email. Your comment will be added here and to the public inbox after moderation.