Docs β Existing install β ZFS root
Already running Omarchy? Getting to a ZFS root
You have a working Omarchy install on btrfs and you want ZFS underneath it. Here is what is possible, the two routes that work, and how to keep your current install bootable while you move.
btrfs and ZFS are different on-disk formats. No tool rewrites one into the other, and anything claiming to "convert" your root filesystem is either copying data elsewhere first or about to lose it. Every real route below moves your data to a new pool and reinstalls the operating system.
That sounds worse than it is. On Omarchy Quattro almost nothing you care
about lives outside /home: the shell, themes, keybindings and
Quickshell config are all in ~/.config and
~/.local/share/omarchy, and the OS itself is just packages. A
reinstall plus a restore is usually a 45-minute job, and you end up on a
filesystem you can snapshot and roll back forever after.
| Route | You need | Downtime | Safety net |
|---|---|---|---|
| A. Reinstall & restore | One disk + an external drive for the backup | The whole job; the machine is unusable in between | Your backup. That is all. Verify it before you start. |
| B. Second disk | A spare internal disk (or an M.2 slot free) | Minutes. You boot back into the old install any time | The old install stays intact and bootable until you erase it. |
Take route B if you have any way to add a disk. Being able to boot the old system while the new one settles in is worth more than the cost of the drive.
1. Confirm what you are on
findmnt -no FSTYPE / # btrfs, probably
pacman -Q omarchy # must be a Quattro (4.x) version
[ -d /sys/firmware/efi ] && echo UEFI || echo "BIOS. ZFSBootMenu needs UEFI"
mokutil --sb-state # want: SecureBoot disabled
lsblk -o NAME,SIZE,MODEL,TRAN,MOUNTPOINTS
If pacman -Q omarchy reports nothing, you are on a pre-Quattro
curl | bash install. Upgrade to Quattro first, on btrfs, and get
that working before adding ZFS to the pile.
2. Capture the install
Do this even on route B, where you keep the old disk. It takes minutes and it is the difference between an afternoon and a bad week.
Your data
# Everything of yours, permissions and ACLs intact.
sudo rsync -aHAX --numeric-ids --info=progress2 \
/home/ /run/media/$USER/backup/home/
The shape of the system
mkdir -p ~/migration && cd ~/migration
pacman -Qqe > pkgs-explicit.txt # what you asked for
pacman -Qqm > pkgs-foreign.txt # AUR / local packages
systemctl list-unit-files --state=enabled > units-enabled.txt
sudo cp -r /etc/NetworkManager/system-connections wifi-and-vpn
timedatectl show > timedate.txt
localectl status > locale.txt
crontab -l > crontab.txt 2>/dev/null || true
Copy ~/migration to the external drive too.
/etc/fstab, /etc/mkinitcpio.conf and anything
bootloader-related belong to the old layout. Restoring them onto a ZFS
root is how people end up in an emergency shell. Let the new install own boot
configuration; bring back your data and your app config, not the plumbing.
3. Install root-on-ZFS
Both routes use the ISO from route 1. Follow that page for the download, the USB stick, the 15-second question and the installer's prompts. The only difference is which disk you point it at.
Route A. Same disk
Verify the backup from another machine or a live USB first: mount it, open a few files, check the sizes look sane. Then install to the disk and erase the old system. Point of no return; there is no undo.
Route B. Second disk, old install untouched
- Shut down, fit the new disk, boot the ISO.
- At the disk selection step, pick the new disk. Read the destructive-confirmation list carefully. It names the exact devices, and this is the moment to catch a mix-up.
- Install as normal, using the same username as before so restoring
/home/<user>lands with the right ownership.
Your firmware will have entries for Limine (old install) and ZFSBootMenu
(new one). omarchy-zfs keeps ZFSBootMenu first in the EFI boot
order on every package transaction, but it only ever reorders. It
never deletes another bootloader's entry, because which systems stay
bootable is your call. So the old install remains one firmware-menu keypress
away. Check with efibootmgr.
4. Restore your data
Log into the new system once so the account and its home dataset exist, then restore into it. On route B the old disk is right there:
# Route B: mount the old btrfs root read-only and copy from it
sudo mkdir -p /mnt/old
sudo mount -o ro /dev/nvme1n1p2 /mnt/old # your old root partition
sudo rsync -aHAX --numeric-ids --info=progress2 \
/mnt/old/home/pete/ /home/pete/
# Route A: same thing, from the external drive
sudo rsync -aHAX --numeric-ids --info=progress2 \
/run/media/pete/backup/home/pete/ /home/pete/
/home is really mounted first
Use mountpoint -q /home && echo mounted, not
findmnt /home. findmnt reports the nearest
enclosing mount, so it answers "mounted" for a plain directory. If you
rsync 200 GB into /home while its dataset is unmounted, the data
lands in the root dataset and vanishes under the real mount at the next
boot.
Fix ownership if the UID changed, then put the packages back:
sudo chown -R pete:pete /home/pete
# Repo packages you had explicitly installed
sudo pacman -S --needed - < ~/migration/pkgs-explicit.txt
# AUR packages, via your helper
yay -S --needed $(cat ~/migration/pkgs-foreign.txt)
# Network connections
sudo cp -r ~/migration/wifi-and-vpn/* /etc/NetworkManager/system-connections/
sudo chmod 600 /etc/NetworkManager/system-connections/*
sudo systemctl restart NetworkManager
Expect pkgs-explicit.txt to contain a few packages
that no longer exist or now come from a different repo. Read pacman's complaints
rather than forcing past them.
5. Take the first snapshot
You are on ZFS now. Use it before you customise anything:
sudo zfs snapshot -r zroot@migrated
zfs list -t snapshot
From here on, every package transaction takes a pre-upgrade snapshot automatically, and ZFSBootMenu can roll back to any of them from before the OS starts.
Retiring the old disk (route B)
Live on the new install for a week or two first. When you are ready, either wipe the old disk and add it as a mirror of your pool:
# Same-size or larger disk. This makes zroot self-healing.
sudo zpool attach zroot /dev/disk/by-id/<existing> /dev/disk/by-id/<old-disk>
zpool status zroot # watch it resilver
β¦or keep it as a local backup target and replicate to it:
sudo zpool create -o ashift=12 -O compression=zstd -O mountpoint=none backup /dev/disk/by-id/<old-disk>
sudo zfs snapshot -r zroot@$(date +%F)
sudo zfs send -R zroot@$(date +%F) | sudo zfs receive -u -d backup
If you attach it as a mirror, remember the old EFI partition is gone. Re-check efibootmgr and keep at least one working ZFSBootMenu entry.
Why not do it in place?
People ask whether they can shrink btrfs, build a pool in the freed space,
copy the system across, and switch. It is technically possible and it is a bad
trade: you are doing a live copy of a running system, then hand-assembling the
parts the installer would have got right. The hostid inside the initramfs, the
zfs mkinitcpio hook ordering, the ESP contents, the ZFSBootMenu EFI
entry and the boot-environment layout. Each one is a silent unbootable-system
bug if you get it slightly wrong, and you will be debugging it with no working
machine. The ISO automates exactly that list, and a second disk costs less than
the evening you would spend.
Alternatives worth considering
- Keep btrfs, add ZFS for data. If what you want is snapshots and replication of your files, route 3 gets you that with no reinstall: ZFS on /home or a data drive.
- Stay on btrfs. Upstream's snapper and limine setup gives bootable snapshots and it is the tested path. Switch if you want ZFS encryption, send/receive or checksums.