Servers that were upgraded from CentOS 6 to CentOS 7 (or RedHat or other derivative) end up with an inconsistent boot loader configuration.  While the grub2 package is actually installed during the CentOS 7 upgrade, it is not actually installed to the MBR/boot sector of the disk.

This causes issues later on, because sometimes new kernels that get installed do not properly configure themselves in grub.conf (for example, being configured without an initramfs.)

However, it’s easy to install grub2 to the MBR/boot sector retroactively, so that the server can use grub2 in the future (just like a fresh install of CentOS 7 would.)

What Version of grub is There Now?

You can check which version of grub is installed on the disk currently with file -s /dev/sda:

Results for Grub 0.94
[root@g1dlgenlab12 boot]# file -s /dev/sda
/dev/sda: x86 boot sector; GRand Unified Bootloader, stage1 version 0x3, boot drive 0x80, 1st sector stage2 0x849f8, GRUB version 0.94; partition 1: ID=0xee, starthead 0, startsector 1, 4294967295 sectors, extended partition table (last)\011, code offset 0x48
Results for Grub 2
[root@g1dlgenlab12 boot]# file -s /dev/sda
/dev/sda: x86 boot sector; GRand Unified Bootloader, stage1 version 0x3, boot drive 0x80, 1st sector stage2 0x849f8; partition 1: ID=0xee, starthead 0, startsector 1, 4294967295 sectors, extended partition table (last)\011, code offset 0x63

The difference is subtle, but from what I can tell, with grub 2, the grub version doesn’t show.  With grub 0.94, it does.

Extra Steps for GPT Disks

Disks larger than ~2.2TB will be configured with a GPT partition table rather than an MBR table.  Because of this, there needs to be a small “grub_bios” partition on the drive for grub2 to be installed to.  So there are some extra steps to get this set up.

Is GPT in use?

Run this fdisk command on the box to determine if it’s a GPT disk:

[root@g1dlgenlab13 ~]# fdisk -l /dev/sda
Disk /dev/sda: 2997.8 GB, 2997752954880 bytes, 5854986240 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x00000000
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1               1  4294967295  2147483647+  ee  GPT

If it’s not GPT, you’ll see the standard boot, root, and/or LVM partitions in the traditional way.

Create grub_bios Partition in Disk Free Space

Even though the disk is partitioned with GPT, there should be about 1MB of free space at the beginning of the disk.  (I think this is the area in which grub 0.94 was installed during the CentOS 6 install.  It just doesn’t actually install in a partition.)

Use parted as below to create the new grub_bios partition in the free space at the beginning of the disk:

[root@g1dlgenlab13 ~]# parted /dev/sda
GNU Parted 3.1
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print free
Model: DELL PERC 6/i (scsi)
Disk /dev/sda: 2998GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number  Start   End     Size    File system  Name  Flags
        17.4kB  1049kB  1031kB  Free Space
 1      1049kB  525MB   524MB   ext4               boot
 2      525MB   2998GB  2997GB                     lvm
        2998GB  2998GB  1032kB  Free Space
(parted) mkpart primary 17.4kB 1048kB
Warning: You requested a partition from 16.9kB to 1048kB (sectors 33..2046).
The closest location we can manage is 17.4kB to 1048kB (sectors 34..2046).
Is this still acceptable to you?
Yes/No? Yes
Warning: The resulting partition is not properly aligned for best performance.
Ignore/Cancel? Ignore
(parted) print
Model: DELL PERC 6/i (scsi)
Disk /dev/sda: 2998GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number  Start   End     Size    File system  Name     Flags
 3      17.4kB  1048kB  1031kB               primary
 1      1049kB  525MB   524MB   ext4                  boot
 2      525MB   2998GB  2997GB                        lvm
(parted) set 3 bios_grub on
(parted) print
Model: DELL PERC 6/i (scsi)
Disk /dev/sda: 2998GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number  Start   End     Size    File system  Name     Flags
 3      17.4kB  1048kB  1031kB               primary  bios_grub
 1      1049kB  525MB   524MB   ext4                  boot
 2      525MB   2998GB  2997GB                        lvm
(parted) quit
Information: You may need to update /etc/fstab.

Now you have a place to actually install the new bootloader.  Proceed on with the rest of the procedure below.

Clear Out any Existing and Unused Kernels

Uninstall all but the currently running kernel:

rpm -q kernel | grep -v `uname -r` | xargs rpm -e

Also remove any leftover redhat-upgrade-tool kernels or initramfs’s from the /boot directory:

[root@g1dlgenlab14 boot]# rm -f initramfs-redhat-upgrade-tool.img vmlinuz-redhat-upgrade-tool

Remove Artifacts from grub 0.9x

Not sure if this is absolutely necessary, but it should prevent dracut or whatever else from trying to update the grub 0.9x config instead of grub 2:

[root@g1dlgenlab13 boot]# mv grub x.grub
[root@g1dlgenlab13 boot]# rm -f /etc/grub.conf

Generate the grub 2 Config

Use grub2-mkconfig to generate the grub2.cfg file, and validate that it’s in the proper location for the /etc/grub2.cfg symlink.

[root@g1dlgenlab13 boot]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
 
(... more output here ...)
 
[root@g1dlgenlab13 boot]# ls -l /etc/grub2.cfg
lrwxrwxrwx 1 root root 22 Apr 24 14:46 /etc/grub2.cfg -> ../boot/grub2/grub.cfg

Look at the /boot/grub2/grub.cfg file to validate the kernel (with initramfs!) is properly configured!  You can also run grubby --default-kernel to make sure the output of that command agrees as well.

Install the Bootloader

This actually installs the bits of the grub2 boot loader into the boot sector/bios_grub partition.

[root@g1dlgenlab13 boot]# grub2-install /dev/sda
Installing for i386-pc platform.
Installation finished. No error reported.

Optional:  yum update kernel to Validate Correct Installation

If you want, you can run yum update kernel at this point and watch a new kernel get installed.  Then do the same validation on /boot/grub2/grub.cfg and/or grubby --default-kernel to make sure it got configured correctly.

Reboot –yolo!

That should do it.  On boot the box should now boot using grub2, with the default kernel, after the boot timeout.