17 January 2011

Missing GRUB Config in Linux

Having recently written up how to restore GRUB to a missing / corrupted
master boot record (MBR)
, it seemed appropriate to follow up with
resolving a missing GRUB config file.  Our host details for this
situation are:
        HOST:           tux
        PROMPTS:        [grub> |tux [0] ]
        OS:             CentOS 5.4 Linux
        DISKS:          [sda (hd0|disk1)|sdb (hd1|disk2)]
        ROOT PARTITION: sdb1
While the host has two viable disks, we'll only focus on disk 2.  Also,
the following details a Red Hat variant of Linux, though may additionally
be usable with other distros or other UNIX variants using GRUB.

After powering on the host, we tell the BIOS to boot disk 2.  Once through
POST, the BIOS runs the boot code from the MBR of disk 2, only to display
the following:
            GNU GRUB  version 0.97  (639K lower / 1047488K upper memory)

         [ Minimal BASH-like line editing is supported.  For the first word, TAB
           lists possible command completions.  Anywhere else TAB lists the possible
           completions of a device/filename.]

        grub> _
Well, GRUB is installed on the MBR, otherwise we wouldn't have seen
the above.  The reason that we see it is likely due to a missing GRUB
configuration file (grub.conf or menu.lst).  Proceeding from that
assumption, we use 'find' to locate the "stage1" boot file on the
available disks, subsequently setting the root disk via 'root':
        grub> find /boot/grub/stage1
         (hd0,0)
         (hd1,0)

        grub> root (hd1,0)
         Filesystem type is ext2fs, partition type 0x83
The 'find' returns two disks.  As previously stated, we want the
correlative to our root disk on "sdb1" so we set 'root' to "hd1,0".
(We are actually setting the device that contains our /boot directory.)
The value breaks down to hd1 = disk 2, hd1,0 = disk2, first partition.
Now we need to tell grub where our kernel is.  In the first 'kernel'
example, I've only typed out the beginning of the kernel file and hit
[TAB] for autocompletion, resulting in the second 'kernel' command.
The second kernel command has additional options of "ro" to tell the
kernel to initially mount the root FS read only, while "root=/dev/sdb1"
identifies our root partition.  After 'kernel', we specify an initial
ramdisk to use via 'initrd' ([TAB] autocompletion can be used here
as well):
        grub> kernel /boot/vml[TAB]

        grub> kernel /boot/vmlinuz-2.6.18-164.el5 ro root=/dev/sdb1
           [Linux-bzImage, setup=0x1e00, size=0x1c31b4]

        grub> initrd /boot/initrd-2.6.18-164.el5.img
           [Linux-initrd @ 0x37d73000, 0x27c402 bytes]

        grub>
As an aside, if either the kernel or ramdisk cannot be found, grub will
return the following:
        grub> kernel /boot/trash[TAB]
        Error 15: File not found

        grub> kernel /boot/trashfile

        Error 15: File not found
In this case, if the file is your kernel and you are typing out the
correct path, you will need to either re-install your kernel or recover it
from backups.  The same applies for the ramdisk, though you may also have
the additional option of using 'mkinitrd' from an alternate boot disk.
After setting the root disk, the kernel file, and the ramdisk, we can
tell GRUB to boot the system which will bring us to our login prompt:
        grub> boot

        # system boots up

        CentOS release 5.4 (Final
        Kernel 2.6.18-164.el5 on an i686

        tux login: _
With the system up, we verify that neither grub.conf nor menu.lst exist,
check if there is a volume label on our root disk, and verify the file
names of our ramdisk and kernel:
        tux [0] /bin/ls -l /boot/grub/grub.conf /boot/grub/menu.lst
        /bin/ls: /boot/grub/grub.conf: No such file or directory
        /bin/ls: /boot/grub/menu.lst: No such file or directory
        tux [2] /sbin/tune2fs -l /dev/sdb1 | /bin/grep name:
        Filesystem volume name:   /2
        tux [0] /bin/ls /boot | /bin/egrep 'vmlinuz|initrd'
        initrd-2.6.18-164.el5.img
        vmlinuz-2.6.18-164.el5
        tux [0]
At this point, we need to create a new configuration file to boot the
host without futher intervention.  Using your favorite text editor
(vi?), create "grub.conf" with the following, or similar, tailoring it
to your needs:
        tux [0] /bin/cat /boot/grub/grub.conf
        default=0
        timeout=5
        title CentOS
                root (hd1,0)
                kernel /boot/vmlinuz-2.6.18-164.el5 ro root=LABEL=/2
                initrd /boot/initrd-2.6.18-164.el5.img
Of note, rather than specifying the exact disk for root as we did from
the GRUB prompt, we've configured "grub.conf" with root using the volume
label (/2) that was returned from 'tune2fs -l'.  Since we are using
CentOS (a Red Hat clone), "menu.lst" is a symlink back to "grub.conf".
Use 'ln -s' to recreate the symlink and verify it:
        tux [0] /bin/ln -s /boot/grub/grub.conf /boot/grub/menu.lst
        tux [0] /bin/ls -l /boot/grub/grub.conf /boot/grub/menu.lst
        -rw-r--r-- 1 root root 141 Jan 17 17:58 /boot/grub/grub.conf
        lrwxrwxrwx 1 root root  20 Jan 17 17:59 /boot/grub/menu.lst -> /boot/grub/grub.conf
With our work complete, the only thing left to do is reboot and verify
our work.  Aside from telling the BIOS to boot disk 2, no further
interaction occurs:
        tux [0] /sbin/reboot

    Output after telling the BIOS to use disk 2:

         GNU GRUB  version 0.97  (639K lower / 1047488K upper memory)

        CentOS


           Use the <up> and <down> keys to select which entry is highlighed.
           Press enter to boot the selected OS, 'e' to edit the
           commands before booting, 'a' to modify the kernel arguements
           before booting, or 'c' for a command-line.

        The highlighted entry will be booted automatically in 5 seconds.

    After timeout, the "CentOS" option is automatically booted:

          Booting 'CentOS'

        root (hd1,0)
         Filesystem type is ext2fs, partition type 0x83
        kernel /boot/vmlinuz-2.6.18-164.el5 ro root=LABEL=/2
           [Linux-bzImage, setup=0x1e00, size=0x1c31b4]
        initrd /boot/initrd-2.6.18-164.el5.img
           [Linux-initrd @ 0x37d73000, 0x27c402 bytes]
        <snip...> 

        CentOS release 5.4 (Final
        Kernel 2.6.18-164.el5 on an i686

        tux login: _

see also:
    GRUB, a Corrupted MBR, and Linux