OpenZFS

3 minute read

OpenZFS is an open-source storage platform. It includes the functionality of both traditional file systems and volume manager. It has many advanced features including:

  • Protection against data corruption. Integrity checking for both data and metadata.
  • Continuous integrity verification and automatic “self-healing” repair
  • Data redundancy with mirroring, RAID-Z1/2/3 [and DRAID]
  • Support for high storage capacities — up to 256 trillion yobibytes (2^128 bytes)
  • Space-saving with transparent compression using LZ4, GZIP or ZSTD
  • Hardware-accelerated native encryption
  • Efficient storage with snapshots and copy-on-write clones
  • Efficient local or remote replication — send only changed blocks with ZFS send and receive

Basics

Videos

Creating a ZFS disk (no raid)

zpool

First, we need to create a zpool. This is done by pooling a couple (or a single) disks together.

The name of the disks can either be referenced to via their /dev path or UUID (prefered).

1user $ sudo zpool create -o ashift=12 <name_of_the_pool> [disk1] [disk2] ...

Now, you can see your pool with the following command:

1user $ zpool list
2
3NAME          SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
4myfirstpool  7.94G   130K  7.94G     0%  1.00x  ONLINE  -

You can also check the health of your pool and if there is any error on that pool using:

 1user $ zpool status
 2
 3  pool: myfirstpool
 4 state: ONLINE
 5  scan: none requested
 6config:
 7
 8        NAME        STATE     READ WRITE CKSUM
 9        myfirstpool  ONLINE       0     0     0
10           loop0     ONLINE       0     0     0
11           loop1     ONLINE       0     0     0
12           loop2     ONLINE       0     0     0
13           loop3     ONLINE       0     0     0

Datasets

Now, you need to create one or more datasets. In order to be secure, the dataset should be encrypted using a passphrase (less secure):

1user $ sudo zfs create -o encryption=on -o keyformat=passphrase -o compression=lz4 <nameofzpool>/<nameofdataset>

To create a dataset using a keyfile (more secure), you first need to create a random file and then the dataset:

1user $ sudo openssl rand -out /root/<FILENAME> 32
2user $ sudo zfs create -o encryption=on -o keyformat=raw -o keylocation=file:///root/<FILENAME> -o compression=lz4 <nameofzpool>/<nameofdataset>

Where 32 stands for 256bit key.

For a list of optimization of dataset creation: https://jrs-s.net/2018/08/17/zfs-tuning-cheat-sheet/

Compression

To enable compression:

1user $ sudo zfs set compression=on <pool>

Snapshot

You can create snapshots of your dataset using the following command:

Pay attention to the @ after the dataset name that is giving its name to the snapshot.

1user $ sudo zfs snapshot <nameofzpool>/<nameofdataset>@<meaningfulname>

You can compare two snapshots together with:

1user $ sudo zfs diff <nameofzpool>/<nameofdataset>@<meaningfulname_NEW> <nameofzpool>/<nameofdataset>@<meaningfulname_OLD>

If one of the snapshots is omitted, it will be compared to the current state of the dataset.

You can restore snapshots using this:

1user $ sudo zfs rollback <nameofzpool>/<nameofdataset>@<meaningfulname>

Streaming

You can send the current the dataset to a new dataset using the following commands:

1user $ sudo zfs send <nameofzpool>/<nameofdataset>@<meaningfulname> > /tmp/<name_of_file>
2user $ cat /tmp/<name_of_file> | sudo zfs receive <OTHER_nameofzpool>/<OTHER_nameofdataset>@<meaningfulname>

The target dataset cannot exist or it will ask you if you want to overwrite it.

Maintenance

Whenever data is read and ZFS encounters an error, it is silently repaired when possible, rewritten back to disk and logged so you can obtain an overview of errors on your pools. There is no fsck or equivalent tool for ZFS. Instead, ZFS supports a feature known as scrubbing. This traverses through all the data in a pool and verifies that all blocks can be read.

To scrub a pool:

1user $ sudo zpool scrub <pool>

Encryption

https://arstechnica.com/gadgets/2021/06/a-quick-start-guide-to-openzfs-native-encryption/

zfs load-key

After creating your encrypted dataset, it’s automatically mounted—but it won’t be, after the system reboots. In order to make your encrypted volumes accessible again, you’ll use the zfs load-key command.

1zfs load-key [**-nr] [-L location] [-a]** poolname/zvol-or-dataset

As usual, the optional -r is for recursive, and it will load both the volume specified and any child volumes. -a for all goes a step further and loads keys for all encrypted volumes found on all currently imported pools.