21.01 ZFS
ZFS is my current filesystem of choice.
What is ZFS is good article.
Notes
- Why you should leave 1MiB space before creating any partition.
- ZFS Tuning Guide - tuning various parameters that you could get benefit from.
- Why you shouldn't generally use ZFS deduplication in most-cases.
- facebook/zstd - zstd and lz4 compression benchmarks and speed compared.
- All ZFS compression methods compared with different types of benchmark.
- How do I change the "label" reported by lsblk.
- How do I determine current size of ARC cache.
- ZFS doesn't need fsck, how it adds auto-repair, security and integrity.
- ZFS allow you to clone/restore a system over stdio.
Some quick points
My current installation reports 1.48x compression ratio (using lz4). This could theoretically go upto 6x with zstd-19 as reported in benchmarks above.
Higher compression doesn't generally means slower system, ZFS uses ARC caching.
Just like writes, ZFS caches reads in the system RAM. They call their read cache the "adaptive replacement cache" (ARC).
Which generally means frequently accessed items are readily available in RAM and hence you get speed from the RAM, which goes around 25.6GB/s for 3200MHz RAM module.
ARC caches can occupy upto 50% of RAM, but they're completely open to give all of 'em back when RAM backpressure increases. You can also clear the cache manually similar to how you do on a non-ZFS system:
echo 3 | sudo tee /proc/sys/vm/drop_caches
.Another killer feature of ZFS is that all of the volumes are shared. See the AVAIL column!
ZFS also allows you to take snapshots of any subvolume:
sudo zfs snapshot zroot/ROOT/void@17June23
and you got a snapshot at/.zfs/snapshot/17June23/
you can always revert back to.
Installation
My Install History
> Click to view <
# Setup a 8-letter hexadecimal hostid (I like a bad food xD)
zgenhostid -f abadf00d
# Cleanup the disk
# blkdiscard is zero-write most-efficient disk clearing method
zpool labelclear -f /dev/nvme0n1 || true
blkdiscard -f /dev/nvme0n1 || sgdisk -go /dev/nvme0n1
# Create partitions (boot, swap, zfs root)
sgdisk -n 1:1m:+550m -t 1:ef00 /dev/nvme0n1
sgdisk -L | grep ef00 # ef00 EFI system partition
sgdisk -L | grep -i swap # 8200 Linux swap
sgdisk -n 2:0:+8G -t 2:8200 /dev/nvme0n1
sgdisk -L | grep -i bf00 # bf00 Solaris root
sgdisk -n 3:0:0 -t 3:bf00 /dev/nvme0n1
mkfs.vfat /dev/nvme0n1p1
mkswap /dev/nvme0n1p2
swapon /dev/nvme0n1p2
# Create a new dataset (zroot)
man zpool-create
man zfsprops
man zpoolprops
zpool create -f -o ashift=12 -O acltype=posixacl -O relatime=on -O compression=zstd -O xattr=sa -O canmount=off -m none zroot /dev/nvme0n1p3
# Create subvolumes in the dataset (zroot/ROOT, zroot/HOME)
man zfs
zfs create -o canmount=off -o mountpoint=none zroot/ROOT
zfs create -o canmount=noauto -o mountpoint=/ zroot/ROOT/void-base
zfs create -o canmount=off -o mountpoint=none zroot/HOME
zfs create -o canmount=noauto -o mountpoint=/home zroot/HOME/void-base
zpool set bootfs=zroot/ROOT/void-base zroot
zpool export zroot
zpool import -N -R /mnt zroot
zfs mount zroot/ROOT/void-base
zfs mount zroot/HOME/void-base
udevadm trigger # force kernel to re-read mount info (optional)
mkdir -p /mnt/boot/efi
mount /dev/nvme0n1p1 /mnt/boot/efi
# Ensure everything is well-n-good
mount | grep mnt
# <connect to internet>
ln -s /etc/sv/dbus /var/service
ln -s /etc/sv/iwd /var/service
ln -s /etc/sv/dhcpcd /var/service
iwctl station wlan0 scan
iwctl station wlan0 connect V2040
XBPS_ARCH=x86_64 xbps-install -S -R https://mirrors.dotsrc.org/voidlinux/current -r /mnt base-system zfs zfsbootmenu linux6.5 linux6.5-headers iwd neovim linux-firmware-intel mesa-dri vulkan-loader mesa-vulkan-intel intel-video-accel xf86-video-intel efibootmgr gummiboot-efistub bash fish-shell btop inxi
mkdir -p /mnt/etc/zfs
zpool set cachefile=/etc/zfs/zpool.cache zroot
echo framework > /mnt/etc/hostname
cp /etc/hostid /mnt/etc/hostid
cp /etc/zfs/zpool.cache /mnt/etc/zfs/zpool.cache
# Setup HOME mount
cat << EOF >> /mnt/etc/rc.local
home_partition=$(mount | awk '$3 == "/" { gsub("ROOT", "HOME", $1); print $1 }')
if [ -n "$home_partition" ]; then zfs mount $home_partition; else echo "Error: Unable to determine the home partition"; fi
EOF
# Set keyboard layout & timezone
nvim /mnt/etc/rc.conf
ln -sf /usr/share/zoneinfo/Asia/Kolkata /mnt/etc/localtime
# Setup dracut
cat << EOF > /mnt/etc/dracut.conf.d/zol.conf
nofsck="yes"
add_dracutmodules+=" zfs "
omit_dracutmodules+=" btrfs "
EOF
zfs set org.zfsbootmenu:commandline="resume=$(blkid | grep nvme0n1p2 | cut -d' ' -f2 | sed 's/"//g') loglevel=4 acpi_osi='Windows 2020' net.ifnames=0 i915.enable_psr=1 intel_pstate=disable nvme.noacpi=1" zroot/ROOT # setting on ROOT makes all children inherit the property (useful in multi-boot)
# Generate locales
sed -i '/en_US/s/^#//' /mnt/etc/default/libc-locales
sed -i 's/LANG=.*/LANG=en_US.UTF-8/' /mnt/etc/locale.conf
xchroot /mnt xbps-reconfigure -f glibc-locales
# Add user
xchroot /mnt useradd -m animesh -G network,wheel,video,audio,input
xchroot /mnt chown -R animesh:animesh /home/animesh
xchroot /mnt sed -i '/%wheel\sALL=(ALL:ALL)\sALL/s/^#//' /etc/sudoers
xchroot /mnt passwd root
xchroot /mnt passwd animesh
# Add mountpoints
blkid
echo "$(blkid | grep nvme0n1p1 | cut -d' ' -f2) /boot/efi vfat defaults 0 0" >> /mnt/etc/fstab
echo "$(blkid | grep nvme0n1p2 | cut -d' ' -f2) none swap defaults 0 0" >> /mnt/etc/fstab
# Configure ZFSBootMenu
cat << EOF > /mnt/etc/zfsbootmenu/config.yaml
Global:
ManageImages: true
BootMountPoint: /boot/efi
DracutConfDir: /etc/zfsbootmenu/dracut.conf.d
PreHooksDir: /etc/zfsbootmenu/generate-zbm.pre.d
PostHooksDir: /etc/zfsbootmenu/generate-zbm.post.d
InitCPIOConfig: /etc/zfsbootmenu/mkinitcpio.conf
Components:
Enabled: false
EFI:
ImageDir: /boot/efi/EFI/zbm
Versions: false
Enabled: true
Kernel:
CommandLine: loglevel=4 acpi_osi='Windows 2020' net.ifnames=0 i915.enable_psr=1 intel_pstate=disable nvme.noacpi=1
EOF
xchroot /mnt xbps-reconfigure -fa # or just run "generate-zbm"
# Generate EFI entries for booting
man efibootmgr
xchroot /mnt efibootmgr --create --disk /dev/nvme0n1 --part 1 -L "ZFSBootMenu (Backup)" --loader \\EFI\\zbm\\vmlinuz-backup.efi
xchroot /mnt efibootmgr --create --disk /dev/nvme0n1 --part 1 -L "ZFSBootMenu" --loader \\EFI\\zbm\\vmlinuz.efi
umount -n -R /mnt
zpool export zroot
reboot
Installation References
- Void Docs - ZFS
- ZFSBootMenu - Step by step installation instructions
- Stetsed's install script (Friend @ Framework discord)
- Some guy's void install script
Some useful commands
zfs list
.zfs get compressratio zroot
.zpool export zroot && zpool import -N -R /mnt zroot
- import zfs at /mnt, useful for debugging via chroot (e.g.zfs mount zroot/ROOT/void
can be used).sudo zfs snapshot zroot/ROOT/void@<your-suffix>
- create a snapshot, can be reverted usingzfs rollback
or by ZFSBootMenu.