You are not logged in.

#1 2017-04-18 16:57:48

rdeckard
Wiki Maintainer
Registered: 2015-01-28
Posts: 137

GRUB cannot find symlinked images

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

#2 2017-04-18 20:11:01

seth
Member
Registered: 2012-09-03
Posts: 50,970

Re: GRUB cannot find symlinked images

I've never tried that but would say the pitfall here is that the symlink resolves into a subvolume?
Tried a hard link?

Offline

#3 2017-04-18 21:26:40

rdeckard
Wiki Maintainer
Registered: 2015-01-28
Posts: 137

Re: GRUB cannot find symlinked images

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.

seth wrote:

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

#4 2017-04-18 22:18:42

rdeckard
Wiki Maintainer
Registered: 2015-01-28
Posts: 137

Re: GRUB cannot find symlinked images

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

Board footer

Powered by FluxBB