= OpenZFS = '''OpenZFS''', formerly '''ZFS on Linux''', is a project aimed at bringing the ZFS [[Linux/FileSystems|file system]] to the [[Linux]] kernel. If using a [[BSD]], ZFS should be supported out of the box. <> ---- == Installation == === Arch === The first step is almost always downgrading the kernel. {{{ version="major.minor.patch-release" pacman -U https://archive.archlinux.org/packages/l/linux-lts/linux-lts-$version-x86_64.pkg.tar.zst https://archive.archlinux.org/packages/l/linux-lts-headers/linux-lts-headers-$version-x86_64.pkg.tar.zst mkinitcpio -P grub-mkconfig -o /boot/grub/grub.cfg }}} To determine which kernel version is supported, try installing ZFS from the [[Linux/Arch/Pacman#Repositories|unofficial repository]]. {{{ pacman-key -r DDF7DB817396A49B2A2723F7403BD972F75D9D76 pacman-key --lsign-key DDF7DB817396A49B2A2723F7403BD972F75D9D76 echo "[archzfs]\nServer = https://archzfs.com/$repo/$arch\n" >> /etc/pacman.conf pacman -Syu archzfs-linux }}} If the last command gives an error about an unsatisfiable dependency involving the kernel, the indicated version is what to use in the above snippet. With a supported kernel and the ZFS module installed, try booting. ---- == Pools == The lowest level of ZFS is '''pools'''. Identify disks by their IDs like: {{{ $ ls -lh /dev/disk/by-id/ total 0 lrwxrwxrwx 1 root root 1 Jan 01 12:30 ata-ABCDE lrwxrwxrwx 1 root root 1 Jan 01 12:30 ata-FGHIJ lrwxrwxrwx 1 root root 1 Jan 01 12:30 ata-KLMNO lrwxrwxrwx 1 root root 1 Jan 01 12:30 ata-PQRST }}} With these 4 drives of ''N'' GB storage each, create a '''RAIDz2''' pool where ''2N'' GB will be dedicated to parity rather than storage. The pool will be fault tolerant for up to 2 failed drives. {{{ zpool create -f tank raidz2 ata-ABCDE ata-FGHIJ ata-KLMNO ata-PQRST }}} Alternatively create a '''RAIDz1''' pool where just ''N'' GB will be dedicated to parity (but the pool will only be fault tolerant of 1 drive failure). ''Alternatively'' alternatively, create a '''Mirror''' pool to maximize fault tolerance (up to 3 failed drives) but leaving just ''N'' GB of storage. Pools can be created with encryption, but it is not recommended. A pool's encryption setting is inherited, so the pool is permanently locked to this singular cryptographic algorithm. The pool will be mounted to a root-level directory named after the pool (`/tank` in this case). Check the status of pools with `zpool status`. To ensure that the pools mount at boot, try: {{{ systemctl enable zfs-import-cache.service zfs.target zfs-import.target }}} ---- == Datasets == To create a dataset within a pool, try: {{{ zfs create tank/data }}} To create an encrypted dataset, try: {{{ zfs create -o encryption=on -o keyformat=passphrase tank/enc }}} The default cryptographic algorithm is `aes-256-gcm`. To mount an encrypted dataset, try: {{{ zfs load-key tank/enc zfs mount tank/enc }}} ---- == Snapshots == To create a snapshot of a pool, try: {{{ zfs snapshot tank/data@snap1 }}} At initialization, a snapshot has negligible size. It grows as changes are made in the dataset. To delete a snapshot, try: {{{ zfs destroy pool/dataset@snap1 }}} '''If `@snap1` is omitted from the `zfs-destroy` call, the dataset will be destroyed instead.''' To delete a range of snapshots, try: {{{ zfs destroy pool/dataset@snap1%snap9 }}} `snap1` and `snap9` can be omitted to delete an open range of snapshots, i.e. to delete `snap9` and all older snapshots, or to delete `snap1` and all newer snapshots. To list available snapshots, try: {{{ zfs list -t snapshot }}} === Sending and Receiving === A snapshot can be copied from one dataset to another like: {{{ zfs send tank1/data@snap1 | zfs recv tank2/data }}} Note that the canonical name for `recv` is `zfs-receive(8)`. Alternatively, a snapshot can be compressed and written to a remote filesystem like: {{{ zfs send tank/data@snap1 | gzip | ssh user@host "cat > dest.tar.gz" }}} To estimate the size of such a compressed file, try: {{{ zfs send tank/data@snap1 | gzip -c | wc -c }}} Note furthermore the `-R` flag for `zfs-send(8)`, which create a '''replicate''' send. This bundles all children datasets (recursively), all snapshots, and all configurations. === Incremental Sending and Receiving === The actual utility of these tools is '''incremental''' sends: {{{ zfs send -i tank1/data@snap1 tank1/data@snap2 | zfs recv tank2/data }}} If there are multiple snapshots between `@snap1` and `@snap2`, note that using `-I tank1/data@snap1` on one call is equivalent to the series of calls using `i tank1/data@snap1a`; `i tank1/data@snap1b`; and so on. Note furthermore that the `-F` flag on `zfs-receive(8)` causes a roll-back to the most recent snapshot of `tank2/data` before initiating the receive. Then, any snapshots that do not exist in `tank1/data` are deleted from `tank2/data`. This is mostly useful for incremental replicate sends (i.e., `zfs send -R -i ...`). To estimate the size of an incremental send, use the dry-run flag (`-n`). {{{ zfs send -n -i tank1/data@snap1 tank1/data@snap2 }}} ---- == Administration == Consider disabling access times with `zfs set atime=off tank` (or `zfs set atime=off tank/data` to limit the setting to a dataset). Consider enabling compression. Upstream considers this to be a reasonable default, even for uncompressible files. {{{ zfs set compression=on tank }}} The default compression algorithm is `lz4`. ZFS pools must be scrubbed to ensure that bit rot is addressed before backups are lost. To trigger this manually, try: {{{ zpool scrub tank }}} Alternatively, enable a [[Linux/Systemd|timer]] to automate this: {{{ systemctl enable zfs-scrub-weekly@tank.timer }}} ---- == See also == [[https://openzfs.github.io/openzfs-docs/man/master/8/zfs-create.8.html|zfs-create(8)]] [[https://openzfs.github.io/openzfs-docs/man/master/8/zfs-destroy.8.html|zfs-destroy(8)]] [[https://openzfs.github.io/openzfs-docs/man/master/8/zfs-list.8.html|zfs-list(8)]] [[https://openzfs.github.io/openzfs-docs/man/master/8/zfs-mount.8.html|zfs-mount(8)]] [[https://openzfs.github.io/openzfs-docs/man/master/8/zfs-receive.8.html|ifs-receive(8)]] [[https://openzfs.github.io/openzfs-docs/man/master/8/zfs-send.8.html|zfs-send(8)]] [[https://openzfs.github.io/openzfs-docs/man/master/8/zfs-snapshot.8.html|zfs-snapshot(8)]] [[https://openzfs.github.io/openzfs-docs/man/master/8/zpool-create.8.html|zpool-create(8)]] [[https://openzfs.github.io/openzfs-docs/man/master/8/zpool-scrub.8.html|zpool-scrub(8)]] [[https://openzfs.github.io/openzfs-docs/man/master/8/zpool-status.8.html|zpool-status(8)]] ---- CategoryRicottone