Subject: GRUB with multiple partitions with identical bzImage

From: Vagrant Cascadian <[email-masked]>
Date: Wed, 15 Nov 2017 15:36:11 -0800

I've been exploring GuixSD for the past few days. Very cool! Even if a
little rough around the edges...

Ran into an ugly problem with GRUB being unable to load the initrd, due
to having multiple GuixSD installs on the same machine, with identical
paths for the bzImage files, but not identical paths for initrd files...

Confusingly, when I loaded the kernel+initrd by hand from the grub
commandline, it would work! But that was because I was specifying which
device to load from...

With some help from the folks on #grub on freenode (Thanks to TJ- and
Jordan_U!), we identified it was an issue with the way GRUB was
configured to search for files:

menuentry "GNU with Linux-Libre 4.13.12 (beta)" {
    search --file --set /gnu/store/q9q8y9rh3jw1qcx6bic1v18qag80z74a-linux-libre-4.13.12/bzImage
    linux /gnu/store/q9q8y9rh3jw1qcx6bic1v18qag80z74a-linux-libre-4.13.12/bzImage \
          --root=/dev/mapper/cryptic \
          --system=/gnu/store/bsxnm36vvx2wxc9h3q5l8b5286gw75hr-system \
          --load=/gnu/store/bsxnm36vvx2wxc9h3q5l8b5286gw75hr-system/boot \
    initrd /gnu/store/7w9dzb6b9vb9gzj61zyqsg4zg6ys4hgb-raw-initrd/initrd
}

I had two partitions, one on (hd0,msdos4) and one on (crypto0) which
both contained
/gnu/store/q9q8y9rh3jw1qcx6bic1v18qag80z74a-linux-libre-4.13.12/bzImage,
and the search command was returning the one on (hd0,msdos4), and thus
setting root (hd0,msdos4).

Unfortunately,
/gnu/store/7w9dzb6b9vb9gzj61zyqsg4zg6ys4hgb-raw-initrd/initrd was only
present on the (crypto0) partition.

So, when it booted, I would get the confusing error message:

  error: file `/gnu/store/7w9dzb6b9vb9gzj61zyqsg4zg6ys4hgb-raw-initrd/initrd' not found

And then a kernel panic, as there was no initrd...

The suggestion from the #grub folks was to use a UUID or some other more
reliable method of finding the correct device to load the kernel and
initrd files from.

A quick workaround might be to also add a search line for the initrd
after loading the kernel:

menuentry "GNU with Linux-Libre 4.13.12 (beta)" {
    search --file --set /gnu/store/q9q8y9rh3jw1qcx6bic1v18qag80z74a-linux-libre-4.13.12/bzImage
    linux /gnu/store/q9q8y9rh3jw1qcx6bic1v18qag80z74a-linux-libre-4.13.12/bzImage \
          --root=/dev/mapper/cryptic \
          --system=/gnu/store/bsxnm36vvx2wxc9h3q5l8b5286gw75hr-system \
          --load=/gnu/store/bsxnm36vvx2wxc9h3q5l8b5286gw75hr-system/boot \
    search --file --set /gnu/store/7w9dzb6b9vb9gzj61zyqsg4zg6ys4hgb-raw-initrd/initrd
    initrd /gnu/store/7w9dzb6b9vb9gzj61zyqsg4zg6ys4hgb-raw-initrd/initrd
}

I'm not sure this is the best approach, as it could potentially load
kernel+initrd from an untrusted filesystem which may contain a malicious
kernel or initrd that simply matches the file paths...

I'll look into a proper solution at some point, but it'd be fine if
someone beats me to it!

live well,
  vagrant