### How to make my OpenSUSE installation boot via PXE ###
       
       
       Booting from PXE is amazing. It allows one to have computers without a hard disk (no vibration, no heat, no noise, no maintenance...).
       Few days ago, I decided to remove hard disks of all my workstation PCs at home, and make them boot via PXE.
       My distribution of choice (as far as we're talking about workstations) is OpenSUSE, therefore I will describe here how to boot an OpenSUSE system from the network, using PXE, TFTP, DHCP, NFS, and a little bit of magic.
       Of course, this is not only true for OpenSUSE, and should be adaptable without major changes to any modern Linux distribution.
       
       
        * The "big picture" *
       
       The whole idea is this: the workstation starts, and the BIOS of the network card (that must provide support for PXE booting) asks for a DHCP lease.
       The local DHCP server provides it with an IP address, a mask, a gateway, and feeds it with a "next-server" DHCP option, along with a "filename" option.
       The "next-server" field contains the IP address of a local TFTP server, and the "filename" field contains the filename of the PXE image that should be loaded from the TFTP server.
       Now, the PC loads the PXE image from the TFTP server. I am using the excellent PXELINUX loader (pxelinux.0).
       When PXELINUX starts, it loads a configuration file from the TFTP server (pxelinux.cfg/default), that contains the menu to display to the user, with corresponding kernel images. The user choose an image, and then PXELINUX loads both a kernel image (usually vmlinuz) and an init ram disk (usually initrd). This is still done via TFTP. One the kernel and init ram disk are loaded into the PC's RAM memory, the Linux kernel starts. We will have to instruct the kernel to mount the root ("/") over NFS (and not on a disk device, like on normal machines). For this, we will need to provide the IP of our NFS server, as well as the path on the server that points to our root filesystem. And basically, that's it! The biggest trouble is to bind all this mess together, so the chained boot process works for every step. :)
       
       Let's see the configuration of most important parts of our PXE architecture.
       
       
        * DHCP *
       
       I won't discuss DHCP configuration. It's pretty trivial, so you can figure it out by yourself. The only thing you need to do is to make sure that the DHCP server provides a "next-server" with the IP of your TFTP server as a value, along with the filename of the PXE loader (pxeloader.0).
       
       
        * PXELINUX *
       
       The PXE boot is assured by pxelinux. The configuration file of pxelinux is rather straight-forward. Here is a section for booting OpenSUSE with a NFS root directory:
       
       label OpenSUSE
           menu label OpenSUSE
           kernel suse_martyna/boot/vmlinuz
           append initrd=suse_martyna/boot/initrd rootfstype=nfs root=/dev/nfs nfsroot=192.168.190.5:/srv/tftp/suse_martyna ip=dhcp rw noresume
       
       
        * INITRD *
       
       to prepare the mkinitrd:
       mkinitrd -f nfs -D eth0
       
       This will add the required kernel modules and a dhcp client to the initrd, which will try to get an IP address via eth0.
       If your network card isn't working at initrd boot stage, you might want to specificaly add its module to the INITRD_MODULES list in /etc/sysconfig/kernel (it contains the list of modules to incorporate into the initrd image by mkinitrd).
       You also might try to use "mkinitrd -A -D eth0", this one will generate a "monster" initrd, containing all possible features and modules.
       
       WARNING: On OpenSUSE 11.4 (and maybe other versions) there is a bug that makes it impossible to mount a NFS root from a NFSv3 server, because the protocols and netconfig files are missing from /etc. Here is a quick fix for that:
       To fix it, I did on the nfs server, as root:
       
       # cd <exported directory for the client's home>
       # chroot .
       # cd /boot
       # mkdir img
       # cd img
       # gzip -cd /boot/initrd | cpio -imd --quiet
       # cp /etc/{protocols,netconfig} etc
       # find . | cpio --quiet -H newc -o | gzip -9 -n > /boot/initrd_patched
       # cd /boot
       # rm initrd
       # ln -s initrd_patched initrd
       # exit
       
       
        * Root directory content *
       
       Then rsync your fs (offline, eg. via a liveCD) to the remote server:
       rsync -a /mnt/mydisk /srv/nfs/suse_root
       
       
        * FSTAB *
       
       in the fstab, replace the / entry with:
          none             /                none
        or (dunno which one is better)
          /dev/nfs         /                 nfs
       
       
        * Other bits to know about *
       Make sure that the network script won't be able to run (if it does, it could crash your system, because your root fs is mounted over the network, remember?):
       chmod -x /etc/init.d/network
       
       Export the NFS share containing the root filesystem as such:
       /srv/tftp/suse_root/         192.168.190.24(rw,no_root_squash,no_subtree_check)
       
       If you get a "FIBMAP: invalid argument" error after or during the boot of your PC, it probably means that your system is trying to use the preload optimization, as this seems to be caused by preload. Try to uninstall the "preload" thing...