Ubuntu ZFS Root

From Mark Furneaux's Wiki
Jump to: navigation, search

Ubuntu does not support installing to a ZFS root filesystem as of 16.04. This guide serves as a workaround.


  1. Boot a live USB
  2. Add the GRUB BIOS partition by running:
    sgdisk -a1 -n2:34:2047 -t2:EF02 /dev/disk/by-id/ata-DISK
  3. Use parted/gparted to create the rest of the partition table
  4. Run:
    apt update
    apt install zfsutils-linux
    zpool create -f -o ashift=12 -O compression=lz4 -O xattr=sa -O mountpoint=none rootpool /dev/disk/by-id/ata-DISK-partN
    zfs create -V 10G rootpool/tempdisk
    zfs create -o mountpoint=none rootpool/ROOT
    zfs create -o mountpoint=/ rootpool/ROOT/hostname
    zpool export rootpool
    zpool import rootpool -R /mnt
    zfs create rootpool/ROOT/hostname/boot
    zfs create rootpool/ROOT/hostname/etc
    zfs create rootpool/ROOT/hostname/home
    zfs create rootpool/ROOT/hostname/tmp
    zfs create rootpool/ROOT/hostname/usr
    zfs create rootpool/ROOT/hostname/var
    zpool set bootfs=rootpool/ROOT/hostname rootpool
  5. Run the installer, selecting /dev/zd0 as the install drive with an ext4 partiton. The bootloader should be set for installation on /dev/zd0. The bootloader install will fail. Continue without a bootloader. Do not reboot once the install is finished.
  6. Run:
    mkdir /media/temp
    mount /dev/zd0p1 /media/temp
    rsync -aAXvH /media/temp/* /mnt --exclude={/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}
    for i in /dev /dev/pts /proc /sys /run; do mount -B $i /mnt$i; done
    chroot /mnt
    apt install zfs-initramfs
    ln -s /dev/disk/by-id/ata-DISK-partN /dev/ata-DISK-partN
    grub-install /dev/disk/by-id/ata-DISK
  7. Remove any entries in /etc/fstab referencing the previous temporary root filesystem
  8. Add "boot=zfs" to /etc/default/grub in GRUB_CMDLINE_LINUX
  9. Install your custom kernel and ZFS modules at this point. It appears that the Ubuntu stock modules will not boot properly since the nested datasets aren't mounted fast enough. Add your custom repository and key, then do something along the lines of:
    apt install linux-image-4.9* linux-headers-4.9* linux-firmware-image-4.9* kmod-spl-4.9* kmod-zfs-4.9* zfs zfs-initramfs
    depmod -a
    You may need to run the apt command twice since it is in a chroot.
  10. Run:
    for i in /dev/pts /dev /proc /sys /run; do umount /mnt$i; done
    umount /media/temp
    zfs destroy rootpool/tempdisk
    zfs snapshot -r rootpool@factory
    zpool export rootpool
  11. Reboot
  12. Setup the apt mirror, run updates, etc. Note that everytime the bootloader is updated, the symlink in /dev will need to be created beforehand.
  13. Set zfs-auto-snapshot user parameters as appropriate:
    zfs set com.sun:auto-snapshot=true rootpool
    for i in daily weekly monthly frequent hourly; do zfs set com.sun:auto-snapshot:$i=true rootpool; done
    apt install zfs-auto-snapshot