Installing Grub 2 on HVM

This page describes the process of installing GRUB 2 to a Xen HVM domU from our Linux rescue image. Normally, you will not need to do this, but there are a few situations in which it might be necessary. If you moved from a legacy VPS to an HVM VPS, we try to automatically install and configure GRUB 2 on the new system. If that process failed, you will need to go through the steps yourself. The instructions for installing GRUB 2 vary among operating systems. For instance, under CentOS 7, there are commands named grub2-install and grub2-mkconfig. Under Ubuntu, their equivalents are named grub-install and grub-mkconfig. During this explanation, we will assume CentOS 7. If your operating system uses different command names, just substitute them in these instructions.

Preliminaries

First, connect to the VPS console for your VPS. Make sure that the VPS is not running. If it is, select option 3 to do a polite shutdown. From the main menu, select option 6 to set bootloader or rescue mode. Select option 2, Linux Live Rescue. Choose either 64-bit or 32-bit from the menu, depending on what type of VPS you have. Answer the prompt about adding SSH keys to the root user, and then select option 0 twice to return to the main menu. Select option 2 to start the instance. Shortly, you’ll be presented with the out-of-band console for the Linux Live Rescue environment. Log in as root at the login prompt. There is no password.

Making the Chroot

The rest of these instructions should be done in a chroot environment. Here is a brief explanation of how to establish it. We assume that you have a very typical partition layout, with everything on one partition, /dev/xvda1. If you use multiple partitions, you will probably need to mount them on the correct directories under /mnt.

$ mount /dev/xvda1 /mnt  # Mount the root partition on /mnt.
# Next, mount additional pseudo-filesystems.
$ mount --rbind --make-rslave /dev /mnt/dev
$ mount --rbind --make-rslave /sys /mnt/sys
$ mount -t proc none /mnt/proc
$ mount --bind "$(readlink -f /etc/resolv.conf)" /mnt/etc/resolv.conf
$ chroot /mnt

Now, you are chrooted in to your existing installation. For the rest of this article, we assume that you are running all commands from within the chroot.

Install the grub2 Package

If the grub2 package is not installed, install it with:

$ yum install grub2

Again, we are assuming CentOS; other distributions will require something different here.

The Common Case: Installing to the MBR

Typically, GRUB is installed directly to the master boot record. That is a bit of a simplification. Part of GRUB, called a stage 1, is installed to the master boot record. The rest of GRUB is installed to some empty space between the master boot record and the start of the first partition, and the stage 1 has just enough code to load the rest of GRUB.

You need at least 62 free sectors between the master boot record and the start of partition 1, in order for this to work. In some special cases, GRUB may require more space than 62 sectors. We’ve concluded that starting partition 1 at sector 2048 or greater leaves plenty of space for GRUB. You should try installing to the master boot record first. If that fails, and you determine that there is not enough free space, see the section titled Installing GRUB 2 to a Partition.

To install GRUB 2 to the master boot record, simply run the following command from the chroot:

$ grub2-install /dev/xvda

If it was successful, proceed with the section titled Configuring GRUB 2.

Installing GRUB 2 to a Partition

This technique is not recommended, but if there is not enough free space after the master boot record, it is your only option.

First, make sure that the immutable attribute is cleared on GRUB 2’s core.img file:

$ chattr -i /boot/grub2/i386-pc/core.img

If the file does not exist, that is ok; it will be created shortly. Next, install GRUB 2 to /dev/xvda1:

$ grub2-install --force /dev/xvda

The --force option is necessary, because grub2-install will ordinarily refuse to install to a partition. Finally, set the immutable attribute on the core.img file:

$ chattr +i /boot/grub2/i386-pc/core.img

That last step is very important. If you fail to do this, your package manager or some other tool might move the core.img file, making your system unbootable. This is one reason we strongly recommend against installing to a partition, unless you have no alternative.

Once you have verified that GRUB is installed, proceed to the Configuring GRUB 2 section.

Considerations for GPT

If you formatted your disk using the GPT partitioning scheme, you are going to need to add a special partition for GRUB 2 called a BIOS boot partition. The version of fdisk supplied on our Linux Live Rescue image supports GPT, so we will use fdisk for these instructions. Run the command:

$ fdisk /dev/xvda

Press n followed by enter to add a new partition. You will be prompted for the partition number and starting sector. Supply appropriate values here; the defaults are probably fine. Next, you will be asked for the last sector or size of the partition. We have concluded that 1 MiB should be adequate, so supply +1M at the prompt. You need to change the type of your new partition. Press t and then enter. At the prompt, supply the partition number that you used above. You will be prompted for the type code. You can get a list of codes by pressing l and then enter. Look for the one named BIOS boot. At the time of this writing, the code is 4. Once you’ve entered the type code, press w and enter to write the new partition table to disk. Exit the utility with q.

Configuring GRUB 2

Using your text editor of choice, edit the file /etc/default/grub. Here is a configuration file from a running system.

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL="serial console"
GRUB_CMDLINE_LINUX="console=ttyS0 rootflags=barrier=0"
GRUB_DISABLE_RECOVERY="true"
GRUB_DISABLE_LINUX_UUID="true"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200"

The most important lines here are GRUB_TERMINAL, GRUB_CMDLINE_LINUX, and GRUB_SERIAL_COMMAND. You should be able to use those three as-is. You might want to add extra options to GRUB_CMDLINE_LINUX, depending on your setup. At the very least, it should contain console=ttyS0 and not console=hvc0.

Once you are done editing the file, save it and run the command:

$ grub2-mkconfig -o /boot/grub2/grub.cfg

Conclusion

GRUB 2 should now be installed and fully configured. Before rebooting your system, you should run the following set of commands:

$ exit  # to exit the chroot environment
$ sync
$ mount -o remount,ro /mnt
$ umount --recursive /mnt
$ exit  # to exit the root shell in rescue mode

Now it is safe to reboot into your new installation. Detach from the out-of-band console by pressing ctrl-]. At the main menu, select option 3 to shut down. Select option 6 to set bootloader. Choose option 1 to boot from disk, 0 to exit the menu, and 2 to start the system.