Howto: Grub2 Multiboot Distro's w/LVM

Write tutorials here
There are more tutorials here http://community.linuxmint.com/tutorial/welcome
Forum rules
Do not start a support topic here please. Before you post please read this

Howto: Grub2 Multiboot Distro's w/LVM

Postby Locuust on Tue Apr 16, 2013 7:22 pm

TL:DR Howto add other distro's located on LVM LV's to main grub2 menu without worrying about grub-install errors when installing to a partitonless disk or an impotent os-prober.

Disclaimer: This will only work if your main distro controlling the MBR bootloader (assuming Mint) and the additional distro's are all using Grub 2.00. If they are different versions that use different format /boot/grub/grub.cfg files you may have to do a real "chainload" (even Grub 1.99 seems to have some syntax differences). I'll present an option 2 that might work if the first option does not.

4/17/13 - Corrected some minor mistakes due to grub version differences.

Overview: Os-prober doesn't work for me. I could never get it to automagically find my other distro's that exist on LV's. I tried every preload and mounting trick I found on forums and it still wouldn't find them. Heck, even the GNU grub manual says that "os-prober and has several shortcomings". To compound this problem, or perhaps this is why os-prober fails, grub-install will not install itself to a so called partitionless disk unless you --force it to (warning of doomsday blocklist breakage fwiw). Most of the alternatives to os-prober I found suggested manually creating static grub menu entries in /etc/grub.d/40_custom. This seemed like a silly waste of time to me because it totally bypassed the other distro's management of it's own grub.cfg. Meaning new kernel updates and the like become a pain to maintain. I figured there had to be some way to replicate the legacy grub chainloading wonder. The answer was a pretty simple one that was all but staring me in the face even though the signal to noise ratio of other solutions prevented me from finding it at first.

Right about now someone is probably about to hit the submit button on a message that says I'm doing it wrong, or that they've grub-installed to partitionless disks for years without breakage, etc. Be that as it may this seems like such a simple solution that I question the reason to brute force another one. By all means correct me if I'm wrong by providing an easier solution.

Note: When a step requires you to change something to fit your install I put the part that needs to be modified in <> and bold it. ex. <enter_your_name_here>

Option 1:

1) Setup -
While it's possible to boot directly from an LV (/boot on LV) it's considered better form to have a standard /boot partition. It's also the only way to go if you latter decide to encrypt your LV's as I understand it. Suffice to say I created a /dev/sda1, 1 Gb, ext4 when installing mint. If you need help installing mint on LVM see this howto. During the Mint install I had it install grub to /dev/sda. Your other distro's can be installed as you see fit on other LV's but make sure you don't have them install their grub/bootloader to /dev/sda (which would overwrite our work here). You have several other options on where to install the bootloader -
1) The MBR of another drive, i.e. /dev/sdb. Only use this option if you're sure you don't have a bootloader on that drive you want to preserve.
2) The root/boot LV for the distro. This is safest in terms of not treading on anyone's feet but can supposedly cause issues if not handled correctly.
3) Not to install at all. Not all installers will let you skip this step (hopefully they still install the grub2 package though).

2) Boot into Mint.

3) Copy lines from grub.cfg of 'other distro' -
sudo mount /dev/mapper/<other_distro_lv_containing_/boot> /mnt
sudo <name-of-your-favorite-editor> /mnt/boot/grub/grub.cfg

You need to find and copy the insmod and root entries from the first menuentry. Below is an example with the lines needed in bold -
menuentry 'Other Distro 64-bit, 4.0-1-generic (/dev/mapper/vg1-otherdistro_root)'
recordfail
gfxmode $linux_gfx_mode
insmod gzio
insmod part_msdos
insmod lvm
insmod ext2
set root='lvm/vg1-otherdistro_root'

Normally you'd want to keep the UUID search lines, but since LVM device names are static we'll skip them.
Code: Select all
sudo umount /mnt

4) Open a new text file, paste the copied lines, and modify into menuentry -
Paste the lines from above into a new file in your favorite text editor. Before these lines enter -
menuentry "<Name_of_your_other_distro> <vg1-otherdistro_root>" {

After the copied lines enter -
configfile /boot/grub/grub.cfg
}

It should look something like this -
menuentry "Arch Linux AMD64 vg1-arch_root" {
insmod gzio
insmod part_msdos
insmod lvm
insmod ext2
set root='lvm/vg1-arch_root'
configfile /boot/grub/grub.cfg

Note: Since your main grub bootloader is v2.00 make sure that the "set root" line is of the following format -
set root='lvm/<volume_group>-<logical_volume>'

If you have more distro's you want to add save this file temporarily and repeat steps 3 and 4 until you have a menuentry for each one (adding an extra line between entries for readability).
Note: If you have a separate /boot LV for some reason, I did out of habit, be sure to remove the /boot from the pathnames above. ex.
configfile /grub/grub.cfg


5) Apply menuentries from step 4 to /etc/grub.d/40_custom -
sudo <name-of-your-favorite-editor> /etc/grub.d/40_custom

Assuming you haven't already modified this file it should look like -
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.

Change the 'exec' line to -
exec tail -n +4 $0

and add a line above it like this -
echo 1>&2 "<Adding Other Distro 1, Distro 2, etc>"

Then copy the resulting text from step 4 to the end of the file. In the end it will look something like this -
#!/bin/sh
echo 1>&2 "Adding Arch Linux, Other Distro 2"
exec tail -n +4 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry "Arch Linux AMD64 vg1-arch_root" {
insmod gzio
insmod part_msdos
insmod lvm
insmod ext2
set root='lvm/vg1-arch_root'
configfile /boot/grub/grub.cfg
}

menuentry "Other Distro 2 AMD64 vg1-otherdistro2_root" {
insmod gzio
insmod part_msdos
insmod lvm
insmod ext2
set root='lvm/vg1-otherdistro2_root'
configfile /boot/grub/grub.cfg
}

Do not save this to 40_custom. Instead, save it to /etc/grub.d/<number>_custom. Where <number> is determined by the scripts you already have in /etc/grub.d. For example -
Code: Select all
ls /etc/grub.d/

00_header
05_debian_theme
06_mint_theme
09_linux_xen
10_linux
11_custom
20_memtest86+
30_os-prober
40_custom
41_custom

In my case I named mine "11_custom". Meaning it will be added after my default linux entries when I run grub-update (because 10_linux adds those). Keep in mind that if you chose a number lower than 10 you have to prefix it with a zero (all numbers must be two digits due to sorting). Once you've saved your custom script you need to make it executable -
sudo chmod +x /etc/grub.d/<your_custom_name_here>

Note: If there are scripts you don't want to run (I disabled 30_os-prober since it's redundant) you can turn them off by -
sudo chmod -x /etc/grub.d/<script_to_disable>

6) Update-grub
Code: Select all
sudo update-grub

If everything went well you should see the message you added above displayed as update-grub runs. Ex -
echo 1>&2 "Adding Other Distro 1, Distro 2, etc"

Reboot and you should now have menuitems that will display the contents of all your other distro's grub.cfg. If those distro's update their config you need not change anything because your primary grub bootloader only references the grub.cfg.

Option 2:
Disclaimer: I stumbled upon this alternative here - http://forum.manjaro.org/index.php?topic=514.0 This option may or may not be subject to the breakage concerns raised by grub-install. I want to say it's not because we aren't actually chaining off the other LV's bootsector, but I may be misunderstanding something from this page - https://wiki.archlinux.org/index.php/GR ... nless_Disk. You will need to locate (or create) the "core.img" file for each of the distro's you're chaining. Below are some grub version specific notes -
Grub 1.99
Check to see if /boot/grub/core.img exists in your grub 1.99 distro(s). The following should create a core.img -
grub-install --grub-setup=/bin/true --recheck --debug /dev/sda
Note: /bin/true tricks script into believing img has been applied to MBR. So this command should only touch your core.img. However it will break the link of any MBR stage one bootloader pointing to it so make sure you don't do this to your main distro. Otherwise you'll have to chroot back into the install from a boot disc and reinstall grub to the MBR.
Grub 2.00:
Check to see if /boot/grub/i386-pc/core.img exists in your grub 2.00 distro(s). If not you will need to follow this step - https://wiki.archlinux.org/index.php/GR ... .img_alone

1) Differences.
The only thing different in option 2 is how you define your menuentry lines in your custom script (see step 5 in option 1). Instead of -
#!/bin/sh
echo 1>&2 "Adding Arch Linux, Other Distro 2"
exec tail -n +4 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry "Arch Linux AMD64 vg1-arch_root" {
insmod gzio
insmod part_msdos
insmod lvm
insmod ext2
set root='lvm/vg1-arch_root'
configfile /boot/grub/grub.cfg
}

You need to make the highlighted changes (to each entry) -
#!/bin/sh
echo 1>&2 "Adding Arch Linux, Other Distro 2"
exec tail -n +4 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry "Arch Linux AMD64 vg1-arch_root" {
insmod gzio
insmod part_msdos
insmod lvm
insmod ext2
set root='lvm/vg1-arch_root'
set OS_boot_config='/boot/grub/grub.cfg'
multiboot <path_to_your_version_dependant_core.img>

}

Pro's - I assume this would work even if the distro's didn't share the same grub version as you are loading the other bootloaders image as I understand it.
Con's - There is a slight delay as the other loader is booted and you cannot return to the previous menu without creating a link back to your primary loader with a similar custom menuentry pointing back to your primary grub install.
*edit* Note: the "OS_boot_config" entry seems to be specific to Burg (alternative to Grub2) so it's probably not needed in this case. I'll leave it for now because I've not tested it w/o it. It's not a option listed in the GNU grub manual.
Locuust
Level 3
Level 3
 
Posts: 156
Joined: Thu Oct 02, 2008 4:54 pm

Linux Mint is funded by ads and donations.
 

Return to Tutorials

Who is online

Users browsing this forum: Total_Blue and 7 guests