Live-System - Diskless / Live over Network setup

Prerequisites

Network Live-System booting requires:

  • a NFS server,
  • a DHCP + TFTP server; examples: (ISC-DHCP + TFTP-HPA) or DNSMasq (fulfilling both roles, and retained for this documentation),
  • a Network Bootstrap Program (NBP); examples: GRUB or PXELinux.

Install server packages (Arch Linux):

pacman -S dnsmasq nfs-utils syslinux
PXELINUX="/usr/lib/syslinux/bios/pxelinux.0 /usr/lib/syslinux/bios/ldlinux.c32" #BIOS
#PXELINUX="$PXELINUX /usr/lib/syslinux/efi64/syslinux.efi /usr/lib/syslinux/efi64/ldlinux.e64" #UEFI

Install server packages (Slackware):

slackpkg install dnsmasq nfs-utils
PXELINUX="/usr/share/syslinux/pxelinux.0" #BIOS only

Install server packages (Ubuntu):

apt install dnsmasq nfs-kernel-server pxelinux syslinux-efi grub-pc
PXELINUX="/usr/lib/PXELINUX/pxelinux.0 /usr/lib/syslinux/modules/bios/ldlinux.c32" #BIOS
#PXELINUX="$PXELINUX /usr/lib/SYSLINUX.EFI/efi64/syslinux.efi /usr/lib/syslinux/modules/efi64/ldlinux.e64" #UEFI

Rebuild live InitRamFS:

NFS (v3 - unable to use v4 yet) as well as the ethernet drivers (of the diskless machines) must be embeded in the live InitRamFS.

  • To find out the ethernet kernel module name, run: sh lspci -k | grep -A 3 Ethernet
  • Run --init action, with additional modules, eg: sh build-live-system.sh --init system live nfsv3:e1000e:8139too:atl1c:alx

Live-System setup

Variables initialization:

srvmsk=$(ip a | grep "inet " | sed -e '/ lo/d' -e 's/ \+/:/g' | cut -f3 -d:)
srv=$(echo $srvmsk | cut -f1 -d/)
msk=$(echo $srvmsk | cut -f2 -d/)
rngbeg="$(echo $srv | cut -f1-3 -d.).100"
rngend="$(echo $srv | cut -f1-3 -d.).200"
gw=$(ip r | grep default | cut -f3 -d' ')
live=   #/path/to/modules/parent/directory (eg: live/linomad)
tftp=/tftpboot

DHCP + TFTP

TFTP files (common)

Populate the $tftp directory with the linux kernel and initial RAM disk: sh mkdir -p $tftp/linomad cp $live/linomad/vmlinuz $tftp/linomad/ chmod a+r $tftp/linomad/vmlinuz cp $live/linomad/initrd.gz $tftp/linomad/

TFTP files (GRUB)

mkdir $tftp/grub
grub-mkimage -p /grub -O i386-pc-pxe -o $tftp/grub/grub.0 pxe tftp normal boot configfile linux multiboot all_video
grub-mkimage -p /grub -O x86_64-efi -o $tftp/grub/grub.efi efinet tftp normal boot configfile linux multiboot all_video
cat > $tftp/boot/grub/grub.cfg << EOF
set gfxpayload=keep
menuentry "Live-System" {
    linux /linomad/vmlinuz sys=$srv:$live max_loop=255 locale=fr_FR.UTF-8 keymap=fr tz=Europe/Paris hwc=UTC ip=\$net_default_ip:$srv:$gw:$msk
    initrd /linomad/initrd.gz
}
EOF

The ip string follows the PXELinux structure: host:pxe_server:gateway:netmask/cidr. GRUB sets the $net_default_ip environment variable from the IP address obtained by DHCP.

If booting on BIOS doesn’t work, it is likely because GRUB hasn’t been patched. Apply TFTP module patch and recompile GRUB, or use PXELinux instead.

TFTP files (PXELinux)

cp $PXELINUX $tftp/
mkdir $tftp/pxelinux.cfg
cat > $tftp/pxelinux.cfg/default << EOF
DEFAULT LiNomad
LABEL LiNomad
    LINUX /linomad/vmlinuz
    INITRD /linomad/initrd.gz
    IPAPPEND 1
    APPEND sys=$srv:$live max_loop=255 locale=fr_FR.UTF-8 keymap=fr tz=Europe/Paris hwc=UTC
EOF

Note: paths are relative to PXELinux root. This is why PXELinux files aren’t put in a pxelinux subfolder.

Configure DNSmasq:

Configure DNSMasq as a DHCP + TFTP server (using PXELinux for BIOS and GRUB for UEFI): sh cat >> /etc/dnsmasq.conf << EOF #port=0 #disable DNS dhcp-range=$rngbeg,$rngend,12h dhcp-option=option:router,$gw enable-tftp tftp-root=$tftp dhcp-match=set:efi-x86_64,option:client-arch,7 dhcp-match=set:efi-x86_64,option:client-arch,9 #dhcp-boot=/grub/grub.0 dhcp-boot=/pxelinux.0 dhcp-boot=tag:efi-x86_64,/grub/grub.efi #dhcp-boot=tag:efi-x86_64,/syslinux.efi EOF See rfc4578 for client-arch values.

Enable and start DNSmasq service (Arch Linux & Ubuntu):

systemctl enable dnsmasq
systemctl start dnsmasq

If DNSmasq refuses to start because port 53 is already in use, try to stop systemd-resolved service.

Enable and start DNSmasq service (Slackware):

chmod +x /etc/rc.d/rc.dnsmasq
/etc/rc.d/rc.dnsmasq start

NFS

Configure the NFS export directory:

cat >> /etc/exports << EOF
$(dirname $(dirname $live)) *(rw,fsid=0)
$(dirname $live) *(ro,async,no_root_squash)
EOF

Enable and start the NFS server (Arch Linux):

systemctl enable nfs-server
systemctl start nfs-server

Enable and start the NFS server (Slackware):

chmod +x etc/rc.d/rc.nfsd
etc/rc.d/rc.nfsd start

Enable and start the NFS server (Ubuntu):

systemctl enable nfs-kernel-server
systemctl start nfs-kernel-server

Abbréviations

  • DHCP

: Dynamic Host Control Protocol - NFS : Network File System - PXE : Preboot Execution Environment - TFTP : Trivial File Transfer Protocol