KDE Neon on ZFS

Based on this excellent guide.

WARNING:  You’re going to be messing with hard drives.  You’ll probably be doing most of this as root.  As the old adage goes, “The good thing about Linux is that it does exactly what you tell it to do.  The bad thing about Linux is that it does exactly what you tell it to do.”  I strongly recommend you to disconnect/remove drives you don’t want touched during this procedure so you don’t inadvertently wipe a disk you don’t want wiped.

Note: at the time of this writing, KDE Neon is based on Ubuntu 16.04 Xenial.

The whole process looks something like this:

  • Boot into Xenial Desktop live environment
  • Install ZFS packages in live environment
  • Prepare array
  • Debootstrap base system into array
  • Chroot into array
  • Install the rest of KDE Neon
  • Tweak
  • Reboot into new KDE Neon system on ZFS

This is really similar to the dotFiles Ubuntu 16.04 (Xenial) ZFS native root install guide I normally use, just with some KDE Neon bits thrown in. I’ve had a great time using KDE Neon, and I enjoy playing around with ZFS things, so naturally I had to combine them.  Read this guide all the way through at least once before starting just to have some idea what you’re in for.  I’ve made notes and highlighted things to draw attention where I believe they are helpful.  I mention it the end, but, if you get stuck, use the guide that I used as a reference.  I got most of my steps straight from his guide.  With that out of the way, lets get started!

Create and boot into Ubuntu 16.04 Xenial Desktop live media

I typically use a USB stick, but CD is ok, too. Get it here.


Install/Start SSH service in live environment

I’m usually doing this whole thing remotely, so I need to enable SSH access:

sudo -i
apt update && apt install -y openssh-server
passwd ubuntu

Probably a good idea to switch to root because most everything we’ll be doing requires administrative privileges:

sudo -i

Here we go!

Install packages

I had an issue where the repositories included with whatever version of Xenial install media I was using did not include ‘zfsutils-linux’. If that happens to you, I recommend using a repo generator in case /etc/apt/sources.list is outdated for some reason.

apt update && apt install -y zfsutils-linux debootstrap vim

Load ZFS kernel module

Issue the following:

modprobe zfs


root@ubuntu:~# lsmod | grep zfs
zfs                  2711552  3
zunicode              331776  1 zfs
zavl                   16384  1 zfs
zcommon                49152  1 zfs
znvpair                77824  2 zcommon,zfs
spl                    98304  3 znvpair,zcommon,zfs

udev things

Create /etc/udev/rules.d/90-zfs.rules with the following contents:

KERNEL=="sd*[!0-9]", IMPORT{parent}=="ID_*", SYMLINK+="$env{ID_BUS}-$env{ID_SERIAL}"
KERNEL=="sd*[0-9]", IMPORT{parent}=="ID_*", SYMLINK+="$env{ID_BUS}-$env{ID_SERIAL}-part%n"

Refresh symlinks to block devices:

udevadm trigger

Partition drive(s)

Double check the drive(s) you’re going to be messing with using lsblk:


Remove existing partition table with wipefs. Do this for each drive that will be used in your array:

wipefs -a /path/to/first/block/device
wipefs -a /path/to/next/block/device

Can verify using lsblk:


Partition drives to be in your pool using the following, adjusting paths to your specific needs (eg. /dev/sdX):

sgdisk -Z -n9:-8M:0 -t9:bf07 -c9:Reserved -n2:-8M:0 -t2:ef02 -c2:GRUB -n1:0:0 -t1:bf01 -c1:ZFS /path/to/first/block/device
sgdisk -Z -n9:-8M:0 -t9:bf07 -c9:Reserved -n2:-8M:0 -t2:ef02 -c2:GRUB -n1:0:0 -t1:bf01 -c1:ZFS /path/to/next/block/device

Use lsblk to verify creation of new partitions:



The following creates a ZFS pool named ‘rpool’ consisting of one RAID1 mirror comprised of two partitions. Again, adjust paths according to how Linux detected your drives, specifying partition 1 on that block device (eg. /dev/sda1):

zpool create -m none -o ashift=12 -O compression=lz4 rpool mirror /path/to/first/block/device1 /path/to/next/block/device1

Create root filesystem on array:

zfs create -o mountpoint=/ rpool/root


zpool status -v  # shows pool status
zfs list  # shows mountpoint

Export pool:

zpool export rpool

Import pool with correct device name(s) and mount on /mnt:

zpool import -d /dev/disk/by-id -R /mnt rpool


zpool status -v  # should show different device name(s)
zfs list  # should show mounted on /mnt

Get base system files into /mnt

This pulls a base system from the internet and dumps it into the directory specified (this might take a while depending on your internet connection):

debootstrap xenial /mnt

Can see the pool start to fill using zpool list -v:

watch zpool list -v  # exit with Ctrl-c

Copy /etc/udev/rules.d/90-zfs.rules we made earlier:

cp /etc/udev/rules.d/90-zfs.rules /mnt/etc/udev/rules.d/90-zfs.rules

Move old /mnt/etc/apt/sources.list out of the way:

mv /mnt/etc/apt/sources.list /mnt/etc/apt/sources.list.old

Create new /mnt/etc/apt/sources.list with the following contents (adjust to taste):

###### Ubuntu Main Repos
deb http://archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse 
deb-src http://archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse 

###### Ubuntu Update Repos
deb http://archive.ubuntu.com/ubuntu/ xenial-security main restricted universe multiverse 
deb http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted universe multiverse 
deb http://archive.ubuntu.com/ubuntu/ xenial-proposed main restricted universe multiverse 
deb http://archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse 
deb-src http://archive.ubuntu.com/ubuntu/ xenial-security main restricted universe multiverse 
deb-src http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted universe multiverse 
deb-src http://archive.ubuntu.com/ubuntu/ xenial-proposed main restricted universe multiverse 
deb-src http://archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse 

###### Ubuntu Partner Repo
deb http://archive.canonical.com/ubuntu xenial partner
deb-src http://archive.canonical.com/ubuntu xenial partner

###### KDE Neon Repo
deb http://archive.neon.kde.org/user xenial main
deb-src http://archive.neon.kde.org/user xenial main

Mount /dev, /proc, and /sys in preparation to chroot:

mount --rbind {,/mnt}/dev
mount --rbind {,/mnt}/proc
mount --rbind {,/mnt}/sys

Chroot into /mnt:

chroot /mnt /bin/bash --login


Initial tweaks

Generate locale:

locale-gen en_US.UTF-8

Install KDE Neon Key:

apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E6D4736255751E5D

Package installation

Update apt and install packages (gonna take a while).  Note: You may want to pick a different kernel version other than what’s currently running (as reported by uname -r). Distrowatch says KDE Neon is currently using 4.10, I’m using 4.10.0-42-generic.

NOTE: In my experience, some KDE Neon package (I think its a GRUB theme package) first creates /etc/default/grub with virtually nothing in it, then grub-pc gets installed, wants to make it again, and apt‘s not sure what to do. When apt gets confused, it asks you what it should do. In my experience, the best course of action is to choose “Use package maintainer’s version” when prompted. I don’t know in what order packages will be installed when you do this guide, so you should view differences just in case. If it has ‘>’ next to the line, that means it is in the new file. If you see a ton of lines with ‘>’ next to them, you do want to chose to use the package maintainers version. If not, keep the existing file. See the end of this post for my /etc/default/grub in the event of emergency.

apt-get update && apt-get install -y zfsutils-linux zfs-initramfs zfs-dkms zfs-zed linux-image-$(uname -r) linux-image-extra-$(uname -r) linux-headers-$(uname -r) grub2-common grub-pc acpi-support vim linux-firmware neon-desktop

When asked where GRUB should be installed, select the ZFS device(s).

Further tweaks

Make sure GRUB modules got installed:

root@ubuntu:/# find /boot -iname '*zfs*'

Set root’s password:

passwd root

Tell systemd to boot graphical.target by default:

systemctl set-default graphical.target

Add a user with sudo privileges:

adduser usernamegoeshere
usermod -aG sudo usernamegoeshere

In /etc/default/grub, change GRUB_CMDLINE_LINUX=”” to GRUB_CMDLINE_LINUX=”boot=zfs”:


Leave chroot:



Make sure GRUB knows the root filesystem is ZFS:

grub-probe /mnt

Install GRUB to boot sectors:

grub-install --root-directory=/mnt /path/to/first/block/device
grub-install --root-directory=/mnt /path/to/next/block/device


reboot now

Welcome to KDE Neon Desktop on ZFS! Enjoy!

Well, hopefully welcome. If you encounter issues, try going through the dotFiles guide that has been my go-to.  Don’t worry about the KDE Neon stuff, as that takes forever to install, just try to get a system booting at all.  If you can get that far, you can add the KDE Neon repositories and install Neon on top of that.

My /etc/default/grub, just in case:

# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
#   info -f grub -n 'Simple configuration'

GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`

# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)

# Uncomment to disable graphical terminal (grub-pc only)

# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'

# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux

# Uncomment to disable generation of recovery mode menu entries

# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE="480 440 1"


Leave a Reply

Your email address will not be published. Required fields are marked *