From ArchWiki
Revision as of 13:23, 9 October 2012 by Buhman (talk | contribs) (Client Configuration)
Jump to: navigation, search

Template:Article summary start Template:Article summary text Template:Article summary heading Template:Article summary wiki Template:Article summary wiki Template:Article summary wiki Template:Article summary end

This allows you to

Server configuration

You will need a DHCP server to setup networking, as well as a TFTP server to transfer the boot image (a requirement of all PXE option roms).


Install ISC dhcp.

# pacman -Syu dhcp

Configure ISC DHCP.

# vim /etc/dhcpd.conf
allow booting;
allow bootp;


option domain-name-servers;

    filename "pxelinux.0";

    subnet netmask {
        option routers;
Note: next-server should be the address of the TFTP server; everything else should be changed to match your network


# systemctl start dhcpd

Or if you use sysvinit,

# rc.d start dhcpd


# vim /etc/xinetd.d/tftp
service tftp
    per_source = 11
    socket_type = dgram
    protocol = udp
    user = root
    server = /usr/sbin/tftpd
    server_args = /mnt/arch/boot
    wait = yes
    cps = 100 2

Network storage

The primary difference between using NFS and NBD is while with both you can in fact have multiple clients using the same installation, with NBD (by the nature of manipulating a filesystem directly) you'll need to use the copyonwrite mode to do so, which ends up discarding all writes on client disconnected. In some situations however, this might be highly desirable.


Install nfs-utils on the server.

# pacman -Syu nfs-utils

You'll need to add the root of your arch installation to your NFS exports.

# vim /etc/exports
/mnt/arch *(rw,fsid=0,no_root_squash,no_subtree_check,async)

Start rpcbind, nfs-common, and nfs-server.

# rc.d start rpcbind nfs-common nfs-server

Add them to the DAEMONS array in rc.conf if you'd like this to happen on boot.

Additional information can be found in the NFS article.


Install nbd.

# pacman -Syu nbd

Configure nbd.

# vim /etc/nbd-server/config
    exportname = /mnt/arch.img
    copyonwrite = false
Note: Set copyonwrite to true if you want to have multiple clients using the same NBD share simultaneously; refer to man 5 nbd-server for more details.

Client installation

Directory setup

Create a sparse file of at least 5 gigabytes, and create an ext4 filesystem on it (you can of course also use a real block device or LVM if you so desire).

# truncate -s 5G /mnt/arch.img
# mkfs.ext4 /mnt/arch.img
# mkdir -p /mnt/arch
# mount /mnt/arch.img /mnt/arch
Note: Creating a separate filesystem is required for NBD but optional for NFS and can be skipped/ignored

First, create a directory that will contain the Arch installation; replace /mnt/arch with wherever you'd like to put your installation.

# export root=/mnt/arch
# mkdir -p "$root/{proc,sys,run,tmp}"
# mkdir -p "$root/dev/{pts,shm}"

This also creates the directories that will be used for the API filesystem mountpoints later. Next we create the directory that pacman stores its database.

# mkdir -p "$root/var/lib/pacman"

Bootstrapping installation

Mount the Linux API filesystems.

# mount -t proc proc "$root/proc" -o nosuid,noexec,nodev
# mount -t sysfs sys "$root/sys" -o nosuid,noexec,nodev
# mount -t devtmpfs udev "$root/dev" -o mode=0755,nosuid
# mount -t devpts devpts "$root/dev/pts" -o mode=0620,gid=5,nosuid,noexec

Install the essential packages needed. Of particular interest is mkinitcpio-nfs-utils; this is the dark sorcery that will mount our root filesystem from the NFS server during early-boot.

# pacman -Syu --root "$root" --dbpath "$root/var/lib/pacman" base base-devel --arch x86_64

Replace x86_64 with i686 as appropriate for your target hardware.

Next, edit "$root/etc/mkinitcpio.conf" and add nfs to the MODULES array, and add net after udev to the HOOKS array.

# vim "$root/etc/mkinitcpio.conf"
HOOKS="base udev net autodetect filesystems"
Note: Add nbd after the net hook if you are using NBD.

The initramfs now needs to be rebuilt; the easiest way to do this is chroot.

# chroot "$root" /bin/bash
(chroot) # mkinitcpio -p linux
# exit

Finally, cleanup by unmounting all of the virtual filesystems we mounted earlier.

umount \
    "$root/dev/pts" \
    "$root/dev" \
    "$root/sys" \

Client configuration

In addition to the setup mentioned here, you should also set up your hostname, timezone, locale, and keymap.


Install syslinux.

# pacman -Syu syslinux

Copy the pxelinux bootloader (provided by the syslinux package) to the boot directory of the client.

# cp /usr/lib/syslinux/pxelinux.0 "$root/boot"
# mkdir "$root/boot/pxelinux.cfg"

We also created the pxelinux.cfg directory, which is where pxelinux searches for configuration files by default. Because we don't want to discriminate between different host MACs, we then create the default configuration.

# vim "$root/boot/pxelinux.cfg/default"
default linux

label linux
kernel vmlinuz-linux
append initrd=initramfs-linux.img rootfstype=nfs root=/dev/nfs nfsroot=,v4,rsize=16384,wsize=16384 ip=:::::eth0:dhcp

Or if you are using NBD, use the following append line:

# append initrd=initramfs-linux.img root=/dev/nbd0 nbd_host= nbd_name=arch ip=:::::eth0:dhcp
Note: You will need to change nbd_host and/or nfsroot, respectively, to match your network configuration (the address of the NFS/NBD server)

The pxelinux configuration syntax identical to syslinux; refer to the upstream documentation for more information.

The kernel and initramfs will be transferred via TFTP, so the paths to those are going to be relative to the TFTP root. Otherwise, the root filesystem is going to be the NFS mount itself, so those are relative to the root of the NFS server.

VFS mountpoints

Add hacks to your fstab for the root filesystem and devpts.

# vim "$root/etc/fstab"
none    /           none
none    /dev/pts    devpts    gid=5,mode=620    0 0

Late-boot networking

This is to prevent the client from trying to reconnect the network and killing itself. Any disconnect of the network and your client will freeze.

The following workaround involves running the dhcpcd DHCP client on start-up with the -s option to use the existing kernel DHCP auto-configured IP address instead of requesting a new one.

# vim "$root/etc/conf.d/dhcpcd"
DHCPCD_ARGS=" -s $(ifconfig eth0 | grep -o '[0-9]*\.[0-9\.]*' | head -n1)"
# vim "$root/etc/rc.conf"

Client boot

If all goes right, you should see the network card get an IP address from the server, then connect and boot the kernel. After the initial kernel messages, you should either see Arch Linux boot, or a "killed init" message.