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