Ramblings of an aging IT geek
← Ramblings of an aging IT geek
linux

putting root on zfs without regretting it

A walk through moving a homelab box's root filesystem onto ZFS for boot environments and snapshots, the bits that bit me, and whether it was worth the bootloader faff.

A server with disks pulled half out of the bays

I have run ZFS for data pools for years and loved it for exactly one feature above all the others: snapshots that cost nothing to take and are there the instant I do something stupid. What I had never done was put root on ZFS, partly out of inertia and partly because the bootloader story always looked like more pain than it was worth. Over the holidays I finally did it on one box, and the headline is: worth it, with caveats.

The reason is boot environments. With root on ZFS, an upgrade becomes "snapshot the current root, apply the upgrade, and if it boots into a mess, roll back to a filesystem that existed thirty seconds ago." That is a categorically better story than the usual "hope the package manager's idea of rollback matches reality".

the layout

I went with a fairly standard split: a small EFI partition, and the rest handed to a single pool with separate datasets for root, home, and the bits I never want rolled back.

zpool create -o ashift=12 rpool /dev/disk/by-id/...
zfs create -o mountpoint=none rpool/ROOT
zfs create -o mountpoint=/    rpool/ROOT/default
zfs create -o mountpoint=/home rpool/home

The separate rpool/home dataset matters. If I roll the root back, I want my home directory to stay in the present, not travel back in time with the system. Same logic for anything stateful: logs, container volumes, the things whose whole job is to remember.

where it bit me

Two things caught me out, both predictable in hindsight.

The first was the initramfs. The boot needs the ZFS module available before the root is mounted, which means rebuilding the initramfs with ZFS included and making sure the bootloader actually points at the right dataset via root=ZFS=rpool/ROOT/default. Get that wrong and you drop to an initramfs prompt with a pool you cannot import yet, which is a lonely place at one in the morning.

The second was ashift. Set it at pool creation or live with it forever. I set ashift=12 for 4K-sector disks, which is the safe default for anything modern, but it is the kind of thing you cannot change later, so it is worth being deliberate rather than accepting whatever ZFS guesses.

was it worth it

For a box I tinker with, unreservedly yes. The first time an upgrade left the system in a sulk and I rolled the entire root back in seconds, I stopped resenting the bootloader faff entirely. Take a snapshot before anything risky, name it after what you are about to do, and the worst case stops being "rebuild the host" and becomes "roll back and go to bed".

The honest caveat is that this adds moving parts to the one filesystem you most need to be boring: the one your machine boots from. If a box absolutely must come up unattended and you will not be there to rescue an initramfs prompt, plain ext4 on root and ZFS for data is the calmer choice. For everything I babysit anyway, root on ZFS has earned its place.