zfs
Pools are managed with the zpool(8) command and have the
following hierarchy:
pool: consists of one or more virtual devices (vdev)vdev: consists of one or more physical devices (dev) and come in different kinds such asdisk,mirror,raidzX, ...disk: single physical disk (vdev == dev)mirror: data is identically replicated on alldevs(requires at least 2 physical devices).
Data stored in a pool is distributed and stored across all vdevs by zfs.
Therefore a total failure of a single vdev can lead to total loss of a pool.
A dataset is a logical volume which can be created on top of a pool. Each
dataset can be configured with its own set of properties like
encryption, quota, ....
Datasets are managed with the zfs(8) command.
zfs pool management
Pools are by default mounted at /<POOL>.
Create, modify and destroy zfs pools
# Create a pool MOOSE with a two mirror vdevs.
zpool create moose mirror <dev1> <dev2> mirror <dev3> <dev4>..
# Add new raidz1 vdev to a pool.
zpool add moose raidz1 <devA> <devB> <devC>..
# Remove a vdev from a pool.
zpool remove moose <vdevX>
# Destroy a pool.
zpool destroy moose
For stable device names in small home setups it is recommended to use names from
/dev/disk/by-id.
Inspect zfs pools
# Show status of all pools or a single one.
zpool status [<pool>]
# Show information / statistics about pools or single one.
zpool list [<pool>]
# Show statistics for all devices.
zpool list -v
# Show command history for pools.
zpool history
Modify vdevs
# vdev MIRROR-0 with two devs.
zpool status
NAME STATE READ WRITE CKSUM
moose ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
virtio-200 ONLINE 0 0 0
virtio-300 ONLINE 0 0 0
# Attach new device to an existing vdev.
zpool attach moose virtio-200 virtio-400
# vdev MIRROR-0 with three devs.
zpool status
NAME STATE READ WRITE CKSUM
moose ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
virtio-200 ONLINE 0 0 0
virtio-300 ONLINE 0 0 0
virtio-400 ONLINE 0 0 0
# Detach device from vdev.
zpool detach moose virtio-200
Replace faulty disk
# MIRROR-0 is degraded as one disk failed, but still intact.
zpool status
NAME STATE READ WRITE CKSUM
moose DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
virtio-200 UNAVAIL 0 0 0 invalid label
virtio-300 ONLINE 0 0 0
# Replace faulty disk, in mirror.
# No data is lost since mirror still has one good disk.
zpool replace moose virtio-200 virtio-400
# MIRROR-0 back in ONLINE (good) state.
zpool status
NAME STATE READ WRITE CKSUM
moose ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
virtio-400 ONLINE 0 0 0
virtio-300 ONLINE 0 0 0
Import or export zfs pools
When moving pools between hosts, the pool must be exported on the currently
active host and imported on the new host.
# Export a pool called MOOSE.
zpool export moose
# If datasets are busy, use lsof to check which processes keep it busy.
# lsof <mntpoint>
# List pools that can be imported using BY-ID deivce names (for example).
zpool import -d /dev/disk/by-id
# Import pool MOOSE using BY-ID device names (for example).
zpool import -d /dev/disk/by-id moose
Device names used by an existing pool can be changed by exporting and importing a pool again.
zfs dataset management
Datasets are by default mounted at /<POOL>/<DATASET>.
Create and destroy zfs datasets
# Create dataset FOO on pool MOOSE.
zfs create moose/foo
# Destroy dataset.
zfs destroy moose/foo
List all zfs datasets
# List all zfs datasets.
zfs list
Mount zfs datasets
# List currently mounted datasets.
zfs mount
# Mount dataset.
zfs mount moose/foo
# Unmount dataset.
zfs unmount moose/foo
Encrypted datasets
Encryption is a readonly property, can only be set when creating a dataset.
# Create encrypted dataset FOO on pool MOOSE.
zfs create -o encryption=on -o keyformat=passphrase moose/foo
# Mount encrypte dataset and load encryption key (if not loaded).
zfs mount -l moose/foo
# -l is equivalent to first loading the key via zfs load-key moose/foo.
# Unmount dataset and unload encryption key (unload is optional).
zfs umount -u moose/foo
Manage zfs encryption keys
# Preload encryption key for dataset.
zfs load-key moose/foo
# Preload encryption key for all datasets.
zfs load-key -a
# Change encryption key for dataset.
zfs change-key moose/foo
# Unload encryption key for dataset.
zfs unload-key moose/foo
Manage dataset properties
# Get all properties for dataset.
zfs get quota moose/foo
# Get single property for dataset.
zfs get all moose/foo
# Get single property for all datasets.
zfs get quota
# Set property on dataset.
zfs set quota=10G moose/foo
Snapshots
# Create snapshot called V2 for dataset moose/foo.
zfs snapshot moose/foo@v2
# List all snapshots.
zfs list -t snapshot
# Make .zfs direcotry visible in the root of the dataset.
zfs set snapdir=visible moose/foo
# Browse available snapshots in visible .zfs direcotry (readonly).
ls /moose/foo/.zfs/snapshot
v1/ v2/
# Create a new dataset based on the V1 snapshot
zfs clone moose/foo@v1 moose/foov1
# Destroy snapshot.
zfs destroy moose/foo@v1
Access control list
Focus on posix acl.
# Set the ACL type for the FOO dataset to POSIXACL.
zfs set acltype=posixacl moose/foo
# Get the ACL type of a given dataset.
zfs get acltype moose/foo
For performance reasons it is recommended to also set
zfs set xattr=sa moose/foo[ref].
Example: zfs pool import during startup (systemd)
The default zpool cache file is /etc/zfs/zpool.cache. When pools are imported
the cache is updated.
Enable the following targets / services to automatically import pools from the cache.
systemctl list-dependencies
...
└─zfs.target
└─zfs-import.target
└─zfs-import-cache.service