Today I’m facing a kernel upgrade in our company legacy systems. Particularly our systems boot from an NFS/Ramdisk, so we’ll require to have enabled:

  • NFS (filesystem and utilities)
  • Networking
  • DHCP

In our Initrd.

Also we are passing boot options to the VM with the NFS mount point for the rootfs as this:

Boot Options: console=ttys0 xencons=tty1 ip=dhcp nfsroot=mynfsserver.domain/resource/myrootfs nfshost=mynfsserver.domain

And the objective would be to upgrade this:

THISSERVER:~ # uname -a
Linux THISSERVER #1 SMP 2010-07-20 14:12:19 +0200 x86_64 x86_64 x86_64 GNU/Linux
THISSERVER:~ # cat /etc/issue
Welcome to SUSE Linux Enterprise Server 11 (x86_64) - Kernel \r (\l).

to this (which is the final result :D):

THISSERVER:~ # uname -a
Linux THISSERVER 3.0.76-0.11-xen #1 SMP Fri Jun 14 08:21:43 UTC 2013 (ccab990) x86_64 x86_64 x86_64 GNU/Linux
THISSERVER:~ # cat /etc/issue

Welcome to SUSE Linux Enterprise Server 11 (x86_64) - Kernel \r (\l).

What we need to change in order to upgrade the kernel

Two files:

  • The kernel itself, also called vmlinuz-<version>
  • Initrd (small filesystem before our /root), also called: initrd-<version>

Those files we’ll be found in our boot partition/disk.

Where do I get the new Kernel and Initrd

We’ll need a new install of SuSe with the new kernel-to-be upgraded, fortunately someone saved an old ISO and I’ve installed the O.S from there in VirtualBox:

  • Linux.SLES-11-SP3-DVD-x86_64-GM-DVD2.iso

After the install is complete, we go to /boot:

So we’ll find:

Enabling Ping,DHCP, NFS, Networking and more in Initrd

Replacing those files in our old boot partition will be enough. But, as we mentioned we need to add certain modules and options to make our system work.

Because we want all the possible options and utilities to be enabled I’ve generated the new Initrd in this way:

mkinitrd -m "nfs e1000" -A -D eth0

Those parameters and options will be easily found on man mkinitrd(8)

Here’s a brief explanation:

  • -m «modules»: Loading nfs and the e1000 Ethernet driver
  • -A «monster» creates initrd with all the possible things you may need
  • -D Interface to start the dhcp

The SuSe website also has good information but always reefer to «man» for the exact parameters of your distribution.

You may ask, Isn’t redundant to load -m nfs e1000 when you are already calling -A? And I say, yes :p.

That’s it, after it’s generated copy your new initrd from /boot in your VM to the old computer, verify that both, kernel and Initrd are changed (respecting the symlinks) and that’s it.

If you need to decompress Initrd

Sometimes for debug or adding new scripts you need to decompress initrd, you can do it this way:

zcat initrd-<VERSION> |cpio -idvm

After you make the necessary changes, for example changing the initrd config of:

  • mkinitrd.config
  • udevrules
mkinitrd.config:-f nfs -I eth0

etc/udev/rules.d/70-persistent-net.rules:SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="*", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

config/[ "$ip" ] || ip=''

bin/    dev=eth0

or others…

You can compress it again (move to the directory were you decompressed the initrd) and:

find . | cpio -o -c | gzip -9 > /tmp/initrd-<version>

In /tmp/initrd-<version> you’ll find your new initrd.

If the NFS isn’t being loaded

Sometimes if you haven’t charged correctly the modules of DHCP the network interface won’t be up, that means NFS won’t be mounted and of course our O.S won’t start leaving us in the initrd CLI.

Try enabling your network interface (by dhcp in my case) in the initrd CLI as this:

dhclient eth0

Then execute ip addr and verify you have a valid IP address on your interface, then mount manually the NFS.

Finally press CTRL-D and the Init process will continue. If it fails check for new errors, if it works your problem is probably related to the Network Interface / DHCP / Fixed IP address on your initrd.