You are not logged in.
Pages: 1
I am exploring ways to boot into old kernels with btrfs snapshots and GRUB. I have the following script that runs before and after the linux package is upgraded:
declare -r pre_or_post=$1
if [[ "$pre_or_post" == "pre" ]]; then
find /usr/lib/modules -xtype l -delete
find /boot -xtype l -delete
kver=$(uname -r)
snapnum=$(snapper --config boot create --print-number --cleanup-algorithm number --description $kver)
ln -s /boot/.snapshots/$snapnum/snapshot/vmlinuz-linux /boot/vmlinuz-linux-$kver
ln -s /boot/.snapshots/$snapnum/snapshot/initramfs-linux.img /boot/initramfs-linux-$kver.img
ln -s /boot/.snapshots/$snapnum/snapshot/initramfs-linux-fallback.img /boot/initramfs-linux-$kver-fallback.img
snapper --config modules create --print-number --cleanup-algorithm number --description $kver > /tmp/.snapnum
elif [[ "$pre_or_post" == "post" ]]; then
ln -s /usr/lib/modules/.snapshots/$(</tmp/.snapnum)/snapshot/$(uname -r) /usr/lib/modules/
kver=$(pacman -Q linux | awk '{print $2}')-ARCH
mv /boot/vmlinuz-linux /boot/vmlinuz-linux-$kver
mv /boot/initramfs-linux.img /boot/initramfs-linux-$kver.img
mv /boot/initramfs-linux-fallback.img /boot/initramfs-linux-$kver-fallback.img
grub-mkconfig -o /boot/grub/grub.cfg
fi
Essentially it creates a snapshot of /boot and symlinks the old images to the boot directory. GRUB recognizes the images when grub-mkconfig is run:
Found linux image: /boot/vmlinuz-linux-4.10.10-1-ARCH
Found initrd image(s) in /boot: intel-ucode.img initramfs-linux-4.10.10-1-ARCH.img
Found fallback initrd image(s) in /boot: intel-ucode.img initramfs-linux-4.10.10-1-ARCH-fallback.img
Found linux image: /boot/vmlinuz-linux-4.10.9-1-ARCH
Found initrd image(s) in /boot: intel-ucode.img initramfs-linux-4.10.9-1-ARCH.img
Found fallback initrd image(s) in /boot: intel-ucode.img initramfs-linux-4.10.9-1-ARCH-fallback.img
done
Here is my grub.cfg: https://ptpb.pw/OZlQ
When I attempt to actually boot an image that is a symlink, GRUB cannot find it. It can find and boot images (in this case the 4.10.10 image is not a symlink so that boots just fine, or I can choose the old image directly and it boots).
Is this a limitation of GRUB or is there a setting I am missing? I have searched the internet and checked the manpages and wiki, but I've come up with nothing so far.
Offline
I've never tried that but would say the pitfall here is that the symlink resolves into a subvolume?
Tried a hard link?
Offline
Looking through /etc/grub.d/10_linux I see that the issue is how the directory and filename are resolved and then set when it comes to finding out the full subvolume's path. It does:
basename=`basename $linux`
dirname=`dirname $linux`
rel_dirname=`make_system_path_relative_to_its_root $dirname`
The make_system_path_relative_to_its_root function above calls grub-mkrelpath
Then later the entry has:
linux ${rel_dirname}/${basename}
This results in:
${rel_dirname}/${basename} = "/@/boot/vmlinuz-linux-4.10.9-1-ARCH"
If I run "grub-mkrelpath /boot/vmlinuz-linux-4.10.9-1-ARCH" I get:
/@/boot/.snapshots/1/snapshot/vmlinuz-linux-4.10.9-1-ARCH
which is the correct location.
Tried a hard link?
Btrfs doesn't like hard linking across subvolumes:
sudo ln /boot/.snapshots/1/snapshot/vmlinuz-linux vmlinuz-linux-4.10.9-1-ARCH
ln: failed to create hard link 'vmlinuz-linux-4.10.9-1-ARCH' => '/boot/.snapshots/1/snapshot/vmlinuz-linux': Invalid cross-device
Offline
My workaround was to create a subdirectory in "/boot" called "old". I put my symlinks there so 10_linux won't detect them. Then I created a grub configuration script by modifying 10_linux to look for symlinks in "old" and properly find where they are.
Offline
Pages: 1