Things change. In an enterprise enviroment, sometimes we’re surprised adding a new hardware component inside a server and the Linux won’t boot up properly. Or maybe you’re just virtualizating (by P2V) a server and faced this problem too, once the original hardware isn’t compatible with the virtual infrasctructure provided by your new hypervisor. And the “Kernel Panic: Unable to sync VFS“, or just a single-user shell with a incomplete Linux kernel waiting for your action (as you would do something!) is the only thing you’re getting.
Luckily, it’s really easy to fix it.
In my case I added a fibre channel card in some servers of my company. All the servers will now access my storage device, and the same storage is already configured to receive the servers’ requisitions.
All the servers will not boot from the storage device. They all will keep booting the OS from the local array and disks, but I need the lpfc.ko module loaded from boot to mount a few directories by fstab (a /usr/sag, a /u02 and a /u03 from an ADABAS and a Oracle servers).
I don’t need to reinstall the OS to solve this problem, I just need to recreate the initrd file and put the module inside it. To do this I will use the mkinitrd program, but the sintax is different to a Linux distribution from another…
So If I don’t update the initrd file, all the LUNs will be detected later by udev, and the respective services may crash by trying to start some applications without any data inside the pointed directories. And a disaster may occour.
The first system: A Suse Linux Enterprise Server 10.2
I think the suse’s mkinitrd it’s the easiest mkinitrd command I’d already tried. You can be sure by reading the manual with the “man mkinitrd” command. To do what we want, you need only to edit the /etc/sysconfig/kernel file using vi:
Now, look for the INITRD_MODULES line and add the module you need inside the quotes:
INITRD_MODULES=”lpfc ide-core ide-disk scsi-mod sd_mod scsi_transport_spi mptbase mptscsih mptspi piix ata_piix processor thermal fan reiserfs edd”
Backup your current initrd file: check your /boot/initrd symlink and backup the original initrd ramdisk. Just recreate the initrd file with the command:
mkinitrd -d /dev/sda2
(where /dev/sda2 is your root device. Check your /etc/fstab file or “mount” command)
If the command finished well, it creates a /boot/initrd-your-kernel-version-and-patches.img file. Update your boot menu (usually in the /boot/grub/menu.lst file) and reboot your server to test if your new hardware device was now detected correctly at boot. Quite easy, a piece of cake!
The another systems: A RHEL 5.5 and a CentOS 5.5 and 5.4
Now I’d just finished my suse server, there’s still a Red Hat (and based) servers waiting for the same update. In RHEL/CentOS and Fedora, there’s no /etc/sysconfig/kernel to mkinitrd read. mkinitrd will read the /etc/modprobe.conf and /etc/modprobe.d/* files, and the sintax is a quite different.
When everything works well, you just need to append “alias your-module your-module”, “alias your-module some-alias” or “install your-module /bin/true” in this file (/etc/modprobe.conf). So re-create the initrd using the following command:
mkinitrd -v -f /boot/your-new-initrd-file.img $(uname -r)
Warning! Pay attention on the text output: Sometimes the module isn’t inserted as it should! If mkinitrd did it, you’ll need to specify this module to mkinitrd by hand:
mkinitrd -v -f /boot/new-initrd.img $(uname -r) –with=lpfc
According the manual, with the “–with” tag, mkinitrd command include the specified module to load after all the SCSI modules. This is what I want, but maybe you need to load a driver before the SCSI modules subsystem. So replace the “–with” parameter by “–preload“.
Now your new initrd file is ready. Update your /boot/grub/menu.lst file and reboot your server to check if everything worked fine.
That’s all, folks!