Repairing a broken grub.conf in CentOS

Today I got an error during updating Hyper-V kernel modules on CentOS 6.3. The upgrading process removes the already loaded kernel modules in a running system. This results in a kernel oops and a broken init ramdisk for the currently running kernel. Sometimes it happens that a kernel oops occures during writing the new grub configuration. On the next boot grub cannot find any configuration files and falls back to the grub shell. You will get a prompt like this:

grub >

Experts will be able to boot the system typing the commands for grub directly in the prompt and boot the system manually. But if you entered the lines and the system is up and running again, you won’t find any grub configuration.

On CentOS you are not able to generate a grub configuration from scratch via any scripts or tools like the Debian update-grub. CentOS itself uses grubby to generate the kernel entries. But grubby needs a template from which it can generate the entries. Last but not least this template will be generated by reading an existing grub entry. This approach ends up in a worst case scenario if you have misconfigured your /boot/grub/grub.conf, /etc/grub.conf or /boot/grub/menu.lst (the both last entries are only symlinks to /boot/grub/grub.conf) and you now try to reset your configuration. And again big trouble, if generating the grub.conf failed – for example during a kernel crash. In my situation it was a kernel crash.

It is absolutely impossible to regenerate a grub.conf from scratch with any of the tools delivered by CentOS. My solution:

  1. boot your system via Install-Disk or by grub command line prompt
  2. create an empty new /boot/grub/grub.conf
  3. add the next code snippet to your grub.conf
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-279.22.1.el6.x86_64)
  root (hd0,0)
  kernel /vmlinuz-2.6.32-279.22.1.el6.x86_64 ro root=/dev/sda3
  initrd /initramfs-2.6.32-279.22.1.el6.x86_64.img

N O T E:
I have a separated /boot partition on my systems. In standard configuration delivered by CentOS /boot and / will be on the same partition. In this case, the path to kernel and initrd will start with /boot/vmlinuz... and /boot/initramfs... . The root partition mostly will be root=/dev/sda1.

Try to boot your system with your manually built grub.conf. If anything works fine you can add new boot entries by CentOS’ tool grubby. For example:

root@host:~ $ grubby --add-kernel="/boot/vmlinuz-2.6.32-279.22.1.el6.x86_64"\
--initrd="/boot/initramfs-2.6.32-279.22.1.el6.x86_64.img"\
--title="CentOS (2.6.32-279.22.1.el6.x86_64)" --copy-default --make-default

The tool grubby will replace the /dev/sda? device file with the UUID string of the partition.
You can use the next line to generate an entry for each kernel image in /boot/:

for kernel in /boot/vmlinuz-*; do \
version=`echo $kernel | awk -F'vmlinuz-' '{print $NF}'`; \
grubby --add-kernel="/boot/vmlinuz-${version}" \
--initrd="/boot/initramfs-${version}.img" \
--title="CentOS (${version})" \
--copy-default --make-default; \
done

You should check the /etc/grub.conf for duplicate entries or maybe you will resort the boot order. Reboot your system to check if anything works fine again.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s