Skip to main content

Set up a ZFS Pool

Like every other OS, Ubuntu comes with its own default file system, which allows for the saving and loading of files and applications.

But, there is a file system for super-nerds called ZFS, which allows for significantly "safer" writing of files, and not only that: You can set up "mirrored disks".

We want a "mirrored disk" -- that is, two disks redundantly storing the same data -- for use with your Lightning node. This is because we will be storing important data, and you want to be protected should one of your disks fail. If a disk fails when you are "mirrored", then the other will continue working.

This gets a little technical

Let's look for our disks

Let's start on your Ubuntu desktop. Press CNTRL-ALT-T, and a terminal window will open on your desktop.

In the terminal window, you'll see a prompt like:

myusername@ubuntu:~$

First, we want to make sure that the system has recognized our drives. Run this command:

myusername@ubuntu:~$ lsblk

Here is my output

myusername@ubuntu:~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 4K 1 loop /snap/bare/5
loop1 7:1 0 303.3M 1 loop /snap/code/146
loop2 7:2 0 496.9M 1 loop /snap/gnome-42-2204/132
loop3 7:3 0 40.9M 1 loop /snap/snapd/20290
loop4 7:4 0 74.2M 1 loop /snap/core22/1122
loop5 7:5 0 346.3M 1 loop /snap/gnome-3-38-2004/119
loop6 7:6 0 63.5M 1 loop /snap/core20/2015
loop7 7:7 0 497M 1 loop /snap/gnome-42-2204/141
loop8 7:8 0 12.3M 1 loop /snap/snap-store/959
loop9 7:9 0 46M 1 loop /snap/snap-store/638
loop10 7:10 0 40.9M 1 loop /snap/snapd/20092
loop11 7:11 0 349.7M 1 loop /snap/gnome-3-38-2004/143
loop12 7:12 0 308.6M 1 loop /snap/code/155
loop13 7:13 0 73.9M 1 loop /snap/core22/864
loop14 7:14 0 63.3M 1 loop /snap/core20/1828
loop15 7:15 0 91.7M 1 loop /snap/gtk-common-themes/1535
sda 8:0 0 1.8T 0 disk
sdb 8:16 0 1.8T 0 disk
nvme0n1 259:0 0 931.5G 0 disk
├─nvme0n1p1 259:1 0 512M 0 part /boot/efi
└─nvme0n1p2 259:2 0 931G 0 part /

So here we have a lot of confusing info!

Ignore any device beginning with loop.

Let's just narrow down on these:

NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda 8:0 0 1.8T 0 disk
sdb 8:16 0 1.8T 0 disk

These two are the two 2TB drives we installed!

You can see that for me they are identified with the names sda and sdb.

For you, you might see other names, because these names are auto-assigned by Ubuntu.

Anyway, you should be able to find the names of your drives. If they're not sda and sdb, you'll just need to note the names of your drives, as we will be using the names a lot in this tutorial.

Now, to set up the ZFS pool, we are going to need a partition on each drive.

Add partitions to both drives

To make these partitions, we are going to run a simple command-line utility called gdisk. We need to make the partitions one-by-one on each drive. Let's start with sda.

myusername@ubuntu:~$ sudo gdisk /dev/sda

We see the output

myusername@ubuntu:~$ sudo gdisk /dev/sda
GPT fdisk (gdisk) version 1.0.5

Partition table scan:
MBR: not present
BSD: not present
APM: not present
GPT: not present

Command (? for help):

Now, create a new GPT partition by using these commands:

Pressing the letter n, and then press the ENTER key six times to accept the default recommended values for partition number, size, first sector, last sector, and hex code.

Then, you should see something like Changed type of partition to 'Linux filesystem'

And then you should find yourself back at a prompt, here:

Command (? for help):

Press the w key for "write"...

Command (? for help): w

Final checks complete. About to write GPT data.
THIS WILL OVERWRITE EXISTING PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sda.
The operation has completed successfully.

Cool! We just added a partition to this drive.

Let's run lsblk to look at the partition

myusername@ubuntu:~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 4K 1 loop /snap/bare/5
loop1 7:1 0 303.3M 1 loop /snap/code/146
loop2 7:2 0 496.9M 1 loop /snap/gnome-42-2204/132
loop3 7:3 0 40.9M 1 loop /snap/snapd/20290
loop4 7:4 0 74.2M 1 loop /snap/core22/1122
loop5 7:5 0 346.3M 1 loop /snap/gnome-3-38-2004/119
loop6 7:6 0 63.5M 1 loop /snap/core20/2015
loop7 7:7 0 497M 1 loop /snap/gnome-42-2204/141
loop8 7:8 0 12.3M 1 loop /snap/snap-store/959
loop9 7:9 0 46M 1 loop /snap/snap-store/638
loop10 7:10 0 40.9M 1 loop /snap/snapd/20092
loop11 7:11 0 349.7M 1 loop /snap/gnome-3-38-2004/143
loop12 7:12 0 308.6M 1 loop /snap/code/155
loop13 7:13 0 73.9M 1 loop /snap/core22/864
loop14 7:14 0 63.3M 1 loop /snap/core20/1828
loop15 7:15 0 91.7M 1 loop /snap/gtk-common-themes/1535
sda 8:0 0 1.8T 0 disk
└─sda1 8:1 0 1.8T 0 part
sdb 8:16 0 1.8T 0 disk
nvme0n1 259:0 0 931.5G 0 disk
├─nvme0n1p1 259:1 0 512M 0 part /boot/efi
└─nvme0n1p2 259:2 0 931G 0 part /

nice! Looks like there is this new partition called sda1:

sda           8:0    0   1.8T  0 disk
└─sda1 8:1 0 1.8T 0 part

So, we want to now go ahead and do that same operation, but for sdb, which is the 2nd drive we installed.

Do this:

myusername@ubuntu:~$ sudo gdisk /dev/sdb

And then perform the rest of the "partition" directions again, for this drive. (n, then ENTER six times, then w to write the changes.)

OK! Are your partitions ready?

Let's find out.

Run lsblk again to look at the partitions:

myusername@ubuntu:~$ lsblk

And you should see partitions on each drive:

sda           8:0    0   1.8T  0 disk
└─sda1 8:1 0 1.8T 0 part
sdb 8:16 0 1.8T 0 disk
└─sdb1 8:17 0 1.8T 0 part

Get the partition UUIDs

Now. In order to safely set up the ZFS pool, we need to find the UUIDs of each partition.

Let's run the command ls -l /dev/disk/by-partuuid/ to look again at the drives on our system.

myusername@ubuntu:~$ ls -l /dev/disk/by-partuuid/
total 0
lrwxrwxrwx 1 root root 15 Mar 24 06:47 45a69679-784b-4717-9972-22ed99c453d4 -> ../../nvme0n1p2
lrwxrwxrwx 1 root root 15 Mar 24 06:47 a881a1d9-8500-42f1-a7e5-a8f0944f688a -> ../../nvme0n1p1
lrwxrwxrwx 1 root root 10 Mar 24 17:27 addee79b-b5b0-4538-82d9-0769969dc71c -> ../../sdb1
lrwxrwxrwx 1 root root 10 Mar 24 14:16 d6f76ad0-6ba1-4320-8355-640d0c897434 -> ../../sda1

Nice. So we now have two uuids: d6f76ad0-6ba1-4320-8355-640d0c897434 and addee79b-b5b0-4538-82d9-0769969dc71c

Install ZFS

First, we need to install ZFS.

Run these two commands:

sudo apt update

sudo apt install zfsutils-linux

Next, let's confirm that ZFS is now installed.

myusername@ubuntu:~$ zfs --version
zfs-2.1.5-1ubuntu6~22.04.4
zfs-kmod-2.2.0-0ubuntu1~23.10.2

Make The ZFS Mirror

OK! So we are ready to set up our ZFS mirror.

The base command we are going to use is:

sudo zpool create mypool mirror /dev/disk/by-partuuid/YOUR-PARTITION-UUID-ONE /dev/disk/by-partuuid/YOUR-PARTITION-UUID-TWO

So, given my partition UUIDs, here is my full command:

sudo zpool create mypool mirror /dev/disk/by-partuuid/d6f76ad0-6ba1-4320-8355-640d0c897434 /dev/disk/by-partuuid/addee79b-b5b0-4538-82d9-0769969dc71c

Run this command (make sure to use your partition UUIDs instead of mine!), and then we can confirm that our zpool exists:


myusername@ubuntu:~$ sudo zpool status mypool
pool: mypool
state: ONLINE
scan: none requested
config:

NAME STATE READ WRITE CKSUM
mypool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
d6f76ad0-6ba1-4320-8355-640d0c897434 ONLINE 0 0 0
addee79b-b5b0-4538-82d9-0769969dc71c ONLINE 0 0 0

errors: No known data errors

Set permissions on the mirror

The final step is to set the permissions on the mirror so that our local account can work with it.

First, let's be sure about our username by using the whoami command.

myusername@ubuntu:~$ whoami

For me, this outputs: megalith

Now, just one more command:

sudo chown YOUR-USERNAME:YOUR-USERNAME /mypool

You need to replace the text megalith below with your own Ubuntu username:

myusername@ubuntu:~$ sudo chown megalith:megalith /mypool

Great! Your ZFS mirror is now ready to go.

info

If you look for other directions about setting up a ZFS pool, they may skip the steps where you first partition the drives and get the UUIDs. My understanding is that this is risky, because if you use just the drive names like sda and sdb, which are auto-assigned by Ubuntu, instead of using partition UUIDs... everything will work well at first, but if you add another drive (even just plug in a USB flash drive) to your system, Ubuntu might change the drive names when you restart, and then your ZFS mirror will lose contact with one or more drives. For some reason I couldn't find any tutorials that use UUIDs instead of drive names, even though, as far as I can tell, UUIDs are the only safe way to make these pools. Fun!