After using ZFS on FreeNAS and then using btrfs on Linux , I was curious to see how ZFS on Linux stacked up against btrfs. I attempted setting up Arch Linux on ZFS around a year ago and after running into multiple problems I abandoned the thought of getting it working. With all the talk recently in the Linux community, I was curious to see if the process had changed at all in the last year and if I could get it running successfully.

In this multi-part series I go through the process of getting Arch Linux running using ZFS as the root file system. In the first section I will explain how to get ZFS on the install media itself so that Arch can be easily installed from the ISO. If you plan to install Arch a different way you can skip to part two for an explanation of the install process.

Part One - Pre-Install Process Link to heading

Since the default install image of Arch Linux does not support ZFS as a file system, the easiest way to install Arch using ZFS is to build a live install image with all the necessary packages installed. While this might sound complicated, the tool Archiso contains everything required to build a new image from scratch. In fact Archiso is what the Arch Linux project uses to build the official images you can download from the site. In order to use Archiso an Arch Linux system is required to build the image.

Preparing the Archiso Image Link to heading

Requirements Link to heading

To use Archiso, the package archiso is needed. Archiso should only be used on an x86_64 system.

Install the package

[root]# pacman -S archiso

Setup Link to heading

Note: To avoid permissions problems with the image, it is recommended to use the root user for all the Archiso steps.

Archiso comes with a customizable profile releng located in /usr/share/archiso/configs/releng, copy the contents to a location for customizing.

[root]# cp -r /usr/share/archiso/configs/releng/* ~/archlive

Archiso Hierarchy Link to heading

The Archiso directory should contain four folders, airootfs, efiboot, isolinux and syslinux, and six files, build.sh, packages.both, packages.i686,packages.x86_64,pacman.conf, and mkinitcpio.conf.

The only files and folders to be concerned with are:

  • airootfs/
    • Acts as / of final image
    • Any files and folders that are wanted should be copied here.
  • packages.both, packages.i686, packages.x86_64
    • Any packages that should be installed onto the final image should be listed in these files.
    • If any of the packages are architecture dependent they should be put in either the i686 or x86_64 package file. Otherwise they should be listed in packages.both.
  • pacman.conf
    • The package manager configuration file.
    • List any additional repositories here.
archlive
| # Important files and folders:
├── airootfs # Make customizations here
│   ├── etc
│   │   ├── # configuration files...
│   │   └── # ...
│   └── root
│       ├── customize_airootfs.sh
│       └── install.txt
├── build.sh # Used to build ISO
| # Customizable files:
├── packages.both
├── packages.i686
├── packages.x86_64
├── pacman.conf
| # Other files and directories
├── mkinitcpio.conf
├── efiboot
│   └── # bootloader files...
├── isolinux
│   └── isolinux.cfg
└── syslinux
    └── # syslinux files...

Customizing The Image Link to heading

Adding Packages Link to heading

Add The ZFS Repository Link to heading

Using Archiso it is easy to specify which packages need to be installed onto the image and any commands that should be be run to set the image up. The easiest way to add ZFS to the image is to use the user repository archzfs. In order to use the archzfs repository, it must be added to the list of repositories in the pacman.conf file.

Edit the pacman.conf file:

[root]# nano ~/archlive/pacman.conf

Above the other repositories [core], [extra] and [community], add [archzfs].

#
# /etc/pacman.conf
#
# See the pacman.conf(5) manpage for option and repository directives

#
# REPOSITORIES

[archzfs]
SigLevel = Optional TrustAll
Server = http://archzfs.com/$repo/x86_64

# Other repositories...

Add The ZFS Package Link to heading

Next, add the zfs-linux group to the list of packages to be installed in ~/archlive/packages.x86_64, it might be the only package in the list.

[root]# nano ~/archlive/packages.x86_64
#
# ~/archlive/packages.x86_64
#

zfs-linux

Other Packages Link to heading

If any administration is going to be done on the live image over SSH, make sure the openssh package is in packages.both.

Running Administrative Commands Link to heading

If any commands need to run such as starting SSH, adding users and the such, they should be listed in the ~/airootfs/root/customize_airootfs.sh file.

 [root]# nano ~/archlive/airootfs/root/customize_airootfs.sh

If SSH will be used, add a user, set their password and root’s password, and start sshd in the bottom of ~/archlive/airootfs/root/customize_airootfs.sh.

# Add user ssh_user with no home directory, in group 'wheel' and using 'zsh'
# Alternatively add a root password
useradd -M -G wheel -s /usr/bin/zsh ssh_user

# Set ssh_user password
echo "ssh_user:ssh_user-password"|chpasswd
echo "root:root-password"|chpasswd

# Enable ssh
systemctl enable sshd.service

Adding Files Link to heading

If any scripts are needed, copy them to ~/archlive/airootfs. They will end up relative to / in the final image.

Build The Image Link to heading

I like to copy the final archlive directory to /tmp and build my images there, this keeps the original directory I made the changes in clean. Run build.sh to generate the image.

[root]# cp -r archlive/ /tmp
[root]# cd /tmp/archlive/
[root]# mkdir out
[root]# ./build.sh -v

To build the image, make the directory out in archlive, the final image will end up there.

Kernel Mismatch Link to heading

If an error occurs stating a different kernel is required, and archzfs hasn’t updated to that version, a workaround is using a local repo to add the kernel required by archzfs.

Local Repository Link to heading

Create the file structure for a local repo we are calling ‘customrepo’.

[root]# mkdir -p /root/{customrepo/x86_64,pkg}

Download required package(s) from the package archive to /root/pkg. Replace ${version} with the required version.

[root]# cd /root/pkg
[root]# wget "https://archive.archlinux.org/packages/l/linux/linux-${version}-x86_64.pkg.tar.xz"

Create the local repo

[root]# repo-add /root/customrepo/x86_64/customrepo.db.tar.gz /root/pkg/linux-4.10.13-1-x86_64.pkg.tar.xz

Edit archlive adding the repo.

[root]# nano /root/archlive/pacman.conf
[customrepo]
SigLevel = Optional TrustAll
Server = file:///root/customrepo/$arch

Now archlive can be built as done previously.

[root]# mkdir /tmp/archlive/
[root]# cp -r /root/archlive/ /tmp
[root]# cd /tmp/archlive/ && mkdir out
[root]# ./build.sh -v

Using The Image Link to heading

The image can be burned to a usb drive.

Find the correct drive with lsblk.

[root]#  lsblk
NAME    MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdx       8:48   0 447.1G  0 disk
└─sdxY    8:49   0 447.1G  0 part

Once the correct drive /dev/sdx is found, write to a usb drive with dd. This will destroy anything on the drive. Make sure to select the entire drive sdx, not a number sdxY.

[root]# dd bs=4M if=archlinux-2016.01.29-dual.iso  of=/dev/sdx status=progress && sync

Once finished the drive should be bootable and ready for installation.

In the next section I will go over the installation process.