OpenZFS
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.